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);
|
beep_get_more(&start, &size);
|
||||||
|
|
||||||
mixer_channel_set_amplitude(PCM_MIXER_CHAN_BEEP, MIX_AMP_UNITY);
|
mixer_channel_set_amplitude(PCM_MIXER_CHAN_BEEP, MIX_AMP_UNITY);
|
||||||
mixer_channel_play_data(PCM_MIXER_CHAN_BEEP,
|
static struct mixer_play_cbs cbs;
|
||||||
beep_count ? beep_get_more : NULL,
|
cbs.get_more = beep_count ? beep_get_more : NULL;
|
||||||
start, size);
|
mixer_channel_play_data(PCM_MIXER_CHAN_BEEP, &cbs, start, size);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,7 @@
|
||||||
#include "kernel.h"
|
#include "kernel.h"
|
||||||
#include "codecs.h"
|
#include "codecs.h"
|
||||||
#include "codec_thread.h"
|
#include "codec_thread.h"
|
||||||
|
#include "pcm_mixer.h"
|
||||||
#include "pcmbuf.h"
|
#include "pcmbuf.h"
|
||||||
#include "audio_thread.h"
|
#include "audio_thread.h"
|
||||||
#include "playback.h"
|
#include "playback.h"
|
||||||
|
|
@ -518,7 +519,7 @@ static void run_codec(void)
|
||||||
codec_queue_ack(Q_CODEC_RUN);
|
codec_queue_ack(Q_CODEC_RUN);
|
||||||
|
|
||||||
trigger_cpu_boost();
|
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)
|
if (!encoder)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -5902,7 +5902,7 @@
|
||||||
</dest>
|
</dest>
|
||||||
<voice>
|
<voice>
|
||||||
*: none
|
*: none
|
||||||
hibylinux: "~U S B"
|
hibylinux: "Ю Ес Би"
|
||||||
multivolume: "~H D 1"
|
multivolume: "~H D 1"
|
||||||
sansac200*,sansaclipplus,sansae200*,sansafuze*: "микро S D"
|
sansac200*,sansaclipplus,sansae200*,sansafuze*: "микро S D"
|
||||||
xduoox3: "микро S D 2"
|
xduoox3: "микро S D 2"
|
||||||
|
|
@ -7004,7 +7004,7 @@
|
||||||
</dest>
|
</dest>
|
||||||
<voice>
|
<voice>
|
||||||
*: none
|
*: none
|
||||||
usb_charging_enable: "Зареждане по време на USB връзка"
|
usb_charging_enable: "Зареждане по време на Ю Ес Би връзка"
|
||||||
</voice>
|
</voice>
|
||||||
</phrase>
|
</phrase>
|
||||||
<phrase>
|
<phrase>
|
||||||
|
|
@ -10103,7 +10103,7 @@
|
||||||
</dest>
|
</dest>
|
||||||
<voice>
|
<voice>
|
||||||
*: none
|
*: none
|
||||||
usb_hid: "Режим USB клавиатура"
|
usb_hid: "Режим Ю Ес Би клавиатура"
|
||||||
</voice>
|
</voice>
|
||||||
</phrase>
|
</phrase>
|
||||||
<phrase>
|
<phrase>
|
||||||
|
|
@ -10490,11 +10490,11 @@
|
||||||
</source>
|
</source>
|
||||||
<dest>
|
<dest>
|
||||||
*: none
|
*: none
|
||||||
usb_hid: "USB УЧИ"
|
usb_hid: "USB у-во за човешки интерфейс"
|
||||||
</dest>
|
</dest>
|
||||||
<voice>
|
<voice>
|
||||||
*: none
|
*: none
|
||||||
usb_hid: "USB устройство за човешки интерфейс"
|
usb_hid: "Ю Ес Би устройство за човешки интерфейс"
|
||||||
</voice>
|
</voice>
|
||||||
</phrase>
|
</phrase>
|
||||||
<phrase>
|
<phrase>
|
||||||
|
|
@ -11230,7 +11230,7 @@
|
||||||
</dest>
|
</dest>
|
||||||
<voice>
|
<voice>
|
||||||
*: none
|
*: none
|
||||||
multidrive_usb: "USB скриване на вътрешната памет"
|
multidrive_usb: "Ю Ес Би скриване на вътрешната памет"
|
||||||
</voice>
|
</voice>
|
||||||
</phrase>
|
</phrase>
|
||||||
<phrase>
|
<phrase>
|
||||||
|
|
@ -15080,7 +15080,7 @@
|
||||||
*: "Влез в режим USB памет?"
|
*: "Влез в режим USB памет?"
|
||||||
</dest>
|
</dest>
|
||||||
<voice>
|
<voice>
|
||||||
*: "Влез в режим USB памет?"
|
*: "Влез в режим Ю Ес Би памет?"
|
||||||
</voice>
|
</voice>
|
||||||
</phrase>
|
</phrase>
|
||||||
<phrase>
|
<phrase>
|
||||||
|
|
@ -16873,11 +16873,11 @@
|
||||||
</source>
|
</source>
|
||||||
<dest>
|
<dest>
|
||||||
*: none
|
*: none
|
||||||
usbdac: "USB-ЦАП"
|
usbdac: "USB ЦАП"
|
||||||
</dest>
|
</dest>
|
||||||
<voice>
|
<voice>
|
||||||
*: none
|
*: none
|
||||||
usbdac: "USB ЦАП"
|
usbdac: "Ю Ес Би цифрово-аналогов преобразувател"
|
||||||
</voice>
|
</voice>
|
||||||
</phrase>
|
</phrase>
|
||||||
<phrase>
|
<phrase>
|
||||||
|
|
@ -16894,7 +16894,7 @@
|
||||||
</dest>
|
</dest>
|
||||||
<voice>
|
<voice>
|
||||||
*: none
|
*: none
|
||||||
usbdac: "В режим USB само зареждане"
|
usbdac: "В режим Ю Ес Би само зареждане"
|
||||||
</voice>
|
</voice>
|
||||||
</phrase>
|
</phrase>
|
||||||
<phrase>
|
<phrase>
|
||||||
|
|
@ -16911,7 +16911,7 @@
|
||||||
</dest>
|
</dest>
|
||||||
<voice>
|
<voice>
|
||||||
*: none
|
*: none
|
||||||
usbdac: "В режим USB памет"
|
usbdac: "В режим Ю Ес Би памет"
|
||||||
</voice>
|
</voice>
|
||||||
</phrase>
|
</phrase>
|
||||||
<phrase>
|
<phrase>
|
||||||
|
|
@ -16924,11 +16924,11 @@
|
||||||
</source>
|
</source>
|
||||||
<dest>
|
<dest>
|
||||||
*: none
|
*: none
|
||||||
usbdac: "USB-ЦАП е активен"
|
usbdac: "USB ЦАП е активен"
|
||||||
</dest>
|
</dest>
|
||||||
<voice>
|
<voice>
|
||||||
*: none
|
*: none
|
||||||
usbdac: "USB ЦАП е активен"
|
usbdac: "Ю Ес Би цифрово-аналогов преобразувател е активен"
|
||||||
</voice>
|
</voice>
|
||||||
</phrase>
|
</phrase>
|
||||||
<phrase>
|
<phrase>
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,7 @@
|
||||||
#include "pcmbuf.h"
|
#include "pcmbuf.h"
|
||||||
#include "dsp-util.h"
|
#include "dsp-util.h"
|
||||||
#include "playback.h"
|
#include "playback.h"
|
||||||
|
#include "dsp_core.h"
|
||||||
#include "codec_thread.h"
|
#include "codec_thread.h"
|
||||||
|
|
||||||
/* Define LOGF_ENABLE to enable logf output in this file */
|
/* Define LOGF_ENABLE to enable logf output in this file */
|
||||||
|
|
@ -68,17 +69,20 @@
|
||||||
chunks */
|
chunks */
|
||||||
|
|
||||||
/* Return data level in 1/4-second increments */
|
/* 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 */
|
/* Number of bytes played per second */
|
||||||
#define BYTERATE (pcmbuf_sampr * PCMBUF_SAMPLE_SIZE)
|
#define BYTERATE (mixer_get_frequency() * PCMBUF_SAMPLE_SIZE)
|
||||||
|
|
||||||
#if MEMORYSIZE > 2
|
#if MEMORYSIZE > 2
|
||||||
/* Keep watermark high for large memory target - at least (2s) */
|
/* Keep watermark high for large memory target - at least (2s) */
|
||||||
#define PCMBUF_WATERMARK (BYTERATE * 2)
|
#define PCMBUF_WATERMARK (BYTERATE * 2)
|
||||||
#define MIN_BUFFER_SIZE (BYTERATE * 3)
|
#define MIN_BUFFER_SIZE (BYTERATE * 3)
|
||||||
/* 1 seconds of buffer is low data */
|
/* 1 seconds of buffer is low data */
|
||||||
#define LOW_DATA DATA_LEVEL(4)
|
#define LOW_DATA data_level(4)
|
||||||
#else
|
#else
|
||||||
#define PCMBUF_WATERMARK (BYTERATE / 4) /* 0.25 seconds */
|
#define PCMBUF_WATERMARK (BYTERATE / 4) /* 0.25 seconds */
|
||||||
#define MIN_BUFFER_SIZE (BYTERATE * 1)
|
#define MIN_BUFFER_SIZE (BYTERATE * 1)
|
||||||
|
|
@ -108,7 +112,6 @@ static size_t pcmbuf_size;
|
||||||
static struct chunkdesc *pcmbuf_descriptors;
|
static struct chunkdesc *pcmbuf_descriptors;
|
||||||
static unsigned int pcmbuf_desc_count;
|
static unsigned int pcmbuf_desc_count;
|
||||||
static unsigned int position_key = 1;
|
static unsigned int position_key = 1;
|
||||||
static unsigned int pcmbuf_sampr = 0;
|
|
||||||
|
|
||||||
static size_t chunk_ridx;
|
static size_t chunk_ridx;
|
||||||
static size_t chunk_widx;
|
static size_t chunk_widx;
|
||||||
|
|
@ -481,7 +484,7 @@ void * pcmbuf_request_buffer(int *count)
|
||||||
if (low_latency_mode)
|
if (low_latency_mode)
|
||||||
{
|
{
|
||||||
/* 1/4s latency. */
|
/* 1/4s latency. */
|
||||||
if (remaining > DATA_LEVEL(1))
|
if (remaining > data_level(1))
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -723,7 +726,7 @@ void pcmbuf_start_track_change(enum pcm_track_change_type type)
|
||||||
else if (crossfade_setting != CROSSFADE_ENABLE_OFF)
|
else if (crossfade_setting != CROSSFADE_ENABLE_OFF)
|
||||||
{
|
{
|
||||||
if (crossfade_status == CROSSFADE_INACTIVE &&
|
if (crossfade_status == CROSSFADE_INACTIVE &&
|
||||||
pcmbuf_unplayed_bytes() >= DATA_LEVEL(2) &&
|
pcmbuf_unplayed_bytes() >= data_level(2) &&
|
||||||
!low_latency_mode)
|
!low_latency_mode)
|
||||||
{
|
{
|
||||||
switch (crossfade_setting)
|
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 */
|
/* Force playback */
|
||||||
void pcmbuf_play_start(void)
|
void pcmbuf_play_start(void)
|
||||||
{
|
{
|
||||||
|
|
@ -845,8 +854,11 @@ void pcmbuf_play_start(void)
|
||||||
chunk_widx != chunk_ridx)
|
chunk_widx != chunk_ridx)
|
||||||
{
|
{
|
||||||
current_desc = NULL;
|
current_desc = NULL;
|
||||||
mixer_channel_play_data(PCM_MIXER_CHAN_PLAYBACK, pcmbuf_pcm_callback,
|
static const struct mixer_play_cbs cbs = {
|
||||||
NULL, 0);
|
.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();
|
size_t unplayed = pcmbuf_unplayed_bytes();
|
||||||
|
|
||||||
/* Reject crossfade if less than .5s of data */
|
/* Reject crossfade if less than .5s of data */
|
||||||
if (unplayed < DATA_LEVEL(2))
|
if (unplayed < data_level(2))
|
||||||
{
|
{
|
||||||
logf("crossfade rejected");
|
logf("crossfade rejected");
|
||||||
crossfade_cancel();
|
crossfade_cancel();
|
||||||
|
|
@ -1437,13 +1449,3 @@ void pcmbuf_set_low_latency(bool state)
|
||||||
{
|
{
|
||||||
low_latency_mode = 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 */
|
/* Misc */
|
||||||
bool pcmbuf_is_lowdata(void);
|
bool pcmbuf_is_lowdata(void);
|
||||||
void pcmbuf_set_low_latency(bool state);
|
void pcmbuf_set_low_latency(bool state);
|
||||||
void pcmbuf_update_frequency(void);
|
|
||||||
unsigned int pcmbuf_get_frequency(void);
|
|
||||||
|
|
||||||
#endif /* PCMBUF_H */
|
#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;
|
skip_resume_adjustments = id3_get(PLAYING_ID3)->skip_resume_adjustments;
|
||||||
|
|
||||||
track_list_clear(TRACK_LIST_CLEAR_ALL);
|
track_list_clear(TRACK_LIST_CLEAR_ALL);
|
||||||
pcmbuf_update_frequency();
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -3049,7 +3048,6 @@ static void audio_start_playback(const struct audio_resume_info *resume_info,
|
||||||
pcmbuf_start_track_change(TRACK_CHANGE_MANUAL);
|
pcmbuf_start_track_change(TRACK_CHANGE_MANUAL);
|
||||||
wipe_track_metadata(true);
|
wipe_track_metadata(true);
|
||||||
}
|
}
|
||||||
pcmbuf_update_frequency();
|
|
||||||
|
|
||||||
/* Set after track finish event in case skip was in progress */
|
/* Set after track finish event in case skip was in progress */
|
||||||
skip_pending = TRACK_SKIP_NONE;
|
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
|
#ifndef PLATFORM_HAS_VOLUME_CHANGE
|
||||||
sound_set_volume(global_status.volume);
|
sound_set_volume(global_status.volume);
|
||||||
#endif
|
#endif
|
||||||
pcmbuf_update_frequency();
|
|
||||||
|
|
||||||
/* Be sure channel is audible */
|
/* Be sure channel is audible */
|
||||||
pcmbuf_fade(false, true);
|
pcmbuf_fade(false, true);
|
||||||
|
|
@ -4315,7 +4312,6 @@ void INIT_ATTR playback_init(void)
|
||||||
mutex_init(&id3_mutex);
|
mutex_init(&id3_mutex);
|
||||||
track_list_init();
|
track_list_init();
|
||||||
buffering_init();
|
buffering_init();
|
||||||
pcmbuf_update_frequency();
|
|
||||||
#ifdef HAVE_CROSSFADE
|
#ifdef HAVE_CROSSFADE
|
||||||
/* Set crossfade setting for next buffer init which should be about... */
|
/* Set crossfade setting for next buffer init which should be about... */
|
||||||
pcmbuf_request_crossfade_enable(global_settings.crossfade);
|
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
|
* 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 */
|
||||||
|
|
||||||
|
|
@ -782,7 +782,7 @@ struct plugin_api {
|
||||||
void (*mixer_channel_calculate_peaks)(enum pcm_mixer_channel channel,
|
void (*mixer_channel_calculate_peaks)(enum pcm_mixer_channel channel,
|
||||||
struct pcm_peaks *peaks);
|
struct pcm_peaks *peaks);
|
||||||
void (*mixer_channel_play_data)(enum pcm_mixer_channel 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);
|
const void *start, size_t size);
|
||||||
void (*mixer_channel_play_pause)(enum pcm_mixer_channel channel, bool play);
|
void (*mixer_channel_play_pause)(enum pcm_mixer_channel channel, bool play);
|
||||||
void (*mixer_channel_stop)(enum pcm_mixer_channel channel);
|
void (*mixer_channel_stop)(enum pcm_mixer_channel channel);
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -466,7 +466,10 @@ void I_SubmitSound(void)
|
||||||
if (!enable_sound)
|
if (!enable_sound)
|
||||||
return;
|
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)
|
void I_ShutdownSound(void)
|
||||||
|
|
|
||||||
|
|
@ -507,6 +507,10 @@ UNUSED_ATTR static int find_min_sampr_ge_22(void)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const struct mixer_play_cbs mixer_cbs = {
|
||||||
|
.get_more = get_more,
|
||||||
|
};
|
||||||
|
|
||||||
static int midimain(const void * filename)
|
static int midimain(const void * filename)
|
||||||
{
|
{
|
||||||
int a, notes_used, vol;
|
int a, notes_used, vol;
|
||||||
|
|
@ -625,7 +629,7 @@ static int midimain(const void * filename)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
rb->pcmbuf_fade(false, true);
|
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)
|
while (!quit)
|
||||||
{
|
{
|
||||||
|
|
@ -684,7 +688,7 @@ static int midimain(const void * filename)
|
||||||
#endif
|
#endif
|
||||||
midi_debug("Rewind to %d:%02d\n", playing_time/60, playing_time%60);
|
midi_debug("Rewind to %d:%02d\n", playing_time/60, playing_time%60);
|
||||||
if (is_playing)
|
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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -706,7 +710,7 @@ static int midimain(const void * filename)
|
||||||
#endif
|
#endif
|
||||||
midi_debug("Skip to %d:%02d\n", playing_time/60, playing_time%60);
|
midi_debug("Skip to %d:%02d\n", playing_time/60, playing_time%60);
|
||||||
if (is_playing)
|
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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -292,6 +292,10 @@ static void get_more(const void** start, size_t* size)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const struct mixer_play_cbs mixer_cbs = {
|
||||||
|
.get_more = get_more,
|
||||||
|
};
|
||||||
|
|
||||||
static void showinfo(void)
|
static void showinfo(void)
|
||||||
{
|
{
|
||||||
char statustext[LINE_LENGTH];
|
char statustext[LINE_LENGTH];
|
||||||
|
|
@ -600,10 +604,9 @@ static void applysettings(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MikMod_Reset(""); BROKEN!
|
// MikMod_Reset(""); BROKEN!
|
||||||
|
|
||||||
rb->mixer_channel_stop(PCM_MIXER_CHAN_PLAYBACK);
|
rb->mixer_channel_stop(PCM_MIXER_CHAN_PLAYBACK);
|
||||||
rb->mixer_set_frequency(md_mixfreq);
|
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
|
#ifdef HAVE_ADJUSTABLE_CPU_FREQ
|
||||||
|
|
@ -810,7 +813,7 @@ static int playfile(char* filename)
|
||||||
display = DISPLAY_INFO;
|
display = DISPLAY_INFO;
|
||||||
Player_Start(module);
|
Player_Start(module);
|
||||||
rb->pcmbuf_fade(false, true);
|
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
|
#ifdef HAVE_ADJUSTABLE_CPU_FREQ
|
||||||
|
|
|
||||||
|
|
@ -173,6 +173,10 @@ static void get_more(const void **start, size_t *size)
|
||||||
pcmbuf_read = pcmbuf_written;
|
pcmbuf_read = pcmbuf_written;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const struct mixer_play_cbs mixer_cbs = {
|
||||||
|
.get_more = get_more,
|
||||||
|
};
|
||||||
|
|
||||||
/** Public interface **/
|
/** Public interface **/
|
||||||
|
|
||||||
/* Return a buffer pointer if at least size bytes are available and if so,
|
/* 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 */
|
/* Restart if playing state was current */
|
||||||
if (status == CHANNEL_PLAYING)
|
if (status == CHANNEL_PLAYING)
|
||||||
rb->mixer_channel_play_data(MPEG_PCM_CHANNEL,
|
rb->mixer_channel_play_data(MPEG_PCM_CHANNEL, &mixer_cbs, NULL, 0);
|
||||||
get_more, NULL, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Seek the reference clock to the specified time - next audio data ready to
|
/* 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)
|
if (play)
|
||||||
{
|
{
|
||||||
rb->mixer_channel_set_amplitude(MPEG_PCM_CHANNEL, MIX_AMP_UNITY);
|
rb->mixer_channel_set_amplitude(MPEG_PCM_CHANNEL, MIX_AMP_UNITY);
|
||||||
rb->mixer_channel_play_data(MPEG_PCM_CHANNEL,
|
rb->mixer_channel_play_data(MPEG_PCM_CHANNEL, &mixer_cbs, NULL, 0);
|
||||||
get_more, NULL, 0);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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 */
|
||||||
|
|
|
||||||
|
|
@ -407,8 +407,11 @@ static void start_sound(void)
|
||||||
|
|
||||||
wsg3_set_sampling_rate(caps->samprs[sr_index]);
|
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_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;
|
sound_playing = true;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -181,7 +181,10 @@ int rockbox_send_dacs(void)
|
||||||
if(!playing && outbuf_fill > 0)
|
if(!playing && outbuf_fill > 0)
|
||||||
{
|
{
|
||||||
/* Start playing. */
|
/* 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. */
|
/* Set status flag. */
|
||||||
playing = true;
|
playing = true;
|
||||||
|
|
|
||||||
|
|
@ -73,7 +73,10 @@ int rockboy_pcm_submit(void)
|
||||||
|
|
||||||
if(newly_started)
|
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;
|
newly_started = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -288,7 +288,10 @@ static int ROCKBOXAUD_OpenAudio(_THIS, SDL_AudioSpec *spec)
|
||||||
|
|
||||||
rbaud_underruns = 0;
|
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. :-) */
|
/* We're ready to rock and roll. :-) */
|
||||||
return(0);
|
return(0);
|
||||||
|
|
|
||||||
|
|
@ -237,7 +237,10 @@ static void play_tone(bool volume_set)
|
||||||
IF_PRIO(, PRIORITY_PLAYBACK)
|
IF_PRIO(, PRIORITY_PLAYBACK)
|
||||||
IF_COP(, CPU));
|
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
|
#ifndef HAVE_VOLUME_IN_LIST
|
||||||
if (volume_set)
|
if (volume_set)
|
||||||
|
|
|
||||||
|
|
@ -222,8 +222,11 @@ void syssnd_update(void)
|
||||||
|
|
||||||
if (!isAudioPlaying && fillCount > 0)
|
if (!isAudioPlaying && fillCount > 0)
|
||||||
{
|
{
|
||||||
|
static const struct mixer_play_cbs cbs = {
|
||||||
|
.get_more = get_more,
|
||||||
|
};
|
||||||
isAudioPlaying = true;
|
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_param = param;
|
||||||
audio_sys = sys;
|
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)
|
void sys_stopAudio(struct System* sys)
|
||||||
|
|
|
||||||
|
|
@ -212,7 +212,10 @@ static void write_buf(void){
|
||||||
= my_buf[j+10] = my_buf[j+11] \
|
= my_buf[j+10] = my_buf[j+11] \
|
||||||
= (((byte)sp_sound_buf[i])<<8) >> settings.volume;
|
= (((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
|
#if 0
|
||||||
/* can use to save and later analyze what we produce */
|
/* 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 =
|
struct voice_pcm_frame *frame =
|
||||||
&voice_buf->frames[voice_buf->frame_out % VOICE_FRAMES];
|
&voice_buf->frames[voice_buf->frame_out % VOICE_FRAMES];
|
||||||
|
|
||||||
mixer_channel_play_data(PCM_MIXER_CHAN_VOICE, voice_pcm_callback,
|
static const struct mixer_play_cbs cbs = {
|
||||||
frame->pcm, frame->size);
|
.get_more = voice_pcm_callback,
|
||||||
|
};
|
||||||
|
mixer_channel_play_data(PCM_MIXER_CHAN_VOICE, &cbs, frame->pcm, frame->size);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Stop the voice channel */
|
/* Stop the voice channel */
|
||||||
|
|
|
||||||
|
|
@ -1607,9 +1607,9 @@ size_t mixer_channel_get_bytes_waiting(enum pcm_mixer_channel channel)
|
||||||
\return
|
\return
|
||||||
\description
|
\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 channel
|
||||||
\param get_more
|
\param cbs
|
||||||
\param start
|
\param start
|
||||||
\param size
|
\param size
|
||||||
\description
|
\description
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -96,8 +96,13 @@ enum channel_status
|
||||||
/** Public interfaces **/
|
/** Public interfaces **/
|
||||||
|
|
||||||
/* Start playback on a channel */
|
/* 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,
|
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);
|
const void *start, size_t size);
|
||||||
|
|
||||||
/* Pause or resume a channel (when started) */
|
/* 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,
|
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);
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,6 @@
|
||||||
before the last samples are sent to the codec and so things are done in
|
before the last samples are sent to the codec and so things are done in
|
||||||
parallel (as much as possible) with sending-out data. */
|
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;
|
static unsigned int mix_frame_size = MIX_FRAME_SAMPLES*4;
|
||||||
|
|
||||||
/* Define this to nonzero to add a marker pulse at each frame start */
|
/* Define this to nonzero to add a marker pulse at each frame start */
|
||||||
|
|
@ -42,13 +41,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 */
|
||||||
pcm_play_callback_type get_more; /* Registered callback */
|
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))
|
||||||
|
|
@ -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;
|
static struct mixer_channel * active_channels[PCM_MIXER_NUM_CHANNELS+1] IBSS_ATTR;
|
||||||
|
|
||||||
/* Number of silence frames to play after all data has played */
|
/* 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;
|
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 **/
|
/** Mixing routines, CPU optmized **/
|
||||||
#include "asm/pcm-mixer.c"
|
#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)
|
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 +163,9 @@ fill_frame:
|
||||||
|
|
||||||
if (chan->size == 0)
|
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);
|
ALIGN_AUDIOBUF(chan->start, chan->size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -233,7 +242,7 @@ fill_frame:
|
||||||
goto fill_frame;
|
goto fill_frame;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (idle_counter++ < MAX_IDLE_FRAMES)
|
else if (idle_counter++ < max_idle_frames())
|
||||||
{
|
{
|
||||||
/* Pad incomplete frames with silence */
|
/* Pad incomplete frames with silence */
|
||||||
if (idle_counter <= 3)
|
if (idle_counter <= 3)
|
||||||
|
|
@ -265,12 +274,6 @@ static void mixer_start_pcm(void)
|
||||||
return;
|
return;
|
||||||
#endif
|
#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 */
|
/* Prepare initial frames and set up the double buffer */
|
||||||
mixer_buffer_callback(PCM_DMAST_STARTED);
|
mixer_buffer_callback(PCM_DMAST_STARTED);
|
||||||
|
|
||||||
|
|
@ -287,14 +290,14 @@ static void mixer_start_pcm(void)
|
||||||
|
|
||||||
/* Start playback on a channel */
|
/* Start playback on a channel */
|
||||||
void mixer_channel_play_data(enum pcm_mixer_channel 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)
|
const void *start, size_t size)
|
||||||
{
|
{
|
||||||
struct mixer_channel *chan = &channels[channel];
|
struct mixer_channel *chan = &channels[channel];
|
||||||
|
|
||||||
ALIGN_AUDIOBUF(start, size);
|
ALIGN_AUDIOBUF(start, size);
|
||||||
|
|
||||||
if (!(start && size) && get_more)
|
if (!(start && size) && cbs && cbs->get_more)
|
||||||
{
|
{
|
||||||
/* Initial buffer not passed - call the callback now */
|
/* Initial buffer not passed - call the callback now */
|
||||||
pcm_play_lock();
|
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 */
|
pcm_play_unlock(); /* Allow playback while doing callback */
|
||||||
|
|
||||||
size = 0;
|
size = 0;
|
||||||
get_more(&start, &size);
|
cbs->get_more(&start, &size);
|
||||||
ALIGN_AUDIOBUF(start, size);
|
ALIGN_AUDIOBUF(start, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -317,7 +320,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->get_more = get_more;
|
chan->play_cbs = cbs;
|
||||||
|
|
||||||
mixer_activate_channel(chan);
|
mixer_activate_channel(chan);
|
||||||
chan_call_buffer_hook(chan);
|
chan_call_buffer_hook(chan);
|
||||||
|
|
@ -429,15 +432,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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -455,24 +457,51 @@ void mixer_reset(void)
|
||||||
/* Set output samplerate */
|
/* Set output samplerate */
|
||||||
void mixer_set_frequency(unsigned int samplerate)
|
void mixer_set_frequency(unsigned int samplerate)
|
||||||
{
|
{
|
||||||
pcm_set_frequency(samplerate);
|
if(pcm_get_frequency() == samplerate)
|
||||||
samplerate = pcm_get_frequency();
|
|
||||||
|
|
||||||
#ifdef CONFIG_SAMPR_TYPES
|
|
||||||
samplerate &= ~SAMPR_TYPE_MASK;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (samplerate == mixer_sampr)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* All data is now invalid */
|
pcm_set_frequency(samplerate);
|
||||||
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->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 */
|
/* Work out how much space we really need */
|
||||||
if (samplerate > SAMPR_96)
|
if (SAMPR_NUM(samplerate) > SAMPR_96)
|
||||||
mix_frame_size = 4;
|
mix_frame_size = 4;
|
||||||
else if (samplerate > SAMPR_48)
|
else if (SAMPR_NUM(samplerate) > SAMPR_48)
|
||||||
mix_frame_size = 2;
|
mix_frame_size = 2;
|
||||||
else
|
else
|
||||||
mix_frame_size = 1;
|
mix_frame_size = 1;
|
||||||
|
|
@ -486,5 +515,5 @@ void mixer_set_frequency(unsigned int samplerate)
|
||||||
/* Get output samplerate */
|
/* Get output samplerate */
|
||||||
unsigned int mixer_get_frequency(void)
|
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");
|
logf("usbaudio: prebuffering done");
|
||||||
playback_audio_underflow = false;
|
playback_audio_underflow = false;
|
||||||
usb_rx_overflow = 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);
|
restore_irq(oldlevel);
|
||||||
retval = true;
|
retval = true;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue