From fbac4f84442b0e2a5cc9c0845ccabf0af554e82a Mon Sep 17 00:00:00 2001 From: Michael Sevakis Date: Wed, 22 Nov 2006 09:13:14 +0000 Subject: [PATCH] Audio bugfixes. Should wait for voice codec to reload before returning buffer when stealing voice. Certain variables that get or may get used during an IRQ should be declared 'volatile'. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@11572 a1c6a512-1295-4272-9138-f99709370657 --- apps/playback.c | 27 ++++++++++++++++++------- firmware/pcm_playback.c | 6 +++--- firmware/pcm_record.c | 4 ++-- firmware/target/coldfire/pcm-coldfire.c | 10 ++++----- 4 files changed, 30 insertions(+), 17 deletions(-) diff --git a/apps/playback.c b/apps/playback.c index 9d03cd266c..2b08a99a8a 100644 --- a/apps/playback.c +++ b/apps/playback.c @@ -396,8 +396,18 @@ unsigned char *audio_get_buffer(bool talk_buf, size_t *buffer_size) logf("get buffer: talk_buf"); /* ok to use everything from audiobuf to audiobufend */ if (buffer_state != BUFFER_STATE_TRASHED) + { talk_buffer_steal(); - buffer_state = BUFFER_STATE_TRASHED; +#ifdef PLAYBACK_VOICE + if (NULL != iram_buf[CODEC_IDX_VOICE]) + { + /* Voice could be swapped out - wait for it to return */ + while (current_codec != CODEC_IDX_VOICE) + yield(); + } +#endif /* PLAYBACK_VOICE */ + buffer_state = BUFFER_STATE_TRASHED; + } } else { @@ -423,6 +433,10 @@ void audio_iram_steal(void) #ifdef PLAYBACK_VOICE if (NULL != iram_buf[CODEC_IDX_VOICE]) { + /* Can't already be stolen */ + if (voice_iram_stolen) + return; + /* Wait for voice to swap back in if current codec was audio */ while (current_codec != CODEC_IDX_VOICE) yield(); @@ -455,15 +469,14 @@ unsigned char *audio_get_recording_buffer(size_t *buffer_size) #ifdef PLAYBACK_VOICE #ifdef IRAM_STEAL - end = dram_buf[CODEC_IDX_VOICE] ? - dram_buf[CODEC_IDX_VOICE] : audiobufend; + end = dram_buf[CODEC_IDX_VOICE]; #else - end = iram_buf[CODEC_IDX_VOICE] ? - iram_buf[CODEC_IDX_VOICE] : audiobufend; + end = iram_buf[CODEC_IDX_VOICE]; #endif /* IRAM_STEAL */ -#else - end = audiobufend; + if (NULL == end) #endif /* PLAYBACK_VOICE */ + end = audiobufend; + buffer_state = BUFFER_STATE_TRASHED; diff --git a/firmware/pcm_playback.c b/firmware/pcm_playback.c index a2d09e7c8d..8b5479cae9 100644 --- a/firmware/pcm_playback.c +++ b/firmware/pcm_playback.c @@ -48,9 +48,9 @@ be shared semi-privately **/ /* the registered callback function to ask for more mp3 data */ -pcm_more_callback_type pcm_callback_for_more = NULL; -bool pcm_playing = false; -bool pcm_paused = false; +volatile pcm_more_callback_type pcm_callback_for_more = NULL; +volatile bool pcm_playing = false; +volatile bool pcm_paused = false; void pcm_play_dma_start(const void *addr, size_t size); void pcm_play_dma_stop(void); diff --git a/firmware/pcm_record.c b/firmware/pcm_record.c index 04289f36ec..a1b2afd1bf 100644 --- a/firmware/pcm_record.c +++ b/firmware/pcm_record.c @@ -55,9 +55,9 @@ be shared semi-privately **/ /* the registered callback function for when more data is available */ -pcm_more_callback_type pcm_callback_more_ready = NULL; +volatile pcm_more_callback_type pcm_callback_more_ready = NULL; /* DMA transfer in is currently active */ -bool pcm_recording = false; +volatile bool pcm_recording = false; /* APIs implemented in the target-specific portion */ void pcm_rec_dma_start(const void *addr, size_t size); diff --git a/firmware/target/coldfire/pcm-coldfire.c b/firmware/target/coldfire/pcm-coldfire.c index 9cd66d772a..a0d3b67f58 100644 --- a/firmware/target/coldfire/pcm-coldfire.c +++ b/firmware/target/coldfire/pcm-coldfire.c @@ -44,13 +44,13 @@ /** Semi-private shared symbols **/ /* the registered callback function to ask for more pcm data */ -extern pcm_more_callback_type pcm_callback_for_more; -extern bool pcm_playing; -extern bool pcm_paused; +extern volatile pcm_more_callback_type pcm_callback_for_more; +extern volatile bool pcm_playing; +extern volatile bool pcm_paused; /* the registered callback function for when more data is available */ -extern pcm_more_callback_type pcm_callback_more_ready; -extern bool pcm_recording; +extern volatile pcm_more_callback_type pcm_callback_more_ready; +extern volatile bool pcm_recording; /* peaks */ static int play_peak_left, play_peak_right;