diff --git a/apps/plugin.h b/apps/plugin.h index f0491f4ece..5dcbdcaee7 100644 --- a/apps/plugin.h +++ b/apps/plugin.h @@ -179,7 +179,7 @@ int plugin_open(const char *plugin, const char *parameter); * when this happens please take the opportunity to sort in * any new functions "waiting" at the end of the list. */ -#define PLUGIN_API_VERSION 281 +#define PLUGIN_API_VERSION 282 /* 239 Marks the removal of ARCHOS HWCODEC and CHARCELL */ @@ -790,7 +790,7 @@ struct plugin_api { unsigned int amplitude); size_t (*mixer_channel_get_bytes_waiting)(enum pcm_mixer_channel channel); void (*mixer_channel_set_buffer_hook)(enum pcm_mixer_channel channel, - chan_buffer_hook_fn_type fn); + const struct mixer_buffer_cbs* cbs); void (*mixer_set_frequency)(unsigned int samplerate); unsigned int (*mixer_get_frequency)(void); void (*pcmbuf_fade)(bool fade, bool in); diff --git a/apps/plugins/oscilloscope.c b/apps/plugins/oscilloscope.c index 49c0aeda4e..123fee2541 100644 --- a/apps/plugins/oscilloscope.c +++ b/apps/plugins/oscilloscope.c @@ -1441,6 +1441,10 @@ static void waveform_buffer_callback(const void *start, size_t size) waveform_buffer_have = have + copy; } +static const struct mixer_buffer_cbs buf_cbs = { + .next_buffer = waveform_buffer_callback, +}; + static void waveform_buffer_reset(void) { /* only called when callback is off */ @@ -1909,7 +1913,7 @@ static void graphmode_setup(void) if (osc.graphmode == GRAPH_WAVEFORM) { rb->mixer_channel_set_buffer_hook(channel, - waveform_buffer_callback); + &buf_cbs); #ifdef HAVE_SCHEDULER_BOOSTCTRL rb->trigger_cpu_boost(); /* Just looks better */ #endif @@ -2013,7 +2017,7 @@ void switch_channel(enum pcm_mixer_channel new_channel) #ifdef OSCILLOSCOPE_GRAPHMODE if (osc.graphmode == GRAPH_WAVEFORM) - rb->mixer_channel_set_buffer_hook(channel, waveform_buffer_callback); + rb->mixer_channel_set_buffer_hook(channel, &buf_cbs); #endif } #endif /* USB_ENABLE_AUDIO */ diff --git a/docs/PLUGIN_API b/docs/PLUGIN_API index 4a895cc0a3..01acbe2181 100644 --- a/docs/PLUGIN_API +++ b/docs/PLUGIN_API @@ -1624,7 +1624,7 @@ void mixer_channel_set_amplitude(enum pcm_mixer_channel channel, unsigned int am \param amplitude \description -void mixer_channel_set_buffer_hook(enum pcm_mixer_channel channel, chan_buffer_hook_fn_type fn) +void mixer_channel_set_buffer_hook(enum pcm_mixer_channel channel, const struct mixer_buffer_cbs* cbs) \param channel \param fn \description diff --git a/firmware/export/pcm_mixer.h b/firmware/export/pcm_mixer.h index 99ded55082..0607b474f6 100644 --- a/firmware/export/pcm_mixer.h +++ b/firmware/export/pcm_mixer.h @@ -133,12 +133,15 @@ void mixer_channel_calculate_peaks(enum pcm_mixer_channel channel, void mixer_adjust_channel_address(enum pcm_mixer_channel channel, off_t offset); -/* Set a hook that is called upon getting a new source buffer for a channel - NOTE: Called for each buffer, not each mixer chunk */ -typedef void (*chan_buffer_hook_fn_type)(const void *start, size_t size); +struct mixer_buffer_cbs { + /* Called for each buffer, not each mixer chunk */ + void (*next_buffer)(const void *start, size_t size); + void (*sampr_changed)(uint32_t sampr); +}; +/* Set a hook that is called upon getting a new source buffer for a channel */ void mixer_channel_set_buffer_hook(enum pcm_mixer_channel channel, - chan_buffer_hook_fn_type fn); + const struct mixer_buffer_cbs* cbs); /* Stop ALL channels and PCM and reset state */ void mixer_reset(void); diff --git a/firmware/pcm_mixer.c b/firmware/pcm_mixer.c index f093084572..46c2f6254d 100644 --- a/firmware/pcm_mixer.c +++ b/firmware/pcm_mixer.c @@ -42,13 +42,13 @@ static unsigned int mix_frame_size = MIX_FRAME_SAMPLES*4; /* Descriptor for each channel */ struct mixer_channel { - const void *start; /* Buffer pointer */ - size_t size; /* Bytes remaining */ - size_t last_size; /* Size of consumed data in prev. cycle */ - const struct mixer_play_cbs* cbs; /* Registered callbacks */ - enum channel_status status; /* Playback status */ - uint32_t amplitude; /* Amp. factor: 0x0000 = mute, 0x10000 = unity */ - chan_buffer_hook_fn_type buffer_hook; /* Callback for new buffer */ + const void *start; /* Buffer pointer */ + size_t size; /* Bytes remaining */ + size_t last_size; /* Size of consumed data in prev. cycle */ + const struct mixer_play_cbs* play_cbs; /* Registered callbacks */ + enum channel_status status; /* Playback status */ + uint32_t amplitude; /* Amp. factor: 0x0000 = mute, 0x10000 = unity */ + const struct mixer_buffer_cbs* buf_cbs; /* Callback for new buffer */ }; #if (defined(HW_HAVE_192) || defined(HW_HAVE_176)) @@ -119,8 +119,8 @@ static void mixer_pcm_callback(const void **addr, size_t *size) static inline void chan_call_buffer_hook(struct mixer_channel *chan) { - if (UNLIKELY(chan->buffer_hook)) - chan->buffer_hook(chan->start, chan->size); + if (UNLIKELY(chan->buf_cbs && chan->buf_cbs->next_buffer)) + chan->buf_cbs->next_buffer(chan->start, chan->size); } /* Buffering callback - calls sub-callbacks and mixes the data for next @@ -154,9 +154,9 @@ fill_frame: if (chan->size == 0) { - if (chan->cbs->get_more) + if (chan->play_cbs->get_more) { - chan->cbs->get_more(&chan->start, &chan->size); + chan->play_cbs->get_more(&chan->start, &chan->size); ALIGN_AUDIOBUF(chan->start, chan->size); } @@ -317,7 +317,7 @@ void mixer_channel_play_data(enum pcm_mixer_channel channel, chan->start = start; chan->size = size; chan->last_size = 0; - chan->cbs = cbs; + chan->play_cbs = cbs; mixer_activate_channel(chan); chan_call_buffer_hook(chan); @@ -429,15 +429,14 @@ void mixer_adjust_channel_address(enum pcm_mixer_channel channel, pcm_play_unlock(); } -/* Set a hook that is called upon getting a new source buffer for a channel - NOTE: Called for each buffer, not each mixer chunk */ +/* Set a hook that is called upon getting a new source buffer for a channel */ void mixer_channel_set_buffer_hook(enum pcm_mixer_channel channel, - chan_buffer_hook_fn_type fn) + const struct mixer_buffer_cbs* cbs) { struct mixer_channel *chan = &channels[channel]; pcm_play_lock(); - chan->buffer_hook = fn; + chan->buf_cbs = cbs; pcm_play_unlock(); } @@ -471,18 +470,18 @@ void mixer_set_frequency(unsigned int samplerate) struct mixer_channel* chan = active_channels[i]; /* Notify upstreams */ - if (chan->cbs) + if (chan->play_cbs) { - if (chan->cbs->sampr_changed) + if (chan->play_cbs->sampr_changed) { - chan->cbs->sampr_changed(samplerate); + chan->play_cbs->sampr_changed(samplerate); } - if (chan->cbs->get_more) + if (chan->play_cbs->get_more) { /* Remake buffer */ const void *start = NULL; size_t size; - chan->cbs->get_more(&start, &size); + chan->play_cbs->get_more(&start, &size); if (start && size) { chan->start = start; chan->size = size; @@ -492,6 +491,14 @@ void mixer_set_frequency(unsigned int samplerate) } } } + /* Notify buffer monitor */ + if (chan->buf_cbs) + { + if (chan->buf_cbs->sampr_changed) + { + chan->buf_cbs->sampr_changed(samplerate); + } + } } /* Work out how much space we really need */