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
* 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);

View file

@ -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 */

View file

@ -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

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,
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);

View file

@ -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 */