diff options
Diffstat (limited to 'firmware')
| -rw-r--r-- | firmware/export/config_caps.h | 34 | ||||
| -rw-r--r-- | firmware/export/pcm.h | 3 | ||||
| -rw-r--r-- | firmware/export/pcm_mixer.h | 6 | ||||
| -rw-r--r-- | firmware/export/pcm_sampr.h | 56 | ||||
| -rw-r--r-- | firmware/pcm.c | 6 | ||||
| -rw-r--r-- | firmware/pcm_mixer.c | 27 |
6 files changed, 125 insertions, 7 deletions
diff --git a/firmware/export/config_caps.h b/firmware/export/config_caps.h index fcb13de..bc0a42b 100644 --- a/firmware/export/config_caps.h +++ b/firmware/export/config_caps.h @@ -116,3 +116,37 @@ #endif #endif /* HAVE_RECORDING */ + +/* Samplerate config */ +#define PCM_SAMPR_CONFIG_ONLY /* no C code */ +#include "pcm_sampr.h" +#undef PCM_SAMPR_CONFIG_ONLY + +#define PLAY_SAMPR_CAPS (HW_SAMPR_CAPS & (SAMPR_CAP_44 | SAMPR_CAP_48)) +/** + * PLAY_SAMPR_MIN: The minimum allowable samplerate for global playback. + * Music won't play at a lower rate. + * PLAY_SAMPR_MAX: The maximum allowable samplerate for global playback. + * Music won't play at a faster rate. + * PLAY_SAMPR_DEFAULT: The default samplerate, unless configured otherwise. + * PLAY_SAMPR_HW_MIN: The minimum allowable rate for some subsystems such + * as the DSP core. DSP never exceeds *MAX to lessen + * buffer allocation demands and overhead. + */ +#if PLAY_SAMPR_CAPS & (PLAY_SAMPR_CAPS - 1) +#define HAVE_PLAY_FREQ +# define PLAY_SAMPR_MIN SAMPR_44 +# define PLAY_SAMPR_MAX SAMPR_48 +# define PLAY_SAMPR_DEFAULT SAMPR_44 +# define PLAY_SAMPR_HW_MIN HW_SAMPR_MIN +#elif PLAY_SAMPR_CAPS & SAMPR_CAP_44 +# define PLAY_SAMPR_MIN SAMPR_44 +# define PLAY_SAMPR_MAX SAMPR_44 +# define PLAY_SAMPR_DEFAULT SAMPR_44 +# define PLAY_SAMPR_HW_MIN HW_SAMPR_MIN +#elif PLAY_SAMPR_CAPS & SAMPR_CAP_48 +# define PLAY_SAMPR_MIN SAMPR_48 +# define PLAY_SAMPR_MAX SAMPR_48 +# define PLAY_SAMPR_DEFAULT SAMPR_48 +# define PLAY_SAMPR_HW_MIN HW_SAMPR_MIN +#endif diff --git a/firmware/export/pcm.h b/firmware/export/pcm.h index fdd4623..23c0bd4 100644 --- a/firmware/export/pcm.h +++ b/firmware/export/pcm.h @@ -53,7 +53,10 @@ unsigned int pcm_sampr_type_rec_to_play(unsigned int samplerate); #endif #endif /* CONFIG_SAMPR_TYPES */ +/* set next frequency to be used */ void pcm_set_frequency(unsigned int samplerate); +/* return last-set frequency */ +unsigned int pcm_get_frequency(void); /* apply settings to hardware immediately */ void pcm_apply_settings(void); diff --git a/firmware/export/pcm_mixer.h b/firmware/export/pcm_mixer.h index d424083..f7f869e 100644 --- a/firmware/export/pcm_mixer.h +++ b/firmware/export/pcm_mixer.h @@ -127,4 +127,10 @@ void mixer_channel_set_buffer_hook(enum pcm_mixer_channel channel, /* Stop ALL channels and PCM and reset state */ void mixer_reset(void); +/* Set output samplerate */ +void mixer_set_frequency(unsigned int samplerate); + +/* Get output samplerate */ +unsigned int mixer_get_frequency(void); + #endif /* PCM_MIXER_H */ diff --git a/firmware/export/pcm_sampr.h b/firmware/export/pcm_sampr.h index 01a8ed4..dcb1bdd 100644 --- a/firmware/export/pcm_sampr.h +++ b/firmware/export/pcm_sampr.h @@ -20,7 +20,12 @@ ****************************************************************************/ #ifndef PCM_SAMPR_H + +/* File might be included for CPP config macros only. Allow it to be included + * again for full C declarations. */ +#ifndef PCM_SAMPR_CONFIG_ONLY #define PCM_SAMPR_H +#endif #ifndef HW_SAMPR_CAPS #define HW_SAMPR_CAPS SAMPR_CAP_44 /* if not defined, default to 44100 */ @@ -75,11 +80,14 @@ SAMPR_CAP_24 | SAMPR_CAP_22 | SAMPR_CAP_16 | \ SAMPR_CAP_12 | SAMPR_CAP_11 | SAMPR_CAP_8) +#ifndef PCM_SAMPR_CONFIG_ONLY /* Master list of all "standard" rates supported. */ extern const unsigned long audio_master_sampr_list[SAMPR_NUM_FREQ]; +#endif /* PCM_SAMPR_CONFIG_ONLY */ /** Hardware sample rates **/ +#ifndef PCM_SAMPR_CONFIG_ONLY /* Enumeration of supported frequencies where 0 is the highest rate supported and REC_NUM_FREQUENCIES is the number available */ enum hw_freq_indexes @@ -183,14 +191,49 @@ enum hw_freq_indexes #define HW_HAVE_8_(...) #endif HW_NUM_FREQ, - HW_FREQ_DEFAULT = HW_FREQ_44, - HW_SAMPR_DEFAULT = SAMPR_44, }; /* enum hw_freq_indexes */ /* list of hardware sample rates */ extern const unsigned long hw_freq_sampr[HW_NUM_FREQ]; +#endif /* PCM_SAMPR_CONFIG_ONLY */ + +#define HW_FREQ_DEFAULT HW_FREQ_44 +#define HW_SAMPR_DEFAULT SAMPR_44 + + +#if HW_SAMPR_CAPS & SAMPR_CAP_96 +# define HW_SAMPR_MAX SAMPR_96 +#elif HW_SAMPR_CAPS & SAMPR_CAP_88 +# define HW_SAMPR_MAX SAMPR_88 +#elif HW_SAMPR_CAPS & SAMPR_CAP_64 +# define HW_SAMPR_MAX SAMPR_64 +#elif HW_SAMPR_CAPS & SAMPR_CAP_48 +# define HW_SAMPR_MAX SAMPR_48 +#else +# define HW_SAMPR_MAX SAMPR_44 +#endif + +#if HW_SAMPR_CAPS & SAMPR_CAP_8 +# define HW_SAMPR_MIN SAMPR_8 +#elif HW_SAMPR_CAPS & SAMPR_CAP_11 +# define HW_SAMPR_MIN SAMPR_11 +#elif HW_SAMPR_CAPS & SAMPR_CAP_12 +# define HW_SAMPR_MIN SAMPR_12 +#elif HW_SAMPR_CAPS & SAMPR_CAP_16 +# define HW_SAMPR_MIN SAMPR_16 +#elif HW_SAMPR_CAPS & SAMPR_CAP_22 +# define HW_SAMPR_MIN SAMPR_22 +#elif HW_SAMPR_CAPS & SAMPR_CAP_24 +# define HW_SAMPR_MIN SAMPR_24 +#elif HW_SAMPR_CAPS & SAMPR_CAP_32 +# define HW_SAMPR_MIN SAMPR_32 +#else +# define HW_SAMPR_MIN SAMPR_44 +#endif #ifdef HAVE_RECORDING + +#ifndef PCM_SAMPR_CONFIG_ONLY /* Enumeration of supported frequencies where 0 is the highest rate supported and REC_NUM_FREQUENCIES is the number available */ enum rec_freq_indexes @@ -296,6 +339,10 @@ enum rec_freq_indexes REC_NUM_FREQ, }; /* enum rec_freq_indexes */ +/* List of recording supported sample rates (set or subset of master list) */ +extern const unsigned long rec_freq_sampr[REC_NUM_FREQ]; +#endif /* PCM_SAMPR_CONFIG_ONLY */ + /* Default to 44.1kHz if not otherwise specified */ #ifndef REC_FREQ_DEFAULT #define REC_FREQ_DEFAULT REC_FREQ_44 @@ -314,8 +361,7 @@ enum rec_freq_indexes REC_HAVE_16_(",16") REC_HAVE_12_(",12") \ REC_HAVE_11_(",11") REC_HAVE_8_(",8")[1] -/* List of recording supported sample rates (set or subset of master list) */ -extern const unsigned long rec_freq_sampr[REC_NUM_FREQ]; + #endif /* HAVE_RECORDING */ #ifdef CONFIG_SAMPR_TYPES @@ -326,8 +372,10 @@ extern const unsigned long rec_freq_sampr[REC_NUM_FREQ]; #define SAMPR_TYPE_REC (0x01 << 24) #endif +#ifndef PCM_SAMPR_CONFIG_ONLY unsigned int pcm_sampr_to_hw_sampr(unsigned int samplerate, unsigned int type); +#endif #else /* ndef CONFIG_SAMPR_TYPES */ diff --git a/firmware/pcm.c b/firmware/pcm.c index e095ab2..60ccdbd 100644 --- a/firmware/pcm.c +++ b/firmware/pcm.c @@ -415,6 +415,12 @@ void pcm_set_frequency(unsigned int samplerate) pcm_fsel = index; } +/* return last-set frequency */ +unsigned int pcm_get_frequency(void) +{ + return pcm_sampr; +} + /* apply pcm settings to the hardware */ void pcm_apply_settings(void) { diff --git a/firmware/pcm_mixer.c b/firmware/pcm_mixer.c index 34852e9..ceba319 100644 --- a/firmware/pcm_mixer.c +++ b/firmware/pcm_mixer.c @@ -25,7 +25,6 @@ #include "pcm.h" #include "pcm-internal.h" #include "pcm_mixer.h" -#include "dsp_core.h" /* For NATIVE_FREQUENCY */ /* Channels use standard-style PCM callback interface but a latency of one frame by double-buffering is introduced in order to facilitate mixing and @@ -33,6 +32,8 @@ 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 = HW_SAMPR_DEFAULT; + /* Define this to nonzero to add a marker pulse at each frame start */ #define FRAME_BOUNDARY_MARKERS 0 @@ -65,7 +66,7 @@ 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 (NATIVE_FREQUENCY*3 / MIX_FRAME_SAMPLES) +#define MAX_IDLE_FRAMES (mixer_sampr*3 / MIX_FRAME_SAMPLES) static unsigned int idle_counter = 0; /** Mixing routines, CPU optmized **/ @@ -256,7 +257,7 @@ static void mixer_start_pcm(void) #endif /* Requires a shared global sample rate for all channels */ - pcm_set_frequency(NATIVE_FREQUENCY); + pcm_set_frequency(mixer_sampr); /* Prepare initial frames and set up the double buffer */ mixer_buffer_callback(PCM_DMAST_STARTED); @@ -438,3 +439,23 @@ void mixer_reset(void) idle_counter = 0; } + +/* Set output samplerate */ +void mixer_set_frequency(unsigned int samplerate) +{ + pcm_set_frequency(samplerate); + samplerate = pcm_get_frequency(); + + if (samplerate == mixer_sampr) + return; + + /* All data is now invalid */ + mixer_reset(); + mixer_sampr = samplerate; +} + +/* Get output samplerate */ +unsigned int mixer_get_frequency(void) +{ + return mixer_sampr; +} |