mirror of
https://github.com/Rockbox/rockbox.git
synced 2026-05-12 11:43:16 -04:00
Compare commits
5 commits
86639acc5e
...
4dbcb13f58
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4dbcb13f58 | ||
|
|
cfb01cfd58 | ||
|
|
498a9fffeb | ||
|
|
e2040cc98c | ||
|
|
cb04b8167c |
25 changed files with 199 additions and 120 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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@
|
|||
#include "kernel.h"
|
||||
#include "codecs.h"
|
||||
#include "codec_thread.h"
|
||||
#include "pcm_mixer.h"
|
||||
#include "pcmbuf.h"
|
||||
#include "audio_thread.h"
|
||||
#include "playback.h"
|
||||
|
|
@ -518,7 +519,7 @@ static void run_codec(void)
|
|||
codec_queue_ack(Q_CODEC_RUN);
|
||||
|
||||
trigger_cpu_boost();
|
||||
dsp_configure(ci.dsp, DSP_SET_OUT_FREQUENCY, pcmbuf_get_frequency());
|
||||
dsp_configure(ci.dsp, DSP_SET_OUT_FREQUENCY, mixer_get_frequency());
|
||||
|
||||
if (!encoder)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -5902,7 +5902,7 @@
|
|||
</dest>
|
||||
<voice>
|
||||
*: none
|
||||
hibylinux: "~U S B"
|
||||
hibylinux: "Ю Ес Би"
|
||||
multivolume: "~H D 1"
|
||||
sansac200*,sansaclipplus,sansae200*,sansafuze*: "микро S D"
|
||||
xduoox3: "микро S D 2"
|
||||
|
|
@ -7004,7 +7004,7 @@
|
|||
</dest>
|
||||
<voice>
|
||||
*: none
|
||||
usb_charging_enable: "Зареждане по време на USB връзка"
|
||||
usb_charging_enable: "Зареждане по време на Ю Ес Би връзка"
|
||||
</voice>
|
||||
</phrase>
|
||||
<phrase>
|
||||
|
|
@ -10103,7 +10103,7 @@
|
|||
</dest>
|
||||
<voice>
|
||||
*: none
|
||||
usb_hid: "Режим USB клавиатура"
|
||||
usb_hid: "Режим Ю Ес Би клавиатура"
|
||||
</voice>
|
||||
</phrase>
|
||||
<phrase>
|
||||
|
|
@ -10490,11 +10490,11 @@
|
|||
</source>
|
||||
<dest>
|
||||
*: none
|
||||
usb_hid: "USB УЧИ"
|
||||
usb_hid: "USB у-во за човешки интерфейс"
|
||||
</dest>
|
||||
<voice>
|
||||
*: none
|
||||
usb_hid: "USB устройство за човешки интерфейс"
|
||||
usb_hid: "Ю Ес Би устройство за човешки интерфейс"
|
||||
</voice>
|
||||
</phrase>
|
||||
<phrase>
|
||||
|
|
@ -11230,7 +11230,7 @@
|
|||
</dest>
|
||||
<voice>
|
||||
*: none
|
||||
multidrive_usb: "USB скриване на вътрешната памет"
|
||||
multidrive_usb: "Ю Ес Би скриване на вътрешната памет"
|
||||
</voice>
|
||||
</phrase>
|
||||
<phrase>
|
||||
|
|
@ -15080,7 +15080,7 @@
|
|||
*: "Влез в режим USB памет?"
|
||||
</dest>
|
||||
<voice>
|
||||
*: "Влез в режим USB памет?"
|
||||
*: "Влез в режим Ю Ес Би памет?"
|
||||
</voice>
|
||||
</phrase>
|
||||
<phrase>
|
||||
|
|
@ -16873,11 +16873,11 @@
|
|||
</source>
|
||||
<dest>
|
||||
*: none
|
||||
usbdac: "USB-ЦАП"
|
||||
usbdac: "USB ЦАП"
|
||||
</dest>
|
||||
<voice>
|
||||
*: none
|
||||
usbdac: "USB ЦАП"
|
||||
usbdac: "Ю Ес Би цифрово-аналогов преобразувател"
|
||||
</voice>
|
||||
</phrase>
|
||||
<phrase>
|
||||
|
|
@ -16894,7 +16894,7 @@
|
|||
</dest>
|
||||
<voice>
|
||||
*: none
|
||||
usbdac: "В режим USB само зареждане"
|
||||
usbdac: "В режим Ю Ес Би само зареждане"
|
||||
</voice>
|
||||
</phrase>
|
||||
<phrase>
|
||||
|
|
@ -16911,7 +16911,7 @@
|
|||
</dest>
|
||||
<voice>
|
||||
*: none
|
||||
usbdac: "В режим USB памет"
|
||||
usbdac: "В режим Ю Ес Би памет"
|
||||
</voice>
|
||||
</phrase>
|
||||
<phrase>
|
||||
|
|
@ -16924,11 +16924,11 @@
|
|||
</source>
|
||||
<dest>
|
||||
*: none
|
||||
usbdac: "USB-ЦАП е активен"
|
||||
usbdac: "USB ЦАП е активен"
|
||||
</dest>
|
||||
<voice>
|
||||
*: none
|
||||
usbdac: "USB ЦАП е активен"
|
||||
usbdac: "Ю Ес Би цифрово-аналогов преобразувател е активен"
|
||||
</voice>
|
||||
</phrase>
|
||||
<phrase>
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
@ -68,17 +69,20 @@
|
|||
chunks */
|
||||
|
||||
/* Return data level in 1/4-second increments */
|
||||
#define DATA_LEVEL(quarter_secs) (pcmbuf_sampr * (quarter_secs))
|
||||
static inline unsigned int data_level(int quarter_secs)
|
||||
{
|
||||
return mixer_get_frequency() * quarter_secs;
|
||||
}
|
||||
|
||||
/* Number of bytes played per second */
|
||||
#define BYTERATE (pcmbuf_sampr * PCMBUF_SAMPLE_SIZE)
|
||||
#define BYTERATE (mixer_get_frequency() * PCMBUF_SAMPLE_SIZE)
|
||||
|
||||
#if MEMORYSIZE > 2
|
||||
/* Keep watermark high for large memory target - at least (2s) */
|
||||
#define PCMBUF_WATERMARK (BYTERATE * 2)
|
||||
#define MIN_BUFFER_SIZE (BYTERATE * 3)
|
||||
/* 1 seconds of buffer is low data */
|
||||
#define LOW_DATA DATA_LEVEL(4)
|
||||
#define LOW_DATA data_level(4)
|
||||
#else
|
||||
#define PCMBUF_WATERMARK (BYTERATE / 4) /* 0.25 seconds */
|
||||
#define MIN_BUFFER_SIZE (BYTERATE * 1)
|
||||
|
|
@ -108,7 +112,6 @@ static size_t pcmbuf_size;
|
|||
static struct chunkdesc *pcmbuf_descriptors;
|
||||
static unsigned int pcmbuf_desc_count;
|
||||
static unsigned int position_key = 1;
|
||||
static unsigned int pcmbuf_sampr = 0;
|
||||
|
||||
static size_t chunk_ridx;
|
||||
static size_t chunk_widx;
|
||||
|
|
@ -481,7 +484,7 @@ void * pcmbuf_request_buffer(int *count)
|
|||
if (low_latency_mode)
|
||||
{
|
||||
/* 1/4s latency. */
|
||||
if (remaining > DATA_LEVEL(1))
|
||||
if (remaining > data_level(1))
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
@ -723,7 +726,7 @@ void pcmbuf_start_track_change(enum pcm_track_change_type type)
|
|||
else if (crossfade_setting != CROSSFADE_ENABLE_OFF)
|
||||
{
|
||||
if (crossfade_status == CROSSFADE_INACTIVE &&
|
||||
pcmbuf_unplayed_bytes() >= DATA_LEVEL(2) &&
|
||||
pcmbuf_unplayed_bytes() >= data_level(2) &&
|
||||
!low_latency_mode)
|
||||
{
|
||||
switch (crossfade_setting)
|
||||
|
|
@ -836,6 +839,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 +854,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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1141,7 +1153,7 @@ static void crossfade_start(void)
|
|||
size_t unplayed = pcmbuf_unplayed_bytes();
|
||||
|
||||
/* Reject crossfade if less than .5s of data */
|
||||
if (unplayed < DATA_LEVEL(2))
|
||||
if (unplayed < data_level(2))
|
||||
{
|
||||
logf("crossfade rejected");
|
||||
crossfade_cancel();
|
||||
|
|
@ -1437,13 +1449,3 @@ void pcmbuf_set_low_latency(bool state)
|
|||
{
|
||||
low_latency_mode = state;
|
||||
}
|
||||
|
||||
void pcmbuf_update_frequency(void)
|
||||
{
|
||||
pcmbuf_sampr = mixer_get_frequency();
|
||||
}
|
||||
|
||||
unsigned int pcmbuf_get_frequency(void)
|
||||
{
|
||||
return pcmbuf_sampr;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -80,7 +80,5 @@ void pcmbuf_sync_position_update(void);
|
|||
/* Misc */
|
||||
bool pcmbuf_is_lowdata(void);
|
||||
void pcmbuf_set_low_latency(bool state);
|
||||
void pcmbuf_update_frequency(void);
|
||||
unsigned int pcmbuf_get_frequency(void);
|
||||
|
||||
#endif /* PCMBUF_H */
|
||||
|
|
|
|||
|
|
@ -3036,7 +3036,6 @@ static void audio_start_playback(const struct audio_resume_info *resume_info,
|
|||
skip_resume_adjustments = id3_get(PLAYING_ID3)->skip_resume_adjustments;
|
||||
|
||||
track_list_clear(TRACK_LIST_CLEAR_ALL);
|
||||
pcmbuf_update_frequency();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -3049,7 +3048,6 @@ static void audio_start_playback(const struct audio_resume_info *resume_info,
|
|||
pcmbuf_start_track_change(TRACK_CHANGE_MANUAL);
|
||||
wipe_track_metadata(true);
|
||||
}
|
||||
pcmbuf_update_frequency();
|
||||
|
||||
/* Set after track finish event in case skip was in progress */
|
||||
skip_pending = TRACK_SKIP_NONE;
|
||||
|
|
@ -3071,7 +3069,6 @@ static void audio_start_playback(const struct audio_resume_info *resume_info,
|
|||
#ifndef PLATFORM_HAS_VOLUME_CHANGE
|
||||
sound_set_volume(global_status.volume);
|
||||
#endif
|
||||
pcmbuf_update_frequency();
|
||||
|
||||
/* Be sure channel is audible */
|
||||
pcmbuf_fade(false, true);
|
||||
|
|
@ -4315,7 +4312,6 @@ void INIT_ATTR playback_init(void)
|
|||
mutex_init(&id3_mutex);
|
||||
track_list_init();
|
||||
buffering_init();
|
||||
pcmbuf_update_frequency();
|
||||
#ifdef HAVE_CROSSFADE
|
||||
/* Set crossfade setting for next buffer init which should be about... */
|
||||
pcmbuf_request_crossfade_enable(global_settings.crossfade);
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
||||
|
|
@ -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);
|
||||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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) */
|
||||
|
|
@ -128,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);
|
||||
|
|
|
|||
|
|
@ -33,7 +33,6 @@
|
|||
before the last samples are sent to the codec and so things are done in
|
||||
parallel (as much as possible) with sending-out data. */
|
||||
|
||||
static unsigned int mixer_sampr = -1U;
|
||||
static unsigned int mix_frame_size = MIX_FRAME_SAMPLES*4;
|
||||
|
||||
/* Define this to nonzero to add a marker pulse at each frame start */
|
||||
|
|
@ -45,10 +44,10 @@ 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* play_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 struct mixer_buffer_cbs* buf_cbs; /* Callback for new buffer */
|
||||
};
|
||||
|
||||
#if (defined(HW_HAVE_192) || defined(HW_HAVE_176))
|
||||
|
|
@ -75,9 +74,19 @@ static struct mixer_channel channels[PCM_MIXER_NUM_CHANNELS] IBSS_ATTR;
|
|||
static struct mixer_channel * active_channels[PCM_MIXER_NUM_CHANNELS+1] IBSS_ATTR;
|
||||
|
||||
/* Number of silence frames to play after all data has played */
|
||||
#define MAX_IDLE_FRAMES (mixer_sampr*3 / (mix_frame_size / 4))
|
||||
static unsigned int idle_counter = 0;
|
||||
|
||||
#ifdef CONFIG_SAMPR_TYPES
|
||||
#define SAMPR_NUM(sampr) (sampr & ~SAMPR_TYPE_MASK)
|
||||
#else
|
||||
#define SAMPR_NUM(sampr) (sampr)
|
||||
#endif
|
||||
|
||||
static inline unsigned int max_idle_frames(void)
|
||||
{
|
||||
return SAMPR_NUM(pcm_get_frequency()) * 3 / (mix_frame_size / 4);
|
||||
}
|
||||
|
||||
/** Mixing routines, CPU optmized **/
|
||||
#include "asm/pcm-mixer.c"
|
||||
|
||||
|
|
@ -119,8 +128,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 +163,9 @@ fill_frame:
|
|||
|
||||
if (chan->size == 0)
|
||||
{
|
||||
if (chan->get_more)
|
||||
if (chan->play_cbs->get_more)
|
||||
{
|
||||
chan->get_more(&chan->start, &chan->size);
|
||||
chan->play_cbs->get_more(&chan->start, &chan->size);
|
||||
ALIGN_AUDIOBUF(chan->start, chan->size);
|
||||
}
|
||||
|
||||
|
|
@ -233,7 +242,7 @@ fill_frame:
|
|||
goto fill_frame;
|
||||
}
|
||||
}
|
||||
else if (idle_counter++ < MAX_IDLE_FRAMES)
|
||||
else if (idle_counter++ < max_idle_frames())
|
||||
{
|
||||
/* Pad incomplete frames with silence */
|
||||
if (idle_counter <= 3)
|
||||
|
|
@ -265,12 +274,6 @@ static void mixer_start_pcm(void)
|
|||
return;
|
||||
#endif
|
||||
|
||||
/* Requires a shared global sample rate for all channels */
|
||||
if (mixer_sampr == -1U)
|
||||
mixer_sampr = pcm_get_frequency();
|
||||
else
|
||||
pcm_set_frequency(mixer_sampr);
|
||||
|
||||
/* Prepare initial frames and set up the double buffer */
|
||||
mixer_buffer_callback(PCM_DMAST_STARTED);
|
||||
|
||||
|
|
@ -287,14 +290,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 +307,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 +320,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->play_cbs = cbs;
|
||||
|
||||
mixer_activate_channel(chan);
|
||||
chan_call_buffer_hook(chan);
|
||||
|
|
@ -429,15 +432,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();
|
||||
}
|
||||
|
||||
|
|
@ -455,24 +457,51 @@ void mixer_reset(void)
|
|||
/* Set output samplerate */
|
||||
void mixer_set_frequency(unsigned int samplerate)
|
||||
{
|
||||
pcm_set_frequency(samplerate);
|
||||
samplerate = pcm_get_frequency();
|
||||
|
||||
#ifdef CONFIG_SAMPR_TYPES
|
||||
samplerate &= ~SAMPR_TYPE_MASK;
|
||||
#endif
|
||||
|
||||
if (samplerate == mixer_sampr)
|
||||
if(pcm_get_frequency() == samplerate)
|
||||
return;
|
||||
|
||||
/* All data is now invalid */
|
||||
mixer_reset();
|
||||
mixer_sampr = samplerate;
|
||||
pcm_set_frequency(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->play_cbs)
|
||||
{
|
||||
if (chan->play_cbs->sampr_changed)
|
||||
{
|
||||
chan->play_cbs->sampr_changed(SAMPR_NUM(samplerate));
|
||||
}
|
||||
if (chan->play_cbs->get_more)
|
||||
{
|
||||
/* Remake buffer */
|
||||
const void *start = NULL;
|
||||
size_t size;
|
||||
chan->play_cbs->get_more(&start, &size);
|
||||
if (start && size) {
|
||||
chan->start = start;
|
||||
chan->size = size;
|
||||
chan->last_size = 0;
|
||||
} else {
|
||||
channel_stopped(chan);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Notify buffer monitor */
|
||||
if (chan->buf_cbs)
|
||||
{
|
||||
if (chan->buf_cbs->sampr_changed)
|
||||
{
|
||||
chan->buf_cbs->sampr_changed(SAMPR_NUM(samplerate));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Work out how much space we really need */
|
||||
if (samplerate > SAMPR_96)
|
||||
if (SAMPR_NUM(samplerate) > SAMPR_96)
|
||||
mix_frame_size = 4;
|
||||
else if (samplerate > SAMPR_48)
|
||||
else if (SAMPR_NUM(samplerate) > SAMPR_48)
|
||||
mix_frame_size = 2;
|
||||
else
|
||||
mix_frame_size = 1;
|
||||
|
|
@ -486,5 +515,5 @@ void mixer_set_frequency(unsigned int samplerate)
|
|||
/* Get output samplerate */
|
||||
unsigned int mixer_get_frequency(void)
|
||||
{
|
||||
return mixer_sampr;
|
||||
return pcm_get_frequency();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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