summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeffrey Goode <jeffg7@gmail.com>2009-11-01 19:39:23 +0000
committerJeffrey Goode <jeffg7@gmail.com>2009-11-01 19:39:23 +0000
commite8eefe98bfd3768a9f3962bc71f0ee0431bae8b1 (patch)
tree8ce274e93fe8882fc25ed61ce5890cbd76c20e5c
parentbcadf96066c20953ae6be7447f1ee2cd8742ab4f (diff)
Code cleanup in codec_thread, playback and pcmbuf; more elegant solution to leftover samples
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@23471 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--apps/codec_thread.c370
-rw-r--r--apps/codec_thread.h5
-rw-r--r--apps/pcmbuf.c28
-rw-r--r--apps/pcmbuf.h1
-rw-r--r--apps/playback.c57
-rw-r--r--apps/playback.h1
6 files changed, 188 insertions, 274 deletions
diff --git a/apps/codec_thread.c b/apps/codec_thread.c
index 22c177589f..d4217c3789 100644
--- a/apps/codec_thread.c
+++ b/apps/codec_thread.c
@@ -20,69 +20,17 @@
*
****************************************************************************/
-//#include <stdio.h>
-//#include <string.h>
-//#include <stdlib.h>
-//#include <ctype.h>
-
#include "playback.h"
#include "codec_thread.h"
#include "system.h"
-//#include "thread.h"
-//#include "file.h"
-//#include "panic.h"
-//#include "memory.h"
-//#include "lcd.h"
-//#include "font.h"
-//#include "button.h"
#include "kernel.h"
-//#include "tree.h"
-//#include "debug.h"
-//#include "sprintf.h"
-//#include "settings.h"
#include "codecs.h"
-//#include "audio.h"
#include "buffering.h"
-//#include "appevents.h"
-//#include "voice_thread.h"
-//#include "mp3_playback.h"
-//#include "usb.h"
-//#include "storage.h"
-//#include "screens.h"
-//#include "playlist.h"
#include "pcmbuf.h"
-//#include "buffer.h"
#include "dsp.h"
#include "abrepeat.h"
-//#include "cuesheet.h"
-#ifdef HAVE_TAGCACHE
-//#include "tagcache.h"
-#endif
-#ifdef HAVE_LCD_BITMAP
-//#include "icons.h"
-//#include "peakmeter.h"
-//#include "action.h"
-#ifdef HAVE_ALBUMART
-//#include "albumart.h"
-//#include "bmp.h"
-#endif
-#endif
-//#include "lang.h"
-//#include "misc.h"
-//#include "sound.h"
#include "metadata.h"
#include "splash.h"
-//#include "talk.h"
-//#include "ata_idle_notify.h"
-
-#ifdef HAVE_RECORDING
-//#include "recording.h"
-//#include "pcm_record.h"
-#endif
-
-#ifdef IPOD_ACCESSORY_PROTOCOL
-//#include "iap.h"
-#endif
/* Define LOGF_ENABLE to enable logf output in this file */
/*#define LOGF_ENABLE*/
@@ -110,12 +58,16 @@
#endif
-/* Variables are commented with the threads that use them: *
- * A=audio, C=codec, V=voice. A suffix of - indicates that *
- * the variable is read but not updated on that thread. */
+/* Variables are commented with the threads that use them:
+ * A=audio, C=codec, V=voice. A suffix of - indicates that
+ * the variable is read but not updated on that thread.
+
+ * Unless otherwise noted, the extern variables are located
+ * in playback.c.
+ */
/* Main state control */
-static volatile bool audio_codec_loaded SHAREDBSS_ATTR = false; /* Codec loaded? (C/A-) */
+volatile bool audio_codec_loaded SHAREDBSS_ATTR = false; /* Codec loaded? (C/A-) */
extern struct mp3entry *thistrack_id3, /* the currently playing track */
*othertrack_id3; /* prev track during track-change-transition, or end of playlist,
@@ -131,25 +83,35 @@ static bool codec_requested_stop = false;
extern struct event_queue audio_queue;
extern struct event_queue codec_queue;
-extern struct event_queue pcmbuf_queue;
+
+extern struct codec_api ci; /* from codecs.c */
/* Codec thread */
-extern struct codec_api ci;
-unsigned int codec_thread_id; /* For modifying thread priority later. */
+unsigned int codec_thread_id; /* For modifying thread priority later.
+ Used by playback.c and pcmbuf.c */
static struct queue_sender_list codec_queue_sender_list;
static long codec_stack[(DEFAULT_STACK_SIZE + 0x2000)/sizeof(long)]
IBSS_ATTR;
static const char codec_thread_name[] = "codec";
+/* function prototypes */
+static bool codec_load_next_track(void);
+
+
/**************************************/
-/* Function to be called by pcm buffer callbacks.
- * Permissible Context(s): Audio interrupt
- */
-static void pcmbuf_callback_queue_post(long id, intptr_t data)
+/** misc external functions */
+
+int get_codec_base_type(int type)
{
- /* No lock since we're already in audio interrupt context */
- queue_post(&pcmbuf_queue, id, data);
+ switch (type) {
+ case AFMT_MPA_L1:
+ case AFMT_MPA_L2:
+ case AFMT_MPA_L3:
+ return AFMT_MPA_L3;
+ }
+
+ return type;
}
const char *get_codec_filename(int cod_spec)
@@ -182,7 +144,30 @@ const char *get_codec_filename(int cod_spec)
return fname;
} /* get_codec_filename */
-/* --- Codec thread --- */
+/* Borrow the codec thread and return the ID */
+void codec_thread_do_callback(void (*fn)(void), unsigned int *id)
+{
+ /* Set id before telling thread to call something; it may be
+ * needed before this function returns. */
+ if (id != NULL)
+ *id = codec_thread_id;
+
+ /* Codec thread will signal just before entering callback */
+ LOGFQUEUE("codec >| Q_CODEC_DO_CALLBACK");
+ queue_send(&codec_queue, Q_CODEC_DO_CALLBACK, (intptr_t)fn);
+}
+
+
+/** codec API callbacks */
+
+static void* codec_get_buffer(size_t *size)
+{
+ if (codec_size >= CODEC_SIZE)
+ return NULL;
+ *size = CODEC_SIZE - codec_size;
+ return &codecbuf[codec_size];
+}
+
static bool codec_pcmbuf_insert_callback(
const void *ch1, const void *ch2, int count)
{
@@ -230,37 +215,8 @@ static bool codec_pcmbuf_insert_callback(
return true;
} /* codec_pcmbuf_insert_callback */
-static void* codec_get_buffer(size_t *size)
-{
- if (codec_size >= CODEC_SIZE)
- return NULL;
- *size = CODEC_SIZE - codec_size;
- return &codecbuf[codec_size];
-}
-
-/* Between the codec and PCM track change, we need to keep updating the
- "elapsed" value of the previous (to the codec, but current to the
- user/PCM/WPS) track, so that the progressbar reaches the end.
- During that transition, the WPS will display prevtrack_id3. */
-static void codec_pcmbuf_position_callback(size_t size) ICODE_ATTR;
-static void codec_pcmbuf_position_callback(size_t size)
-{
- /* This is called from an ISR, so be quick */
- unsigned int time = size * 1000 / 4 / NATIVE_FREQUENCY +
- othertrack_id3->elapsed;
-
- if (time >= othertrack_id3->length)
- {
- pcmbuf_set_position_callback(NULL);
- othertrack_id3->elapsed = othertrack_id3->length;
- }
- else
- othertrack_id3->elapsed = time;
-}
-
static void codec_set_elapsed_callback(unsigned int value)
{
- unsigned int latency;
if (ci.seek_time)
return;
@@ -268,30 +224,33 @@ static void codec_set_elapsed_callback(unsigned int value)
ab_position_report(value);
#endif
- latency = pcmbuf_get_latency();
+ unsigned int latency = pcmbuf_get_latency();
if (value < latency)
thistrack_id3->elapsed = 0;
- else if (value - latency > thistrack_id3->elapsed ||
- value - latency < thistrack_id3->elapsed - 2)
+ else
{
- thistrack_id3->elapsed = value - latency;
+ unsigned int elapsed = value - latency;
+ if (elapsed > thistrack_id3->elapsed ||
+ elapsed < thistrack_id3->elapsed - 2)
+ {
+ thistrack_id3->elapsed = elapsed;
+ }
}
}
static void codec_set_offset_callback(size_t value)
{
- unsigned int latency;
-
if (ci.seek_time)
return;
- latency = pcmbuf_get_latency() * thistrack_id3->bitrate / 8;
+ unsigned int latency = pcmbuf_get_latency() * thistrack_id3->bitrate / 8;
if (value < latency)
thistrack_id3->offset = 0;
else
thistrack_id3->offset = value - latency;
}
+/* helper function, not a callback */
static void codec_advance_buffer_counters(size_t amount)
{
bufadvance(get_audio_hid(), amount);
@@ -346,18 +305,6 @@ static void* codec_request_buffer_callback(size_t *realsize, size_t reqsize)
return ptr;
} /* codec_request_buffer_callback */
-int get_codec_base_type(int type)
-{
- switch (type) {
- case AFMT_MPA_L1:
- case AFMT_MPA_L2:
- case AFMT_MPA_L3:
- return AFMT_MPA_L3;
- }
-
- return type;
-}
-
static void codec_advance_buffer_callback(size_t amount)
{
codec_advance_buffer_counters(amount);
@@ -370,15 +317,26 @@ static void codec_advance_buffer_loc_callback(void *ptr)
codec_advance_buffer_callback(amount);
}
+static bool codec_seek_buffer_callback(size_t newpos)
+{
+ logf("codec_seek_buffer_callback");
+
+ int ret = bufseek(get_audio_hid(), newpos);
+ if (ret == 0) {
+ ci.curpos = newpos;
+ return true;
+ }
+ else {
+ return false;
+ }
+}
+
static void codec_seek_complete_callback(void)
{
logf("seek_complete");
- /* If seeking-while-playing, pcm playback is actually paused (pcm_is_paused())
- * but audio_is_paused() is false. If seeking-while-paused, audio_is_paused() is
- * true, but pcm playback may have actually stopped due to a previous buffer clear.
- * The buffer clear below occurs with either condition. A seemless seek skips
- * this section and no buffer clear occurs.
- */
+ /* If seeking-while-playing, pcm_is_paused() is true.
+ * If seeking-while-paused, audio_is_paused() is true.
+ * A seamless seek skips this section. */
if (pcm_is_paused() || audio_is_paused())
{
/* Clear the buffer */
@@ -392,51 +350,104 @@ static void codec_seek_complete_callback(void)
ci.seek_time = 0;
}
-static bool codec_seek_buffer_callback(size_t newpos)
+static void codec_discard_codec_callback(void)
{
- logf("codec_seek_buffer_callback");
+ int *codec_hid = get_codec_hid();
+ if (*codec_hid >= 0)
+ {
+ bufclose(*codec_hid);
+ *codec_hid = -1;
+ }
+}
- int ret = bufseek(get_audio_hid(), newpos);
- if (ret == 0) {
- ci.curpos = newpos;
+static bool codec_request_next_track_callback(void)
+{
+ int prev_codectype;
+
+ if (ci.stop_codec || !audio_is_playing())
+ return false;
+
+ prev_codectype = get_codec_base_type(thistrack_id3->codectype);
+ if (!codec_load_next_track())
+ return false;
+
+ /* Seek to the beginning of the new track because if the struct
+ mp3entry was buffered, "elapsed" might not be zero (if the track has
+ been played already but not unbuffered) */
+ codec_seek_buffer_callback(thistrack_id3->first_frame_offset);
+ /* Check if the next codec is the same file. */
+ if (prev_codectype == get_codec_base_type(thistrack_id3->codectype))
+ {
+ logf("New track loaded");
+ codec_discard_codec_callback();
return true;
}
- else {
+ else
+ {
+ logf("New codec:%d/%d", thistrack_id3->codectype, prev_codectype);
return false;
}
}
static void codec_configure_callback(int setting, intptr_t value)
{
- switch (setting) {
- default:
- if (!dsp_configure(ci.dsp, setting, value))
- { logf("Illegal key:%d", setting); }
- }
+ if (!dsp_configure(ci.dsp, setting, value))
+ { logf("Illegal key:%d", setting); }
}
-static void codec_track_changed(void)
+/* Initialize codec API */
+void codec_init_codec_api(void)
{
- LOGFQUEUE("codec > audio Q_AUDIO_TRACK_CHANGED");
- queue_post(&audio_queue, Q_AUDIO_TRACK_CHANGED, 0);
+ ci.dsp = (struct dsp_config *)dsp_configure(NULL, DSP_MYDSP,
+ CODEC_IDX_AUDIO);
+ ci.codec_get_buffer = codec_get_buffer;
+ ci.pcmbuf_insert = codec_pcmbuf_insert_callback;
+ ci.set_elapsed = codec_set_elapsed_callback;
+ ci.read_filebuf = codec_filebuf_callback;
+ ci.request_buffer = codec_request_buffer_callback;
+ ci.advance_buffer = codec_advance_buffer_callback;
+ ci.advance_buffer_loc = codec_advance_buffer_loc_callback;
+ ci.seek_buffer = codec_seek_buffer_callback;
+ ci.seek_complete = codec_seek_complete_callback;
+ ci.request_next_track = codec_request_next_track_callback;
+ ci.discard_codec = codec_discard_codec_callback;
+ ci.set_offset = codec_set_offset_callback;
+ ci.configure = codec_configure_callback;
}
-static void codec_pcmbuf_track_changed_callback(void)
-{
- pcmbuf_set_position_callback(NULL);
- pcmbuf_callback_queue_post(Q_AUDIO_TRACK_CHANGED, 0);
-}
-static void codec_discard_codec_callback(void)
+/** pcmbuf track change callbacks */
+
+/* Between the codec and PCM track change, we need to keep updating the
+ "elapsed" value of the previous (to the codec, but current to the
+ user/PCM/WPS) track, so that the progressbar reaches the end.
+ During that transition, the WPS will display prevtrack_id3. */
+static void codec_pcmbuf_position_callback(size_t size) ICODE_ATTR;
+static void codec_pcmbuf_position_callback(size_t size)
{
- int *codec_hid = get_codec_hid();
- if (*codec_hid >= 0)
+ /* This is called from an ISR, so be quick */
+ unsigned int time = size * 1000 / 4 / NATIVE_FREQUENCY +
+ othertrack_id3->elapsed;
+
+ if (time >= othertrack_id3->length)
{
- bufclose(*codec_hid);
- *codec_hid = -1;
+ pcmbuf_set_position_callback(NULL);
+ othertrack_id3->elapsed = othertrack_id3->length;
}
+ else
+ othertrack_id3->elapsed = time;
}
+static void codec_pcmbuf_track_changed_callback(void)
+{
+ LOGFQUEUE("codec > pcmbuf/audio Q_AUDIO_TRACK_CHANGED");
+ pcmbuf_set_position_callback(NULL);
+ audio_post_track_change();
+}
+
+
+/** track change functions */
+
static inline void codec_gapless_track_change(void)
{
/* callback keeps the progress bar moving while the pcmbuf empties */
@@ -450,7 +461,8 @@ static inline void codec_crossfade_track_change(void)
/* Initiate automatic crossfade mode */
pcmbuf_crossfade_init(false);
/* Notify the wps that the track change starts now */
- codec_track_changed();
+ LOGFQUEUE("codec > audio Q_AUDIO_TRACK_CHANGED");
+ queue_post(&audio_queue, Q_AUDIO_TRACK_CHANGED, 0);
}
static void codec_track_skip_done(bool was_manual)
@@ -531,35 +543,7 @@ static bool codec_load_next_track(void)
}
}
-static bool codec_request_next_track_callback(void)
-{
- int prev_codectype;
-
- if (ci.stop_codec || !audio_is_playing())
- return false;
-
- prev_codectype = get_codec_base_type(thistrack_id3->codectype);
- if (!codec_load_next_track())
- return false;
-
- /* Seek to the beginning of the new track because if the struct
- mp3entry was buffered, "elapsed" might not be zero (if the track has
- been played already but not unbuffered) */
- codec_seek_buffer_callback(thistrack_id3->first_frame_offset);
- /* Check if the next codec is the same file. */
- if (prev_codectype == get_codec_base_type(thistrack_id3->codectype))
- {
- logf("New track loaded");
- codec_discard_codec_callback();
- return true;
- }
- else
- {
- logf("New codec:%d/%d", thistrack_id3->codectype, prev_codectype);
- return false;
- }
-}
-
+/** CODEC THREAD */
static void codec_thread(void)
{
struct queue_event ev;
@@ -734,44 +718,6 @@ static void codec_thread(void)
}
}
-/* Borrow the codec thread and return the ID */
-void codec_thread_do_callback(void (*fn)(void), unsigned int *id)
-{
- /* Set id before telling thread to call something; it may be
- * needed before this function returns. */
- if (id != NULL)
- *id = codec_thread_id;
-
- /* Codec thread will signal just before entering callback */
- LOGFQUEUE("codec >| Q_CODEC_DO_CALLBACK");
- queue_send(&codec_queue, Q_CODEC_DO_CALLBACK, (intptr_t)fn);
-}
-
-void codec_init_codec_api(void)
-{
- /* Initialize codec api. */
- ci.read_filebuf = codec_filebuf_callback;
- ci.pcmbuf_insert = codec_pcmbuf_insert_callback;
- ci.codec_get_buffer = codec_get_buffer;
- ci.request_buffer = codec_request_buffer_callback;
- ci.advance_buffer = codec_advance_buffer_callback;
- ci.advance_buffer_loc = codec_advance_buffer_loc_callback;
- ci.request_next_track = codec_request_next_track_callback;
- ci.seek_buffer = codec_seek_buffer_callback;
- ci.seek_complete = codec_seek_complete_callback;
- ci.set_elapsed = codec_set_elapsed_callback;
- ci.set_offset = codec_set_offset_callback;
- ci.configure = codec_configure_callback;
- ci.discard_codec = codec_discard_codec_callback;
- ci.dsp = (struct dsp_config *)dsp_configure(NULL, DSP_MYDSP,
- CODEC_IDX_AUDIO);
-}
-
-bool codec_is_loaded(void)
-{
- return audio_codec_loaded;
-}
-
void make_codec_thread(void)
{
codec_thread_id = create_thread(
diff --git a/apps/codec_thread.h b/apps/codec_thread.h
index 26a0f1fdd8..a849e07d39 100644
--- a/apps/codec_thread.h
+++ b/apps/codec_thread.h
@@ -24,12 +24,11 @@
#include <stdbool.h>
+int get_codec_base_type(int type);
const char *get_codec_filename(int cod_spec);
void codec_thread_do_callback(void (*fn)(void),
unsigned int *codec_thread_id);
-void make_codec_thread(void);
-int get_codec_base_type(int type);
void codec_init_codec_api(void);
-bool codec_is_loaded(void);
+void make_codec_thread(void);
#endif
diff --git a/apps/pcmbuf.c b/apps/pcmbuf.c
index 4a338aa900..3ec0c114da 100644
--- a/apps/pcmbuf.c
+++ b/apps/pcmbuf.c
@@ -135,12 +135,13 @@ static void pcmbuf_under_watermark(bool under);
static bool pcmbuf_flush_fillpos(void);
#define CALL_IF_EXISTS(function, args...) if (function) function(args)
-/* This function has 2 major logical parts (separated by brackets both for
+/* This function has 3 major logical parts (separated by brackets both for
* readability and variable scoping). The first part performs the
- * operastions related to finishing off the last buffer we fed to the DMA.
- * The second part performs the operations involved in sending a new buffer
- * to the DMA. Finally the function checks the status of the buffer and
- * boosts if necessary */
+ * operations related to finishing off the last buffer we fed to the DMA.
+ * The second part detects the end of playlist condition when the pcm
+ * buffer is empty except for uncommitted samples. Then they are committed.
+ * The third part performs the operations involved in sending a new buffer
+ * to the DMA. */
static void pcmbuf_callback(unsigned char** start, size_t* size) ICODE_ATTR;
static void pcmbuf_callback(unsigned char** start, size_t* size)
{
@@ -164,6 +165,15 @@ static void pcmbuf_callback(unsigned char** start, size_t* size)
if (pcmbuf_current == crossfade_chunk)
crossfade_chunk = pcmbuf_read;
}
+
+ {
+ /* Commit last samples at end of playlist */
+ if (audiobuffer_fillpos && !pcmbuf_read)
+ {
+ logf("pcmbuf callback: commit last samples");
+ pcmbuf_flush_fillpos();
+ }
+ }
{
/* Send the new buffer to the pcm */
@@ -1109,11 +1119,3 @@ bool pcmbuf_is_crossfade_enabled(void)
return crossfade_enabled;
}
-
-/** PLAY LAST REMAINING SAMPLES AT END OF PLAYBACK
- * Commit any remaining samples in the PCM buffer for playback. */
-void pcmbuf_play_remainder(void)
-{
- if (audiobuffer_fillpos)
- pcmbuf_flush_fillpos();
-}
diff --git a/apps/pcmbuf.h b/apps/pcmbuf.h
index 4cb1c1acb7..b4e551f74d 100644
--- a/apps/pcmbuf.h
+++ b/apps/pcmbuf.h
@@ -75,6 +75,5 @@ void pcmbuf_beep(unsigned int frequency, size_t duration, int amplitude);
int pcmbuf_used_descs(void);
int pcmbuf_descs(void);
-void pcmbuf_play_remainder(void);
#endif
diff --git a/apps/playback.c b/apps/playback.c
index 57ed3bdb96..35f1e8ff4d 100644
--- a/apps/playback.c
+++ b/apps/playback.c
@@ -23,70 +23,36 @@
/* TODO: Pause should be handled in here, rather than PCMBUF so that voice can
* play whilst audio is paused */
-//#include <stdio.h>
#include <string.h>
-//#include <ctype.h>
-
#include "playback.h"
#include "codec_thread.h"
-//#include "system.h"
-//#include "thread.h"
-//#include "file.h"
-//#include "panic.h"
-//#include "memory.h"
-//#include "lcd.h"
-//#include "font.h"
-//#include "button.h"
#include "kernel.h"
-//#include "tree.h"
-//#include "debug.h"
-//#include "sprintf.h"
-//#include "settings.h"
#include "codecs.h"
-//#include "audio.h"
#include "buffering.h"
-//#include "appevents.h"
#include "voice_thread.h"
-//#include "mp3_playback.h"
#include "usb.h"
-//#include "storage.h"
#include "ata.h"
-//#include "screens.h"
#include "playlist.h"
#include "pcmbuf.h"
#include "buffer.h"
-//#include "dsp.h"
-//#include "abrepeat.h"
#include "cuesheet.h"
#ifdef HAVE_TAGCACHE
#include "tagcache.h"
#endif
#ifdef HAVE_LCD_BITMAP
-//#include "icons.h"
-//#include "peakmeter.h"
-//#include "action.h"
#ifdef HAVE_ALBUMART
#include "albumart.h"
-//#include "bmp.h"
#endif
#endif
-//#include "lang.h"
-//#include "misc.h"
#include "sound.h"
#include "metadata.h"
#include "splash.h"
#include "talk.h"
-//#include "ata_idle_notify.h"
#ifdef HAVE_RECORDING
-//#include "recording.h"
#include "pcm_record.h"
#endif
-#ifdef IPOD_ACCESSORY_PROTOCOL
-//#include "iap.h"
-#endif
-
#define PLAYBACK_VOICE
/* amount of guess-space to allow for codecs that must hunt and peck
@@ -139,8 +105,9 @@ static bool audio_thread_ready SHAREDBSS_ATTR = false;
/* TBD: Split out "audio" and "playback" (ie. calling) threads */
/* Main state control */
-static volatile bool playing SHAREDBSS_ATTR = false; /* Is audio playing? (A) */
+static volatile bool playing SHAREDBSS_ATTR = false;/* Is audio playing? (A) */
static volatile bool paused SHAREDBSS_ATTR = false; /* Is audio paused? (A/C-) */
+extern volatile bool audio_codec_loaded; /* Codec loaded? (C/A-) */
/* Ring buffer where compressed audio and codecs are loaded */
static unsigned char *filebuf = NULL; /* Start of buffer (A/C-) */
@@ -233,7 +200,7 @@ static size_t buffer_margin = 5; /* Buffer margin aka anti-skip buffer (A/C-) *
/* Event queues */
struct event_queue audio_queue SHAREDBSS_ATTR;
struct event_queue codec_queue SHAREDBSS_ATTR;
-struct event_queue pcmbuf_queue SHAREDBSS_ATTR;
+static struct event_queue pcmbuf_queue SHAREDBSS_ATTR;
extern struct codec_api ci;
extern unsigned int codec_thread_id;
@@ -256,6 +223,13 @@ static void audio_stop_playback(void);
/**************************************/
+/* Post message from pcmbuf callback in the codec thread that
+ * the end of the previous track has just been played. */
+void audio_post_track_change(void)
+{
+ queue_post(&pcmbuf_queue, Q_AUDIO_TRACK_CHANGED, 0);
+}
+
/* Scan the pcmbuf queue and return true if a message pulled.
* Permissible Context(s): Thread
*/
@@ -1077,7 +1051,7 @@ static bool audio_loadcodec(bool start_play)
if (id3 && prev_id3 &&
get_codec_base_type(id3->codectype) ==
get_codec_base_type(prev_id3->codectype)
- && codec_is_loaded())
+ && audio_codec_loaded)
{
logf("Reusing prev. codec");
return true;
@@ -1634,7 +1608,7 @@ static void audio_stop_codec_flush(void)
ci.stop_codec = true;
pcmbuf_pause(true);
- while (codec_is_loaded())
+ while (audio_codec_loaded)
yield();
/* If the audio codec is not loaded any more, and the audio is still
@@ -1652,13 +1626,6 @@ static void audio_stop_playback(void)
{
if (playing)
{
- /* If still actively playing here, play out the last samples in the
- * pcm buffer before stopping. If a manual stop has occurred, the
- * paused flag is set, so don't continue playback.
- */
- if (!paused)
- pcmbuf_play_remainder();
-
/* If we were playing, save resume information */
struct mp3entry *id3 = NULL;
diff --git a/apps/playback.h b/apps/playback.h
index a53d2bb2e7..95b0bef0df 100644
--- a/apps/playback.h
+++ b/apps/playback.h
@@ -69,6 +69,7 @@ enum
};
bool audio_restore_playback(int type); /* Restores the audio buffer to handle the requested playback */
size_t audio_get_filebuflen(void);
+void audio_post_track_change(void);
int get_audio_hid(void);
int *get_codec_hid(void);
void audio_set_prev_elapsed(unsigned long setting);