diff --git a/apps/buffering.c b/apps/buffering.c index b35206766b..9c8d107a86 100644 --- a/apps/buffering.c +++ b/apps/buffering.c @@ -91,6 +91,8 @@ /* point at which the file buffer will fight for CPU time */ #define BUFFERING_CRITICAL_LEVEL (1024*128) +#define BUF_HANDLE_MASK 0x7FFFFFFF + /* Ring buffer helper macros */ /* Buffer pointer (p) plus value (v), wrapped if necessary */ @@ -224,7 +226,7 @@ static struct memory_handle *add_handle(size_t data_size, const bool can_wrap, const bool alloc_all) { /* gives each handle a unique id */ - static int cur_handle_id = 1; + static int cur_handle_id = 0; size_t shift; size_t new_widx; size_t len; @@ -292,7 +294,7 @@ static struct memory_handle *add_handle(size_t data_size, const bool can_wrap, new_handle->id = cur_handle_id; /* Wrap signed int is safe and 0 doesn't happen */ - if (++cur_handle_id < 1) cur_handle_id = 1; + cur_handle_id = (cur_handle_id + 1) & BUF_HANDLE_MASK; new_handle->next = NULL; num_handles++; @@ -314,7 +316,7 @@ static struct memory_handle *add_handle(size_t data_size, const bool can_wrap, static bool rm_handle(const struct memory_handle *h) { if (h == NULL) - return false; + return true; mutex_lock(&llist_mutex); @@ -359,7 +361,7 @@ static bool rm_handle(const struct memory_handle *h) NULL if the handle wasn't found */ static struct memory_handle *find_handle(const int handle_id) { - if (handle_id <= 0) + if (handle_id < 0) return NULL; mutex_lock(&llist_mutex); @@ -664,16 +666,18 @@ static void rebuffer_handle(int handle_id, size_t newpos) static bool close_handle(int handle_id) { struct memory_handle *h = find_handle(handle_id); + + /* If the handle is not found, it is closed */ if (!h) - return false; + return true; if (h->fd >= 0) { close(h->fd); h->fd = -1; } - rm_handle(h); - return true; + /* rm_handle returns true unless the handle somehow persists after exit */ + return rm_handle(h); } /* Free buffer space by moving the handle struct right before the useful @@ -1327,7 +1331,7 @@ bool buffering_reset(char *buf, size_t buflen) cur_handle = NULL; cached_handle = NULL; num_handles = 0; - base_handle_id = 0; + base_handle_id = -1; buffer_callback_count = 0; memset(buffer_low_callback_funcs, 0, sizeof(buffer_low_callback_funcs)); diff --git a/apps/playback.c b/apps/playback.c index d575be9db5..5132bd629a 100644 --- a/apps/playback.c +++ b/apps/playback.c @@ -362,31 +362,36 @@ static struct mp3entry *bufgetid3(int handle_id) static bool clear_track_info(struct track_info *track) { + /* bufclose returns true if the handle is not found, or if it is closed + * successfully, so these checks are safe on non-existant handles */ if (!track) return false; - if (track->codec_hid > 0) { + if (track->codec_hid >= 0) { if (bufclose(track->codec_hid)) - track->codec_hid = 0; + track->codec_hid = -1; else return false; } - if (track->id3_hid > 0) { + if (track->id3_hid >= 0) { if (bufclose(track->id3_hid)) - track->id3_hid = 0; + track->id3_hid = -1; else return false; } - if (track->audio_hid > 0) { + if (track->audio_hid >= 0) { if (bufclose(track->audio_hid)) - track->audio_hid = 0; + track->audio_hid = -1; else return false; } - memset(track, 0, sizeof(struct track_info)); + track->filesize = 0; + track->taginfo_ready = false; + track->event_sent = false; + return true; } @@ -642,7 +647,7 @@ struct mp3entry* audio_current_track(void) return &curtrack_id3; else if (offset == -1 && *prevtrack_id3.path) return &prevtrack_id3; - else if (tracks[cur_idx].id3_hid > 0) + else if (tracks[cur_idx].id3_hid >= 0) return bufgetid3(tracks[cur_idx].id3_hid); memset(&temp_id3, 0, sizeof(struct mp3entry)); @@ -681,7 +686,7 @@ struct mp3entry* audio_next_track(void) next_idx++; next_idx &= MAX_TRACK_MASK; - if (tracks[next_idx].id3_hid <= 0) + if (tracks[next_idx].id3_hid < 0) return NULL; return &nexttrack_id3; @@ -1681,10 +1686,10 @@ static void codec_pcmbuf_track_changed_callback(void) static void codec_discard_codec_callback(void) { - if (CUR_TI->codec_hid > 0) + if (CUR_TI->codec_hid >= 0) { bufclose(CUR_TI->codec_hid); - CUR_TI->codec_hid = 0; + CUR_TI->codec_hid = -1; } } @@ -1849,7 +1854,7 @@ static void codec_thread(void) case Q_CODEC_LOAD: LOGFQUEUE("codec < Q_CODEC_LOAD"); - if (CUR_TI->codec_hid <= 0) { + if (CUR_TI->codec_hid < 0) { logf("Codec slot is empty!"); /* Wait for the pcm buffer to go empty */ while (pcm_is_playing()) @@ -1961,7 +1966,7 @@ static void codec_thread(void) } } - if (CUR_TI->codec_hid > 0) + if (CUR_TI->codec_hid >= 0) { LOGFQUEUE("codec > codec Q_CODEC_LOAD"); queue_post(&codec_queue, Q_CODEC_LOAD, 0); @@ -2042,18 +2047,18 @@ long audio_filebufused(void) static void audio_update_trackinfo(void) { - if (CUR_TI->id3_hid > 0) + if (CUR_TI->id3_hid >= 0) copy_mp3entry(&curtrack_id3, bufgetid3(CUR_TI->id3_hid)); - CUR_TI->taginfo_ready = (CUR_TI->id3_hid > 0); + CUR_TI->taginfo_ready = (CUR_TI->id3_hid >= 0); int next_idx = track_ridx + 1; next_idx &= MAX_TRACK_MASK; - if (tracks[next_idx].id3_hid > 0) + if (tracks[next_idx].id3_hid >= 0) copy_mp3entry(&nexttrack_id3, bufgetid3(tracks[next_idx].id3_hid)); - tracks[next_idx].taginfo_ready = (tracks[next_idx].id3_hid > 0); + tracks[next_idx].taginfo_ready = (tracks[next_idx].id3_hid >= 0); ci.filesize = CUR_TI->filesize; curtrack_id3.elapsed = 0; @@ -2094,7 +2099,7 @@ static void audio_clear_track_entries(bool clear_unbuffered) { /* If there is an unbuffer callback, call it, otherwise, * just clear the track */ - if (track_unbuffer_callback && tracks[cur_idx].id3_hid > 0) + if (track_unbuffer_callback && tracks[cur_idx].id3_hid >= 0) track_unbuffer_callback(bufgetid3(tracks[cur_idx].id3_hid)); clear_track_info(&tracks[cur_idx]); @@ -2125,7 +2130,7 @@ static bool audio_loadcodec(bool start_play) int prev_track; char codec_path[MAX_PATH]; /* Full path to codec */ - if (tracks[track_widx].id3_hid <= 0) { + if (tracks[track_widx].id3_hid < 0) { return false; } @@ -2134,7 +2139,7 @@ static bool audio_loadcodec(bool start_play) if (codec_fn == NULL) return false; - tracks[track_widx].codec_hid = false; + tracks[track_widx].codec_hid = -1; if (start_play) { @@ -2299,15 +2304,15 @@ static bool audio_load_track(int offset, bool start_play) } /* Get track metadata if we don't already have it. */ - if (tracks[track_widx].id3_hid <= 0) + if (tracks[track_widx].id3_hid < 0) { if (get_metadata(&id3, fd, trackname)) { - tracks[track_widx].id3_hid = bufalloc(&id3, sizeof(struct mp3entry), - TYPE_ID3); - tracks[track_widx].taginfo_ready = (tracks[track_widx].id3_hid > 0); + tracks[track_widx].id3_hid = + bufalloc(&id3, sizeof(struct mp3entry), TYPE_ID3); + tracks[track_widx].taginfo_ready = (tracks[track_widx].id3_hid >= 0); - if (tracks[track_widx].id3_hid <= 0) + if (tracks[track_widx].id3_hid < 0) { last_peek_offset--; close(fd); @@ -2438,7 +2443,7 @@ static bool audio_load_track(int offset, bool start_play) tracks[track_widx].audio_hid = bufopen(trackname, file_offset, type); - if (tracks[track_widx].audio_hid <= 0) + if (tracks[track_widx].audio_hid < 0) return false; if (start_play) @@ -2468,7 +2473,7 @@ static void audio_generate_postbuffer_events(void) { /* Mark the event 'sent' even if we don't really send one */ tracks[cur_idx].event_sent = true; - if (track_buffer_callback && tracks[cur_idx].id3_hid > 0) + if (track_buffer_callback && tracks[cur_idx].id3_hid >= 0) track_buffer_callback(bufgetid3(tracks[cur_idx].id3_hid)); } if (cur_idx == track_widx) @@ -2771,6 +2776,8 @@ static void audio_stop_playback(void) static void audio_play_start(size_t offset) { + int i; + #if INPUT_SRC_CAPS != 0 audio_set_input_source(AUDIO_SRC_PLAYBACK, SRCF_PLAYBACK); audio_set_output_source(AUDIO_SRC_PLAYBACK); @@ -2792,8 +2799,10 @@ static void audio_play_start(size_t offset) sound_set_volume(global_settings.volume); track_widx = track_ridx = 0; - /* Mark all entries null. */ - memset(tracks, 0, sizeof(struct track_info) * MAX_TRACK); + /* Clear all track entries. */ + for (i = 0; i < MAX_TRACK; i++) { + clear_track_info(&tracks[i]); + } last_peek_offset = -1;