summaryrefslogtreecommitdiff
path: root/apps/plugins/mpegplayer/pcm_output.c
diff options
context:
space:
mode:
authorMichael Sevakis <jethead71@rockbox.org>2008-02-01 02:25:15 +0000
committerMichael Sevakis <jethead71@rockbox.org>2008-02-01 02:25:15 +0000
commitf90cbcb652af3bf794ec61d7f7ec3de00c8b7cb2 (patch)
tree62c13ffdeb5112181897103a6a015cfc1fab98ae /apps/plugins/mpegplayer/pcm_output.c
parent7e402d8202af409a0ea8f3f2676a2e6f501af05b (diff)
mpegplayer: Use the core DSP to process audio. Removes the sample rate restriction on audio and any mpeg audio samplerate may be used. Use the global sound settings for audio output with the option to force any one of the processing stages off. All are forced off by default. I didn't personally care to fully duplicate the Sound Settings menu which would have been needed since using the core one would affect settings globally and exactly the same configuration probably isn't desired since the CPU load for video playback is much greater. Rebalance the threading to compensate with some expense to buffering speed.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@16194 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/plugins/mpegplayer/pcm_output.c')
-rw-r--r--apps/plugins/mpegplayer/pcm_output.c35
1 files changed, 26 insertions, 9 deletions
diff --git a/apps/plugins/mpegplayer/pcm_output.c b/apps/plugins/mpegplayer/pcm_output.c
index ac89308af1..e17f635f72 100644
--- a/apps/plugins/mpegplayer/pcm_output.c
+++ b/apps/plugins/mpegplayer/pcm_output.c
@@ -33,6 +33,7 @@ static struct pcm_frame_header * ALIGNED_ATTR(4) pcmbuf_head IBSS_ATTR;
static struct pcm_frame_header * ALIGNED_ATTR(4) pcmbuf_tail IBSS_ATTR;
/* Bytes */
+static ssize_t pcmbuf_curr_size IBSS_ATTR; /* Size of currently playing frame */
static uint64_t pcmbuf_read IBSS_ATTR; /* Number of bytes read by DMA */
static uint64_t pcmbuf_written IBSS_ATTR; /* Number of bytes written by source */
static ssize_t pcmbuf_threshold IBSS_ATTR; /* Non-silence threshold */
@@ -42,6 +43,9 @@ static uint32_t clock_base IBSS_ATTR; /* Our base clock */
static uint32_t clock_start IBSS_ATTR; /* Clock at playback start */
static int32_t clock_adjust IBSS_ATTR; /* Clock drift adjustment */
+int pcm_skipped = 0;
+int pcm_underruns = 0;
+
/* Small silence clip. ~5.80ms @ 44.1kHz */
static int16_t silence[256*2] ALIGNED_ATTR(4) = { 0 };
@@ -51,7 +55,7 @@ static inline void pcm_advance_buffer(struct pcm_frame_header **p,
{
*p = SKIPBYTES(*p, size);
if (*p >= pcmbuf_end)
- *p = pcm_buffer;
+ *p = SKIPBYTES(*p, -PCMOUT_BUFSIZE);
}
/* Inline internally but not externally */
@@ -68,7 +72,13 @@ inline ssize_t pcm_output_free(void)
/* Audio DMA handler */
static void get_more(unsigned char **start, size_t *size)
{
- ssize_t sz = pcm_output_used();
+ ssize_t sz;
+
+ /* Free-up the last frame played frame if any */
+ pcmbuf_read += pcmbuf_curr_size;
+ pcmbuf_curr_size = 0;
+
+ sz = pcm_output_used();
if (sz > pcmbuf_threshold)
{
@@ -95,16 +105,20 @@ static void get_more(unsigned char **start, size_t *size)
/* Frame more than 100ms late - drop it */
pcm_advance_buffer(&pcmbuf_head, sz);
pcmbuf_read += sz;
+ pcm_skipped++;
if (pcmbuf_read < pcmbuf_written)
continue;
+
+ /* Ran out so revert to default watermark */
+ pcmbuf_threshold = PCMOUT_PLAY_WM;
}
else if (offset < 100*CLOCK_RATE/1000)
{
/* Frame less than 100ms early - play it */
- *start = (unsigned char *)pcmbuf_head->data;
+ *start = pcmbuf_head->data;
pcm_advance_buffer(&pcmbuf_head, sz);
- pcmbuf_read += sz;
+ pcmbuf_curr_size = sz;
sz -= sizeof (struct pcm_frame_header);
@@ -124,6 +138,9 @@ static void get_more(unsigned char **start, size_t *size)
else
{
/* Ran out so revert to default watermark */
+ if (pcmbuf_threshold == PCMOUT_LOW_WM)
+ pcm_underruns++;
+
pcmbuf_threshold = PCMOUT_PLAY_WM;
}
@@ -164,8 +181,9 @@ void pcm_output_flush(void)
rb->pcm_play_stop();
pcmbuf_threshold = PCMOUT_PLAY_WM;
- pcmbuf_read = pcmbuf_written = 0;
+ pcmbuf_curr_size = pcmbuf_read = pcmbuf_written = 0;
pcmbuf_head = pcmbuf_tail = pcm_buffer;
+ pcm_skipped = pcm_underruns = 0;
/* Restart if playing state was current */
if (playing && !paused)
@@ -251,10 +269,9 @@ bool pcm_output_init(void)
pcmbuf_head = pcm_buffer;
pcmbuf_tail = pcm_buffer;
pcmbuf_end = SKIPBYTES(pcm_buffer, PCMOUT_BUFSIZE);
- pcmbuf_read = 0;
- pcmbuf_written = 0;
+ pcmbuf_curr_size = pcmbuf_read = pcmbuf_written = 0;
- rb->pcm_set_frequency(SAMPR_44);
+ rb->pcm_set_frequency(NATIVE_FREQUENCY);
#if INPUT_SRC_CAPS != 0
/* Select playback */
@@ -264,7 +281,7 @@ bool pcm_output_init(void)
#if SILENCE_TEST_TONE
/* Make the silence clip a square wave */
- const int16_t silence_amp = 32767 / 16;
+ const int16_t silence_amp = INT16_MAX / 16;
unsigned i;
for (i = 0; i < ARRAYLEN(silence); i += 2)