summaryrefslogtreecommitdiffstats
path: root/firmware
diff options
context:
space:
mode:
authorMichael Sevakis <jethead71@rockbox.org>2012-05-02 17:22:28 -0400
committerMichael Sevakis <jethead71@rockbox.org>2012-05-02 17:22:28 -0400
commitda6cebb6b0b17b4a75a2bd4f51b7cf70b5dafe40 (patch)
treedf0eb18120c38ec7b08d3ae1e0837f0781065e87 /firmware
parent3d3a144cf68186fd34f7bf11181b7757c7a6018d (diff)
downloadrockbox-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.c28
-rw-r--r--firmware/export/mp3_playback.h3
-rw-r--r--firmware/export/pcm_mixer.h6
-rw-r--r--firmware/font.c2
-rw-r--r--firmware/include/buflib.h6
-rw-r--r--firmware/pcm_mixer.c10
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)
{