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 fcb13debfc..bc0a42bedf 100644 --- a/firmware/export/config_caps.h +++ b/firmware/export/config_caps.h | |||
@@ -116,3 +116,37 @@ | |||
116 | #endif | 116 | #endif |
117 | 117 | ||
118 | #endif /* HAVE_RECORDING */ | 118 | #endif /* HAVE_RECORDING */ |
119 | |||
120 | /* Samplerate config */ | ||
121 | #define PCM_SAMPR_CONFIG_ONLY /* no C code */ | ||
122 | #include "pcm_sampr.h" | ||
123 | #undef PCM_SAMPR_CONFIG_ONLY | ||
124 | |||
125 | #define PLAY_SAMPR_CAPS (HW_SAMPR_CAPS & (SAMPR_CAP_44 | SAMPR_CAP_48)) | ||
126 | /** | ||
127 | * PLAY_SAMPR_MIN: The minimum allowable samplerate for global playback. | ||
128 | * Music won't play at a lower rate. | ||
129 | * PLAY_SAMPR_MAX: The maximum allowable samplerate for global playback. | ||
130 | * Music won't play at a faster rate. | ||
131 | * PLAY_SAMPR_DEFAULT: The default samplerate, unless configured otherwise. | ||
132 | * PLAY_SAMPR_HW_MIN: The minimum allowable rate for some subsystems such | ||
133 | * as the DSP core. DSP never exceeds *MAX to lessen | ||
134 | * buffer allocation demands and overhead. | ||
135 | */ | ||
136 | #if PLAY_SAMPR_CAPS & (PLAY_SAMPR_CAPS - 1) | ||
137 | #define HAVE_PLAY_FREQ | ||
138 | # define PLAY_SAMPR_MIN SAMPR_44 | ||
139 | # define PLAY_SAMPR_MAX SAMPR_48 | ||
140 | # define PLAY_SAMPR_DEFAULT SAMPR_44 | ||
141 | # define PLAY_SAMPR_HW_MIN HW_SAMPR_MIN | ||
142 | #elif PLAY_SAMPR_CAPS & SAMPR_CAP_44 | ||
143 | # define PLAY_SAMPR_MIN SAMPR_44 | ||
144 | # define PLAY_SAMPR_MAX SAMPR_44 | ||
145 | # define PLAY_SAMPR_DEFAULT SAMPR_44 | ||
146 | # define PLAY_SAMPR_HW_MIN HW_SAMPR_MIN | ||
147 | #elif PLAY_SAMPR_CAPS & SAMPR_CAP_48 | ||
148 | # define PLAY_SAMPR_MIN SAMPR_48 | ||
149 | # define PLAY_SAMPR_MAX SAMPR_48 | ||
150 | # define PLAY_SAMPR_DEFAULT SAMPR_48 | ||
151 | # define PLAY_SAMPR_HW_MIN HW_SAMPR_MIN | ||
152 | #endif | ||
diff --git a/firmware/export/pcm.h b/firmware/export/pcm.h index fdd46237a6..23c0bd4a0b 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); | |||
53 | #endif | 53 | #endif |
54 | #endif /* CONFIG_SAMPR_TYPES */ | 54 | #endif /* CONFIG_SAMPR_TYPES */ |
55 | 55 | ||
56 | /* set next frequency to be used */ | ||
56 | void pcm_set_frequency(unsigned int samplerate); | 57 | void pcm_set_frequency(unsigned int samplerate); |
58 | /* return last-set frequency */ | ||
59 | unsigned int pcm_get_frequency(void); | ||
57 | /* apply settings to hardware immediately */ | 60 | /* apply settings to hardware immediately */ |
58 | void pcm_apply_settings(void); | 61 | void pcm_apply_settings(void); |
59 | 62 | ||
diff --git a/firmware/export/pcm_mixer.h b/firmware/export/pcm_mixer.h index d424083002..f7f869eaaf 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, | |||
127 | /* Stop ALL channels and PCM and reset state */ | 127 | /* Stop ALL channels and PCM and reset state */ |
128 | void mixer_reset(void); | 128 | void mixer_reset(void); |
129 | 129 | ||
130 | /* Set output samplerate */ | ||
131 | void mixer_set_frequency(unsigned int samplerate); | ||
132 | |||
133 | /* Get output samplerate */ | ||
134 | unsigned int mixer_get_frequency(void); | ||
135 | |||
130 | #endif /* PCM_MIXER_H */ | 136 | #endif /* PCM_MIXER_H */ |
diff --git a/firmware/export/pcm_sampr.h b/firmware/export/pcm_sampr.h index 01a8ed428e..dcb1bdd80f 100644 --- a/firmware/export/pcm_sampr.h +++ b/firmware/export/pcm_sampr.h | |||
@@ -20,7 +20,12 @@ | |||
20 | ****************************************************************************/ | 20 | ****************************************************************************/ |
21 | 21 | ||
22 | #ifndef PCM_SAMPR_H | 22 | #ifndef PCM_SAMPR_H |
23 | |||
24 | /* File might be included for CPP config macros only. Allow it to be included | ||
25 | * again for full C declarations. */ | ||
26 | #ifndef PCM_SAMPR_CONFIG_ONLY | ||
23 | #define PCM_SAMPR_H | 27 | #define PCM_SAMPR_H |
28 | #endif | ||
24 | 29 | ||
25 | #ifndef HW_SAMPR_CAPS | 30 | #ifndef HW_SAMPR_CAPS |
26 | #define HW_SAMPR_CAPS SAMPR_CAP_44 /* if not defined, default to 44100 */ | 31 | #define HW_SAMPR_CAPS SAMPR_CAP_44 /* if not defined, default to 44100 */ |
@@ -75,11 +80,14 @@ | |||
75 | SAMPR_CAP_24 | SAMPR_CAP_22 | SAMPR_CAP_16 | \ | 80 | SAMPR_CAP_24 | SAMPR_CAP_22 | SAMPR_CAP_16 | \ |
76 | SAMPR_CAP_12 | SAMPR_CAP_11 | SAMPR_CAP_8) | 81 | SAMPR_CAP_12 | SAMPR_CAP_11 | SAMPR_CAP_8) |
77 | 82 | ||
83 | #ifndef PCM_SAMPR_CONFIG_ONLY | ||
78 | /* Master list of all "standard" rates supported. */ | 84 | /* Master list of all "standard" rates supported. */ |
79 | extern const unsigned long audio_master_sampr_list[SAMPR_NUM_FREQ]; | 85 | extern const unsigned long audio_master_sampr_list[SAMPR_NUM_FREQ]; |
86 | #endif /* PCM_SAMPR_CONFIG_ONLY */ | ||
80 | 87 | ||
81 | /** Hardware sample rates **/ | 88 | /** Hardware sample rates **/ |
82 | 89 | ||
90 | #ifndef PCM_SAMPR_CONFIG_ONLY | ||
83 | /* Enumeration of supported frequencies where 0 is the highest rate | 91 | /* Enumeration of supported frequencies where 0 is the highest rate |
84 | supported and REC_NUM_FREQUENCIES is the number available */ | 92 | supported and REC_NUM_FREQUENCIES is the number available */ |
85 | enum hw_freq_indexes | 93 | enum hw_freq_indexes |
@@ -183,14 +191,49 @@ enum hw_freq_indexes | |||
183 | #define HW_HAVE_8_(...) | 191 | #define HW_HAVE_8_(...) |
184 | #endif | 192 | #endif |
185 | HW_NUM_FREQ, | 193 | HW_NUM_FREQ, |
186 | HW_FREQ_DEFAULT = HW_FREQ_44, | ||
187 | HW_SAMPR_DEFAULT = SAMPR_44, | ||
188 | }; /* enum hw_freq_indexes */ | 194 | }; /* enum hw_freq_indexes */ |
189 | 195 | ||
190 | /* list of hardware sample rates */ | 196 | /* list of hardware sample rates */ |
191 | extern const unsigned long hw_freq_sampr[HW_NUM_FREQ]; | 197 | extern const unsigned long hw_freq_sampr[HW_NUM_FREQ]; |
198 | #endif /* PCM_SAMPR_CONFIG_ONLY */ | ||
199 | |||
200 | #define HW_FREQ_DEFAULT HW_FREQ_44 | ||
201 | #define HW_SAMPR_DEFAULT SAMPR_44 | ||
202 | |||
203 | |||
204 | #if HW_SAMPR_CAPS & SAMPR_CAP_96 | ||
205 | # define HW_SAMPR_MAX SAMPR_96 | ||
206 | #elif HW_SAMPR_CAPS & SAMPR_CAP_88 | ||
207 | # define HW_SAMPR_MAX SAMPR_88 | ||
208 | #elif HW_SAMPR_CAPS & SAMPR_CAP_64 | ||
209 | # define HW_SAMPR_MAX SAMPR_64 | ||
210 | #elif HW_SAMPR_CAPS & SAMPR_CAP_48 | ||
211 | # define HW_SAMPR_MAX SAMPR_48 | ||
212 | #else | ||
213 | # define HW_SAMPR_MAX SAMPR_44 | ||
214 | #endif | ||
215 | |||
216 | #if HW_SAMPR_CAPS & SAMPR_CAP_8 | ||
217 | # define HW_SAMPR_MIN SAMPR_8 | ||
218 | #elif HW_SAMPR_CAPS & SAMPR_CAP_11 | ||
219 | # define HW_SAMPR_MIN SAMPR_11 | ||
220 | #elif HW_SAMPR_CAPS & SAMPR_CAP_12 | ||
221 | # define HW_SAMPR_MIN SAMPR_12 | ||
222 | #elif HW_SAMPR_CAPS & SAMPR_CAP_16 | ||
223 | # define HW_SAMPR_MIN SAMPR_16 | ||
224 | #elif HW_SAMPR_CAPS & SAMPR_CAP_22 | ||
225 | # define HW_SAMPR_MIN SAMPR_22 | ||
226 | #elif HW_SAMPR_CAPS & SAMPR_CAP_24 | ||
227 | # define HW_SAMPR_MIN SAMPR_24 | ||
228 | #elif HW_SAMPR_CAPS & SAMPR_CAP_32 | ||
229 | # define HW_SAMPR_MIN SAMPR_32 | ||
230 | #else | ||
231 | # define HW_SAMPR_MIN SAMPR_44 | ||
232 | #endif | ||
192 | 233 | ||
193 | #ifdef HAVE_RECORDING | 234 | #ifdef HAVE_RECORDING |
235 | |||
236 | #ifndef PCM_SAMPR_CONFIG_ONLY | ||
194 | /* Enumeration of supported frequencies where 0 is the highest rate | 237 | /* Enumeration of supported frequencies where 0 is the highest rate |
195 | supported and REC_NUM_FREQUENCIES is the number available */ | 238 | supported and REC_NUM_FREQUENCIES is the number available */ |
196 | enum rec_freq_indexes | 239 | enum rec_freq_indexes |
@@ -296,6 +339,10 @@ enum rec_freq_indexes | |||
296 | REC_NUM_FREQ, | 339 | REC_NUM_FREQ, |
297 | }; /* enum rec_freq_indexes */ | 340 | }; /* enum rec_freq_indexes */ |
298 | 341 | ||
342 | /* List of recording supported sample rates (set or subset of master list) */ | ||
343 | extern const unsigned long rec_freq_sampr[REC_NUM_FREQ]; | ||
344 | #endif /* PCM_SAMPR_CONFIG_ONLY */ | ||
345 | |||
299 | /* Default to 44.1kHz if not otherwise specified */ | 346 | /* Default to 44.1kHz if not otherwise specified */ |
300 | #ifndef REC_FREQ_DEFAULT | 347 | #ifndef REC_FREQ_DEFAULT |
301 | #define REC_FREQ_DEFAULT REC_FREQ_44 | 348 | #define REC_FREQ_DEFAULT REC_FREQ_44 |
@@ -314,8 +361,7 @@ enum rec_freq_indexes | |||
314 | REC_HAVE_16_(",16") REC_HAVE_12_(",12") \ | 361 | REC_HAVE_16_(",16") REC_HAVE_12_(",12") \ |
315 | REC_HAVE_11_(",11") REC_HAVE_8_(",8")[1] | 362 | REC_HAVE_11_(",11") REC_HAVE_8_(",8")[1] |
316 | 363 | ||
317 | /* List of recording supported sample rates (set or subset of master list) */ | 364 | |
318 | extern const unsigned long rec_freq_sampr[REC_NUM_FREQ]; | ||
319 | #endif /* HAVE_RECORDING */ | 365 | #endif /* HAVE_RECORDING */ |
320 | 366 | ||
321 | #ifdef CONFIG_SAMPR_TYPES | 367 | #ifdef CONFIG_SAMPR_TYPES |
@@ -326,8 +372,10 @@ extern const unsigned long rec_freq_sampr[REC_NUM_FREQ]; | |||
326 | #define SAMPR_TYPE_REC (0x01 << 24) | 372 | #define SAMPR_TYPE_REC (0x01 << 24) |
327 | #endif | 373 | #endif |
328 | 374 | ||
375 | #ifndef PCM_SAMPR_CONFIG_ONLY | ||
329 | unsigned int pcm_sampr_to_hw_sampr(unsigned int samplerate, | 376 | unsigned int pcm_sampr_to_hw_sampr(unsigned int samplerate, |
330 | unsigned int type); | 377 | unsigned int type); |
378 | #endif | ||
331 | 379 | ||
332 | #else /* ndef CONFIG_SAMPR_TYPES */ | 380 | #else /* ndef CONFIG_SAMPR_TYPES */ |
333 | 381 | ||
diff --git a/firmware/pcm.c b/firmware/pcm.c index e095ab2cea..60ccdbd2fc 100644 --- a/firmware/pcm.c +++ b/firmware/pcm.c | |||
@@ -415,6 +415,12 @@ void pcm_set_frequency(unsigned int samplerate) | |||
415 | pcm_fsel = index; | 415 | pcm_fsel = index; |
416 | } | 416 | } |
417 | 417 | ||
418 | /* return last-set frequency */ | ||
419 | unsigned int pcm_get_frequency(void) | ||
420 | { | ||
421 | return pcm_sampr; | ||
422 | } | ||
423 | |||
418 | /* apply pcm settings to the hardware */ | 424 | /* apply pcm settings to the hardware */ |
419 | void pcm_apply_settings(void) | 425 | void pcm_apply_settings(void) |
420 | { | 426 | { |
diff --git a/firmware/pcm_mixer.c b/firmware/pcm_mixer.c index 34852e97e9..ceba31962e 100644 --- a/firmware/pcm_mixer.c +++ b/firmware/pcm_mixer.c | |||
@@ -25,7 +25,6 @@ | |||
25 | #include "pcm.h" | 25 | #include "pcm.h" |
26 | #include "pcm-internal.h" | 26 | #include "pcm-internal.h" |
27 | #include "pcm_mixer.h" | 27 | #include "pcm_mixer.h" |
28 | #include "dsp_core.h" /* For NATIVE_FREQUENCY */ | ||
29 | 28 | ||
30 | /* Channels use standard-style PCM callback interface but a latency of one | 29 | /* Channels use standard-style PCM callback interface but a latency of one |
31 | frame by double-buffering is introduced in order to facilitate mixing and | 30 | frame by double-buffering is introduced in order to facilitate mixing and |
@@ -33,6 +32,8 @@ | |||
33 | before the last samples are sent to the codec and so things are done in | 32 | before the last samples are sent to the codec and so things are done in |
34 | parallel (as much as possible) with sending-out data. */ | 33 | parallel (as much as possible) with sending-out data. */ |
35 | 34 | ||
35 | static unsigned int mixer_sampr = HW_SAMPR_DEFAULT; | ||
36 | |||
36 | /* Define this to nonzero to add a marker pulse at each frame start */ | 37 | /* Define this to nonzero to add a marker pulse at each frame start */ |
37 | #define FRAME_BOUNDARY_MARKERS 0 | 38 | #define FRAME_BOUNDARY_MARKERS 0 |
38 | 39 | ||
@@ -65,7 +66,7 @@ static struct mixer_channel channels[PCM_MIXER_NUM_CHANNELS] IBSS_ATTR; | |||
65 | static struct mixer_channel * active_channels[PCM_MIXER_NUM_CHANNELS+1] IBSS_ATTR; | 66 | static struct mixer_channel * active_channels[PCM_MIXER_NUM_CHANNELS+1] IBSS_ATTR; |
66 | 67 | ||
67 | /* Number of silence frames to play after all data has played */ | 68 | /* Number of silence frames to play after all data has played */ |
68 | #define MAX_IDLE_FRAMES (NATIVE_FREQUENCY*3 / MIX_FRAME_SAMPLES) | 69 | #define MAX_IDLE_FRAMES (mixer_sampr*3 / MIX_FRAME_SAMPLES) |
69 | static unsigned int idle_counter = 0; | 70 | static unsigned int idle_counter = 0; |
70 | 71 | ||
71 | /** Mixing routines, CPU optmized **/ | 72 | /** Mixing routines, CPU optmized **/ |
@@ -256,7 +257,7 @@ static void mixer_start_pcm(void) | |||
256 | #endif | 257 | #endif |
257 | 258 | ||
258 | /* Requires a shared global sample rate for all channels */ | 259 | /* Requires a shared global sample rate for all channels */ |
259 | pcm_set_frequency(NATIVE_FREQUENCY); | 260 | pcm_set_frequency(mixer_sampr); |
260 | 261 | ||
261 | /* Prepare initial frames and set up the double buffer */ | 262 | /* Prepare initial frames and set up the double buffer */ |
262 | mixer_buffer_callback(PCM_DMAST_STARTED); | 263 | mixer_buffer_callback(PCM_DMAST_STARTED); |
@@ -438,3 +439,23 @@ void mixer_reset(void) | |||
438 | 439 | ||
439 | idle_counter = 0; | 440 | idle_counter = 0; |
440 | } | 441 | } |
442 | |||
443 | /* Set output samplerate */ | ||
444 | void mixer_set_frequency(unsigned int samplerate) | ||
445 | { | ||
446 | pcm_set_frequency(samplerate); | ||
447 | samplerate = pcm_get_frequency(); | ||
448 | |||
449 | if (samplerate == mixer_sampr) | ||
450 | return; | ||
451 | |||
452 | /* All data is now invalid */ | ||
453 | mixer_reset(); | ||
454 | mixer_sampr = samplerate; | ||
455 | } | ||
456 | |||
457 | /* Get output samplerate */ | ||
458 | unsigned int mixer_get_frequency(void) | ||
459 | { | ||
460 | return mixer_sampr; | ||
461 | } | ||