diff options
author | Michael Sevakis <jethead71@rockbox.org> | 2012-05-02 17:22:28 -0400 |
---|---|---|
committer | Michael Sevakis <jethead71@rockbox.org> | 2012-05-02 17:22:28 -0400 |
commit | da6cebb6b0b17b4a75a2bd4f51b7cf70b5dafe40 (patch) | |
tree | df0eb18120c38ec7b08d3ae1e0837f0781065e87 /firmware | |
parent | 3d3a144cf68186fd34f7bf11181b7757c7a6018d (diff) | |
download | rockbox-da6cebb6b0b17b4a75a2bd4f51b7cf70b5dafe40.tar.gz rockbox-da6cebb6b0b17b4a75a2bd4f51b7cf70b5dafe40.zip |
Use buflib for the allocation of voice PCM resources.
Buffers are not allocated and thread is not created until the first
call where voice is required.
Adds a different callback (sync_callback) to buflib so that other
sorts of synchonization are possible, such as briefly locking-out the
PCM callback for a buffer move. It's sort of a messy addition but it
is needed so voice decoding won't have to be stopped when its buffer
is moved.
Change-Id: I4d4d8c35eed5dd15fb7ee7df9323af3d036e92b3
Diffstat (limited to 'firmware')
-rw-r--r-- | firmware/buflib.c | 28 | ||||
-rw-r--r-- | firmware/export/mp3_playback.h | 3 | ||||
-rw-r--r-- | firmware/export/pcm_mixer.h | 6 | ||||
-rw-r--r-- | firmware/font.c | 2 | ||||
-rw-r--r-- | firmware/include/buflib.h | 6 | ||||
-rw-r--r-- | firmware/pcm_mixer.c | 10 |
6 files changed, 42 insertions, 13 deletions
diff --git a/firmware/buflib.c b/firmware/buflib.c index 2d4b4b8bb2..f73c8ce4fb 100644 --- a/firmware/buflib.c +++ b/firmware/buflib.c @@ -210,23 +210,27 @@ move_block(struct buflib_context* ctx, union buflib_data* block, int shift) /* disable IRQs to make accessing the buffer from interrupt context safe. */ /* protect the move callback, as a cached global pointer might be updated * in it. and protect "tmp->alloc = new_start" for buflib_get_data() */ - disable_irq(); /* call the callback before moving */ - if (ops) + if (ops && ops->sync_callback) + ops->sync_callback(handle, true); + else + disable_irq(); + + bool retval = false; + if (!ops || ops->move_callback(handle, tmp->alloc, new_start) + != BUFLIB_CB_CANNOT_MOVE) { - if (ops->move_callback(handle, tmp->alloc, new_start) - == BUFLIB_CB_CANNOT_MOVE) - { - enable_irq(); - return false; - } + tmp->alloc = new_start; /* update handle table */ + memmove(new_block, block, block->val * sizeof(union buflib_data)); + retval = true; } - tmp->alloc = new_start; /* update handle table */ - memmove(new_block, block, block->val * sizeof(union buflib_data)); + if (ops && ops->sync_callback) + ops->sync_callback(handle, false); + else + enable_irq(); - enable_irq(); - return true; + return retval; } /* Compact allocations and handle table, adjusting handle pointers as needed. diff --git a/firmware/export/mp3_playback.h b/firmware/export/mp3_playback.h index de27a2a46d..7434021611 100644 --- a/firmware/export/mp3_playback.h +++ b/firmware/export/mp3_playback.h @@ -27,7 +27,10 @@ #include <stdbool.h> /* callback fn */ +#ifndef MP3_PLAY_CALLBACK_DEFINED +#define MP3_PLAY_CALLBACK_DEFINED typedef void (*mp3_play_callback_t)(const void **start, size_t* size); +#endif /* functions formerly in mpeg.c */ void mp3_init(int volume, int bass, int treble, int balance, int loudness, diff --git a/firmware/export/pcm_mixer.h b/firmware/export/pcm_mixer.h index 6e1632d5ae..5d8deb2bbf 100644 --- a/firmware/export/pcm_mixer.h +++ b/firmware/export/pcm_mixer.h @@ -22,6 +22,8 @@ #ifndef PCM_MIXER_H #define PCM_MIXER_H +#include <sys/types.h> + /** Simple config **/ /* Length of PCM frames (always) */ @@ -111,6 +113,10 @@ const void * mixer_channel_get_buffer(enum pcm_mixer_channel channel, int *count void mixer_channel_calculate_peaks(enum pcm_mixer_channel channel, int *left, int *right); +/* Adjust channel pointer by a given offset to support movable buffers */ +void mixer_adjust_channel_address(enum pcm_mixer_channel channel, + off_t offset); + /* Stop ALL channels and PCM and reset state */ void mixer_reset(void); diff --git a/firmware/font.c b/firmware/font.c index 895ce15446..4b21f0ffe3 100644 --- a/firmware/font.c +++ b/firmware/font.c @@ -141,7 +141,7 @@ void font_lock(int font_id, bool lock) lock_font_handle(buflib_allocations[font_id], lock); } -static struct buflib_callbacks buflibops = {buflibmove_callback, NULL }; +static struct buflib_callbacks buflibops = {buflibmove_callback, NULL, NULL }; static inline struct font *pf_from_handle(int handle) { diff --git a/firmware/include/buflib.h b/firmware/include/buflib.h index 9cd7c0b2e0..6c9ccf7402 100644 --- a/firmware/include/buflib.h +++ b/firmware/include/buflib.h @@ -103,6 +103,12 @@ struct buflib_callbacks { * at least shrinkable */ int (*shrink_callback)(int handle, unsigned hints, void* start, size_t old_size); + /** + * This is called when special steps must be taken for synchronization + * both before the move_callback is called and after the data has been + * moved. + */ + void (*sync_callback)(int handle, bool sync_on); }; #define BUFLIB_SHRINK_POS_MASK ((1<<0|1<<1)<<30) diff --git a/firmware/pcm_mixer.c b/firmware/pcm_mixer.c index c3e7ffa478..85d31ade70 100644 --- a/firmware/pcm_mixer.c +++ b/firmware/pcm_mixer.c @@ -406,6 +406,16 @@ void mixer_channel_calculate_peaks(enum pcm_mixer_channel channel, *right = peaks->val[1]; } +/* Adjust channel pointer by a given offset to support movable buffers */ +void mixer_adjust_channel_address(enum pcm_mixer_channel channel, + off_t offset) +{ + pcm_play_lock(); + /* Makes no difference if it's stopped */ + channels[channel].start += offset; + pcm_play_unlock(); +} + /* Stop ALL channels and PCM and reset state */ void mixer_reset(void) { |