pcm_mixer: introduce mixer_buffer_cbs

intended to add sampr_changed callback to buffer hook as well as mixer
playback

Change-Id: I9df6194a884cfb813342a827b7fdc3bccbe3d60c
This commit is contained in:
mojyack 2026-02-24 16:39:42 +09:00 committed by Solomon Peachy
parent cb04b8167c
commit e2040cc98c
5 changed files with 44 additions and 30 deletions

View file

@ -179,7 +179,7 @@ int plugin_open(const char *plugin, const char *parameter);
* when this happens please take the opportunity to sort in * when this happens please take the opportunity to sort in
* any new functions "waiting" at the end of the list. * 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 */ /* 239 Marks the removal of ARCHOS HWCODEC and CHARCELL */
@ -790,7 +790,7 @@ struct plugin_api {
unsigned int amplitude); unsigned int amplitude);
size_t (*mixer_channel_get_bytes_waiting)(enum pcm_mixer_channel channel); size_t (*mixer_channel_get_bytes_waiting)(enum pcm_mixer_channel channel);
void (*mixer_channel_set_buffer_hook)(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); void (*mixer_set_frequency)(unsigned int samplerate);
unsigned int (*mixer_get_frequency)(void); unsigned int (*mixer_get_frequency)(void);
void (*pcmbuf_fade)(bool fade, bool in); void (*pcmbuf_fade)(bool fade, bool in);

View file

@ -1441,6 +1441,10 @@ static void waveform_buffer_callback(const void *start, size_t size)
waveform_buffer_have = have + copy; waveform_buffer_have = have + copy;
} }
static const struct mixer_buffer_cbs buf_cbs = {
.next_buffer = waveform_buffer_callback,
};
static void waveform_buffer_reset(void) static void waveform_buffer_reset(void)
{ {
/* only called when callback is off */ /* only called when callback is off */
@ -1909,7 +1913,7 @@ static void graphmode_setup(void)
if (osc.graphmode == GRAPH_WAVEFORM) if (osc.graphmode == GRAPH_WAVEFORM)
{ {
rb->mixer_channel_set_buffer_hook(channel, rb->mixer_channel_set_buffer_hook(channel,
waveform_buffer_callback); &buf_cbs);
#ifdef HAVE_SCHEDULER_BOOSTCTRL #ifdef HAVE_SCHEDULER_BOOSTCTRL
rb->trigger_cpu_boost(); /* Just looks better */ rb->trigger_cpu_boost(); /* Just looks better */
#endif #endif
@ -2013,7 +2017,7 @@ void switch_channel(enum pcm_mixer_channel new_channel)
#ifdef OSCILLOSCOPE_GRAPHMODE #ifdef OSCILLOSCOPE_GRAPHMODE
if (osc.graphmode == GRAPH_WAVEFORM) 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
} }
#endif /* USB_ENABLE_AUDIO */ #endif /* USB_ENABLE_AUDIO */

View file

@ -1624,7 +1624,7 @@ void mixer_channel_set_amplitude(enum pcm_mixer_channel channel, unsigned int am
\param amplitude \param amplitude
\description \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 channel
\param fn \param fn
\description \description

View file

@ -133,12 +133,15 @@ void mixer_channel_calculate_peaks(enum pcm_mixer_channel channel,
void mixer_adjust_channel_address(enum pcm_mixer_channel channel, void mixer_adjust_channel_address(enum pcm_mixer_channel channel,
off_t offset); off_t offset);
/* Set a hook that is called upon getting a new source buffer for a channel struct mixer_buffer_cbs {
NOTE: Called for each buffer, not each mixer chunk */ /* Called for each buffer, not each mixer chunk */
typedef void (*chan_buffer_hook_fn_type)(const void *start, size_t size); 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, 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 */ /* Stop ALL channels and PCM and reset state */
void mixer_reset(void); void mixer_reset(void);

View file

@ -42,13 +42,13 @@ static unsigned int mix_frame_size = MIX_FRAME_SAMPLES*4;
/* Descriptor for each channel */ /* Descriptor for each channel */
struct mixer_channel struct mixer_channel
{ {
const void *start; /* Buffer pointer */ const void *start; /* Buffer pointer */
size_t size; /* Bytes remaining */ size_t size; /* Bytes remaining */
size_t last_size; /* Size of consumed data in prev. cycle */ size_t last_size; /* Size of consumed data in prev. cycle */
const struct mixer_play_cbs* cbs; /* Registered callbacks */ const struct mixer_play_cbs* play_cbs; /* Registered callbacks */
enum channel_status status; /* Playback status */ enum channel_status status; /* Playback status */
uint32_t amplitude; /* Amp. factor: 0x0000 = mute, 0x10000 = unity */ uint32_t amplitude; /* Amp. factor: 0x0000 = mute, 0x10000 = unity */
chan_buffer_hook_fn_type buffer_hook; /* Callback for new buffer */ const struct mixer_buffer_cbs* buf_cbs; /* Callback for new buffer */
}; };
#if (defined(HW_HAVE_192) || defined(HW_HAVE_176)) #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) static inline void chan_call_buffer_hook(struct mixer_channel *chan)
{ {
if (UNLIKELY(chan->buffer_hook)) if (UNLIKELY(chan->buf_cbs && chan->buf_cbs->next_buffer))
chan->buffer_hook(chan->start, chan->size); chan->buf_cbs->next_buffer(chan->start, chan->size);
} }
/* Buffering callback - calls sub-callbacks and mixes the data for next /* Buffering callback - calls sub-callbacks and mixes the data for next
@ -154,9 +154,9 @@ fill_frame:
if (chan->size == 0) 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); ALIGN_AUDIOBUF(chan->start, chan->size);
} }
@ -317,7 +317,7 @@ void mixer_channel_play_data(enum pcm_mixer_channel channel,
chan->start = start; chan->start = start;
chan->size = size; chan->size = size;
chan->last_size = 0; chan->last_size = 0;
chan->cbs = cbs; chan->play_cbs = cbs;
mixer_activate_channel(chan); mixer_activate_channel(chan);
chan_call_buffer_hook(chan); chan_call_buffer_hook(chan);
@ -429,15 +429,14 @@ void mixer_adjust_channel_address(enum pcm_mixer_channel channel,
pcm_play_unlock(); pcm_play_unlock();
} }
/* Set a hook that is called upon getting a new source buffer for a channel /* Set a hook that is called upon getting a new source buffer for a channel */
NOTE: Called for each buffer, not each mixer chunk */
void mixer_channel_set_buffer_hook(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)
{ {
struct mixer_channel *chan = &channels[channel]; struct mixer_channel *chan = &channels[channel];
pcm_play_lock(); pcm_play_lock();
chan->buffer_hook = fn; chan->buf_cbs = cbs;
pcm_play_unlock(); pcm_play_unlock();
} }
@ -471,18 +470,18 @@ void mixer_set_frequency(unsigned int samplerate)
struct mixer_channel* chan = active_channels[i]; struct mixer_channel* chan = active_channels[i];
/* Notify upstreams */ /* 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 */ /* Remake buffer */
const void *start = NULL; const void *start = NULL;
size_t size; size_t size;
chan->cbs->get_more(&start, &size); chan->play_cbs->get_more(&start, &size);
if (start && size) { if (start && size) {
chan->start = start; chan->start = start;
chan->size = size; 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 */ /* Work out how much space we really need */