mirror of
https://github.com/Rockbox/rockbox.git
synced 2026-05-12 11:43:16 -04:00
pcm_mixer: introduce mixer_play_cbs
the added sampr_changed callback can be used to notify the mixer user of frequency changes Change-Id: I309db76576090fd5c019a1ba082af446129dd4a3
This commit is contained in:
parent
86639acc5e
commit
cb04b8167c
20 changed files with 128 additions and 47 deletions
|
|
@ -97,7 +97,7 @@ void beep_play(unsigned int frequency, unsigned int duration,
|
|||
beep_get_more(&start, &size);
|
||||
|
||||
mixer_channel_set_amplitude(PCM_MIXER_CHAN_BEEP, MIX_AMP_UNITY);
|
||||
mixer_channel_play_data(PCM_MIXER_CHAN_BEEP,
|
||||
beep_count ? beep_get_more : NULL,
|
||||
start, size);
|
||||
static struct mixer_play_cbs cbs;
|
||||
cbs.get_more = beep_count ? beep_get_more : NULL;
|
||||
mixer_channel_play_data(PCM_MIXER_CHAN_BEEP, &cbs, start, size);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@
|
|||
#include "pcmbuf.h"
|
||||
#include "dsp-util.h"
|
||||
#include "playback.h"
|
||||
#include "dsp_core.h"
|
||||
#include "codec_thread.h"
|
||||
|
||||
/* Define LOGF_ENABLE to enable logf output in this file */
|
||||
|
|
@ -836,6 +837,12 @@ static void pcmbuf_pcm_callback(const void **start, size_t *size)
|
|||
}
|
||||
}
|
||||
|
||||
static void pcmbuf_sampr_callback(uint32_t sampr)
|
||||
{
|
||||
struct dsp_config* dsp = dsp_get_config(CODEC_IDX_AUDIO);
|
||||
dsp_configure(dsp, DSP_SET_OUT_FREQUENCY, sampr);
|
||||
}
|
||||
|
||||
/* Force playback */
|
||||
void pcmbuf_play_start(void)
|
||||
{
|
||||
|
|
@ -845,8 +852,11 @@ void pcmbuf_play_start(void)
|
|||
chunk_widx != chunk_ridx)
|
||||
{
|
||||
current_desc = NULL;
|
||||
mixer_channel_play_data(PCM_MIXER_CHAN_PLAYBACK, pcmbuf_pcm_callback,
|
||||
NULL, 0);
|
||||
static const struct mixer_play_cbs cbs = {
|
||||
.get_more = pcmbuf_pcm_callback,
|
||||
.sampr_changed = pcmbuf_sampr_callback,
|
||||
};
|
||||
mixer_channel_play_data(PCM_MIXER_CHAN_PLAYBACK, &cbs, NULL, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -782,7 +782,7 @@ struct plugin_api {
|
|||
void (*mixer_channel_calculate_peaks)(enum pcm_mixer_channel channel,
|
||||
struct pcm_peaks *peaks);
|
||||
void (*mixer_channel_play_data)(enum pcm_mixer_channel channel,
|
||||
pcm_play_callback_type get_more,
|
||||
const struct mixer_play_cbs* cbs,
|
||||
const void *start, size_t size);
|
||||
void (*mixer_channel_play_pause)(enum pcm_mixer_channel channel, bool play);
|
||||
void (*mixer_channel_stop)(enum pcm_mixer_channel channel);
|
||||
|
|
|
|||
|
|
@ -466,7 +466,10 @@ void I_SubmitSound(void)
|
|||
if (!enable_sound)
|
||||
return;
|
||||
|
||||
rb->mixer_channel_play_data(PCM_MIXER_CHAN_PLAYBACK, &get_more, NULL, 0);
|
||||
static const struct mixer_play_cbs cbs = {
|
||||
.get_more = get_more,
|
||||
};
|
||||
rb->mixer_channel_play_data(PCM_MIXER_CHAN_PLAYBACK, &cbs, NULL, 0);
|
||||
}
|
||||
|
||||
void I_ShutdownSound(void)
|
||||
|
|
|
|||
|
|
@ -507,6 +507,10 @@ UNUSED_ATTR static int find_min_sampr_ge_22(void)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static const struct mixer_play_cbs mixer_cbs = {
|
||||
.get_more = get_more,
|
||||
};
|
||||
|
||||
static int midimain(const void * filename)
|
||||
{
|
||||
int a, notes_used, vol;
|
||||
|
|
@ -625,7 +629,7 @@ static int midimain(const void * filename)
|
|||
#endif
|
||||
|
||||
rb->pcmbuf_fade(false, true);
|
||||
rb->mixer_channel_play_data(PCM_MIXER_CHAN_PLAYBACK, get_more, NULL, 0);
|
||||
rb->mixer_channel_play_data(PCM_MIXER_CHAN_PLAYBACK, &mixer_cbs, NULL, 0);
|
||||
|
||||
while (!quit)
|
||||
{
|
||||
|
|
@ -684,7 +688,7 @@ static int midimain(const void * filename)
|
|||
#endif
|
||||
midi_debug("Rewind to %d:%02d\n", playing_time/60, playing_time%60);
|
||||
if (is_playing)
|
||||
rb->mixer_channel_play_data(PCM_MIXER_CHAN_PLAYBACK, get_more, NULL, 0);
|
||||
rb->mixer_channel_play_data(PCM_MIXER_CHAN_PLAYBACK, &mixer_cbs, NULL, 0);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -706,7 +710,7 @@ static int midimain(const void * filename)
|
|||
#endif
|
||||
midi_debug("Skip to %d:%02d\n", playing_time/60, playing_time%60);
|
||||
if (is_playing)
|
||||
rb->mixer_channel_play_data(PCM_MIXER_CHAN_PLAYBACK, get_more, NULL, 0);
|
||||
rb->mixer_channel_play_data(PCM_MIXER_CHAN_PLAYBACK, &mixer_cbs, NULL, 0);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -292,6 +292,10 @@ static void get_more(const void** start, size_t* size)
|
|||
#endif
|
||||
}
|
||||
|
||||
static const struct mixer_play_cbs mixer_cbs = {
|
||||
.get_more = get_more,
|
||||
};
|
||||
|
||||
static void showinfo(void)
|
||||
{
|
||||
char statustext[LINE_LENGTH];
|
||||
|
|
@ -600,10 +604,9 @@ static void applysettings(void)
|
|||
}
|
||||
|
||||
// MikMod_Reset(""); BROKEN!
|
||||
|
||||
rb->mixer_channel_stop(PCM_MIXER_CHAN_PLAYBACK);
|
||||
rb->mixer_set_frequency(md_mixfreq);
|
||||
rb->mixer_channel_play_data(PCM_MIXER_CHAN_PLAYBACK, get_more, NULL, 0);
|
||||
rb->mixer_channel_play_data(PCM_MIXER_CHAN_PLAYBACK, &mixer_cbs, NULL, 0);
|
||||
}
|
||||
|
||||
#ifdef HAVE_ADJUSTABLE_CPU_FREQ
|
||||
|
|
@ -810,7 +813,7 @@ static int playfile(char* filename)
|
|||
display = DISPLAY_INFO;
|
||||
Player_Start(module);
|
||||
rb->pcmbuf_fade(false, true);
|
||||
rb->mixer_channel_play_data(PCM_MIXER_CHAN_PLAYBACK, get_more, NULL, 0);
|
||||
rb->mixer_channel_play_data(PCM_MIXER_CHAN_PLAYBACK, &mixer_cbs, NULL, 0);
|
||||
}
|
||||
|
||||
#ifdef HAVE_ADJUSTABLE_CPU_FREQ
|
||||
|
|
|
|||
|
|
@ -173,6 +173,10 @@ static void get_more(const void **start, size_t *size)
|
|||
pcmbuf_read = pcmbuf_written;
|
||||
}
|
||||
|
||||
static const struct mixer_play_cbs mixer_cbs = {
|
||||
.get_more = get_more,
|
||||
};
|
||||
|
||||
/** Public interface **/
|
||||
|
||||
/* Return a buffer pointer if at least size bytes are available and if so,
|
||||
|
|
@ -236,8 +240,7 @@ void pcm_output_flush(void)
|
|||
|
||||
/* Restart if playing state was current */
|
||||
if (status == CHANNEL_PLAYING)
|
||||
rb->mixer_channel_play_data(MPEG_PCM_CHANNEL,
|
||||
get_more, NULL, 0);
|
||||
rb->mixer_channel_play_data(MPEG_PCM_CHANNEL, &mixer_cbs, NULL, 0);
|
||||
}
|
||||
|
||||
/* Seek the reference clock to the specified time - next audio data ready to
|
||||
|
|
@ -318,8 +321,7 @@ void pcm_output_play_pause(bool play)
|
|||
if (play)
|
||||
{
|
||||
rb->mixer_channel_set_amplitude(MPEG_PCM_CHANNEL, MIX_AMP_UNITY);
|
||||
rb->mixer_channel_play_data(MPEG_PCM_CHANNEL,
|
||||
get_more, NULL, 0);
|
||||
rb->mixer_channel_play_data(MPEG_PCM_CHANNEL, &mixer_cbs, NULL, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -407,8 +407,11 @@ static void start_sound(void)
|
|||
|
||||
wsg3_set_sampling_rate(caps->samprs[sr_index]);
|
||||
|
||||
static const struct mixer_play_cbs cbs = {
|
||||
.get_more = get_more,
|
||||
};
|
||||
rb->mixer_set_frequency(caps->samprs[sr_index]);
|
||||
rb->mixer_channel_play_data(PCM_MIXER_CHAN_PLAYBACK, get_more, NULL, 0);
|
||||
rb->mixer_channel_play_data(PCM_MIXER_CHAN_PLAYBACK, &cbs, NULL, 0);
|
||||
|
||||
sound_playing = true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -181,7 +181,10 @@ int rockbox_send_dacs(void)
|
|||
if(!playing && outbuf_fill > 0)
|
||||
{
|
||||
/* Start playing. */
|
||||
rb->mixer_channel_play_data(PCM_MIXER_CHAN_PLAYBACK, pdbox_get_more, NULL, 0);
|
||||
static const struct mixer_play_cbs cbs = {
|
||||
.get_more = pdbox_get_more,
|
||||
};
|
||||
rb->mixer_channel_play_data(PCM_MIXER_CHAN_PLAYBACK, &cbs, NULL, 0);
|
||||
|
||||
/* Set status flag. */
|
||||
playing = true;
|
||||
|
|
|
|||
|
|
@ -73,7 +73,10 @@ int rockboy_pcm_submit(void)
|
|||
|
||||
if(newly_started)
|
||||
{
|
||||
rb->mixer_channel_play_data(PCM_MIXER_CHAN_PLAYBACK, &get_more, NULL, 0);
|
||||
static const struct mixer_play_cbs cbs = {
|
||||
.get_more = get_more,
|
||||
};
|
||||
rb->mixer_channel_play_data(PCM_MIXER_CHAN_PLAYBACK, &cbs, NULL, 0);
|
||||
newly_started = false;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -288,7 +288,10 @@ static int ROCKBOXAUD_OpenAudio(_THIS, SDL_AudioSpec *spec)
|
|||
|
||||
rbaud_underruns = 0;
|
||||
|
||||
rb->mixer_channel_play_data(PCM_MIXER_CHAN_PLAYBACK, get_more, NULL, 0);
|
||||
static const struct mixer_play_cbs cbs = {
|
||||
.get_more = get_more,
|
||||
};
|
||||
rb->mixer_channel_play_data(PCM_MIXER_CHAN_PLAYBACK, &cbs, NULL, 0);
|
||||
|
||||
/* We're ready to rock and roll. :-) */
|
||||
return(0);
|
||||
|
|
|
|||
|
|
@ -237,7 +237,10 @@ static void play_tone(bool volume_set)
|
|||
IF_PRIO(, PRIORITY_PLAYBACK)
|
||||
IF_COP(, CPU));
|
||||
|
||||
rb->mixer_channel_play_data(PCM_MIXER_CHAN_PLAYBACK, get_more, NULL, 0);
|
||||
static const struct mixer_play_cbs cbs = {
|
||||
.get_more = get_more,
|
||||
};
|
||||
rb->mixer_channel_play_data(PCM_MIXER_CHAN_PLAYBACK, &cbs, NULL, 0);
|
||||
|
||||
#ifndef HAVE_VOLUME_IN_LIST
|
||||
if (volume_set)
|
||||
|
|
|
|||
|
|
@ -222,8 +222,11 @@ void syssnd_update(void)
|
|||
|
||||
if (!isAudioPlaying && fillCount > 0)
|
||||
{
|
||||
static const struct mixer_play_cbs cbs = {
|
||||
.get_more = get_more,
|
||||
};
|
||||
isAudioPlaying = true;
|
||||
rb->mixer_channel_play_data(PCM_MIXER_CHAN_PLAYBACK, get_more, NULL, 0);
|
||||
rb->mixer_channel_play_data(PCM_MIXER_CHAN_PLAYBACK, &cbs, NULL, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1029,7 +1029,10 @@ void sys_startAudio(struct System* sys, AudioCallback callback, void *param)
|
|||
audio_param = param;
|
||||
audio_sys = sys;
|
||||
|
||||
rb->mixer_channel_play_data(PCM_MIXER_CHAN_PLAYBACK, get_more, NULL, 0);
|
||||
static const struct mixer_play_cbs cbs = {
|
||||
.get_more = get_more,
|
||||
};
|
||||
rb->mixer_channel_play_data(PCM_MIXER_CHAN_PLAYBACK, &cbs, NULL, 0);
|
||||
}
|
||||
|
||||
void sys_stopAudio(struct System* sys)
|
||||
|
|
|
|||
|
|
@ -212,7 +212,10 @@ static void write_buf(void){
|
|||
= my_buf[j+10] = my_buf[j+11] \
|
||||
= (((byte)sp_sound_buf[i])<<8) >> settings.volume;
|
||||
|
||||
rb->mixer_channel_play_data(PCM_MIXER_CHAN_PLAYBACK, get_more, (unsigned char*)(my_buf),TMNUM*4*3*2);
|
||||
static const struct mixer_play_cbs cbs = {
|
||||
.get_more = get_more,
|
||||
};
|
||||
rb->mixer_channel_play_data(PCM_MIXER_CHAN_PLAYBACK, &cbs, (unsigned char*)(my_buf),TMNUM*4*3*2);
|
||||
|
||||
#if 0
|
||||
/* can use to save and later analyze what we produce */
|
||||
|
|
|
|||
|
|
@ -245,8 +245,10 @@ static void voice_start_playback(void)
|
|||
struct voice_pcm_frame *frame =
|
||||
&voice_buf->frames[voice_buf->frame_out % VOICE_FRAMES];
|
||||
|
||||
mixer_channel_play_data(PCM_MIXER_CHAN_VOICE, voice_pcm_callback,
|
||||
frame->pcm, frame->size);
|
||||
static const struct mixer_play_cbs cbs = {
|
||||
.get_more = voice_pcm_callback,
|
||||
};
|
||||
mixer_channel_play_data(PCM_MIXER_CHAN_VOICE, &cbs, frame->pcm, frame->size);
|
||||
}
|
||||
|
||||
/* Stop the voice channel */
|
||||
|
|
|
|||
|
|
@ -1607,9 +1607,9 @@ size_t mixer_channel_get_bytes_waiting(enum pcm_mixer_channel channel)
|
|||
\return
|
||||
\description
|
||||
|
||||
void mixer_channel_play_data(enum pcm_mixer_channel channel, pcm_play_callback_type get_more, const void *start, size_t size)
|
||||
void mixer_channel_play_data(enum pcm_mixer_channel channel, const struct mixer_play_cbs* cbs, const void *start, size_t size)
|
||||
\param channel
|
||||
\param get_more
|
||||
\param cbs
|
||||
\param start
|
||||
\param size
|
||||
\description
|
||||
|
|
|
|||
|
|
@ -96,8 +96,13 @@ enum channel_status
|
|||
/** Public interfaces **/
|
||||
|
||||
/* Start playback on a channel */
|
||||
struct mixer_play_cbs {
|
||||
void (*get_more)(const void **start, size_t *size);
|
||||
void (*sampr_changed)(uint32_t sampr);
|
||||
};
|
||||
|
||||
void mixer_channel_play_data(enum pcm_mixer_channel channel,
|
||||
pcm_play_callback_type get_more,
|
||||
const struct mixer_play_cbs* cbs,
|
||||
const void *start, size_t size);
|
||||
|
||||
/* Pause or resume a channel (when started) */
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ struct mixer_channel
|
|||
const void *start; /* Buffer pointer */
|
||||
size_t size; /* Bytes remaining */
|
||||
size_t last_size; /* Size of consumed data in prev. cycle */
|
||||
pcm_play_callback_type get_more; /* Registered callback */
|
||||
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 */
|
||||
|
|
@ -154,9 +154,9 @@ fill_frame:
|
|||
|
||||
if (chan->size == 0)
|
||||
{
|
||||
if (chan->get_more)
|
||||
if (chan->cbs->get_more)
|
||||
{
|
||||
chan->get_more(&chan->start, &chan->size);
|
||||
chan->cbs->get_more(&chan->start, &chan->size);
|
||||
ALIGN_AUDIOBUF(chan->start, chan->size);
|
||||
}
|
||||
|
||||
|
|
@ -287,14 +287,14 @@ static void mixer_start_pcm(void)
|
|||
|
||||
/* Start playback on a channel */
|
||||
void mixer_channel_play_data(enum pcm_mixer_channel channel,
|
||||
pcm_play_callback_type get_more,
|
||||
const struct mixer_play_cbs* cbs,
|
||||
const void *start, size_t size)
|
||||
{
|
||||
struct mixer_channel *chan = &channels[channel];
|
||||
|
||||
ALIGN_AUDIOBUF(start, size);
|
||||
|
||||
if (!(start && size) && get_more)
|
||||
if (!(start && size) && cbs && cbs->get_more)
|
||||
{
|
||||
/* Initial buffer not passed - call the callback now */
|
||||
pcm_play_lock();
|
||||
|
|
@ -304,7 +304,7 @@ void mixer_channel_play_data(enum pcm_mixer_channel channel,
|
|||
pcm_play_unlock(); /* Allow playback while doing callback */
|
||||
|
||||
size = 0;
|
||||
get_more(&start, &size);
|
||||
cbs->get_more(&start, &size);
|
||||
ALIGN_AUDIOBUF(start, 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->get_more = get_more;
|
||||
chan->cbs = cbs;
|
||||
|
||||
mixer_activate_channel(chan);
|
||||
chan_call_buffer_hook(chan);
|
||||
|
|
@ -464,11 +464,36 @@ void mixer_set_frequency(unsigned int samplerate)
|
|||
|
||||
if (samplerate == mixer_sampr)
|
||||
return;
|
||||
|
||||
/* All data is now invalid */
|
||||
mixer_reset();
|
||||
mixer_sampr = samplerate;
|
||||
|
||||
for (size_t i = 0; i < ARRAYLEN(active_channels) && active_channels[i]; i += 1)
|
||||
{
|
||||
struct mixer_channel* chan = active_channels[i];
|
||||
|
||||
/* Notify upstreams */
|
||||
if (chan->cbs)
|
||||
{
|
||||
if (chan->cbs->sampr_changed)
|
||||
{
|
||||
chan->cbs->sampr_changed(samplerate);
|
||||
}
|
||||
if (chan->cbs->get_more)
|
||||
{
|
||||
/* Remake buffer */
|
||||
const void *start = NULL;
|
||||
size_t size;
|
||||
chan->cbs->get_more(&start, &size);
|
||||
if (start && size) {
|
||||
chan->start = start;
|
||||
chan->size = size;
|
||||
chan->last_size = 0;
|
||||
} else {
|
||||
channel_stopped(chan);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Work out how much space we really need */
|
||||
if (samplerate > SAMPR_96)
|
||||
mix_frame_size = 4;
|
||||
|
|
|
|||
|
|
@ -1337,7 +1337,10 @@ bool usb_audio_fast_transfer_complete(int ep, int dir, int status, int length)
|
|||
logf("usbaudio: prebuffering done");
|
||||
playback_audio_underflow = false;
|
||||
usb_rx_overflow = false;
|
||||
mixer_channel_play_data(PCM_MIXER_CHAN_USBAUDIO, playback_audio_get_more, NULL, 0);
|
||||
static const struct mixer_play_cbs cbs = {
|
||||
.get_more = playback_audio_get_more,
|
||||
};
|
||||
mixer_channel_play_data(PCM_MIXER_CHAN_USBAUDIO, &cbs, NULL, 0);
|
||||
}
|
||||
restore_irq(oldlevel);
|
||||
retval = true;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue