summaryrefslogtreecommitdiff
path: root/firmware
diff options
context:
space:
mode:
Diffstat (limited to 'firmware')
-rw-r--r--firmware/export/config_caps.h34
-rw-r--r--firmware/export/pcm.h3
-rw-r--r--firmware/export/pcm_mixer.h6
-rw-r--r--firmware/export/pcm_sampr.h56
-rw-r--r--firmware/pcm.c6
-rw-r--r--firmware/pcm_mixer.c27
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 */
56void pcm_set_frequency(unsigned int samplerate); 57void pcm_set_frequency(unsigned int samplerate);
58/* return last-set frequency */
59unsigned int pcm_get_frequency(void);
57/* apply settings to hardware immediately */ 60/* apply settings to hardware immediately */
58void pcm_apply_settings(void); 61void 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 */
128void mixer_reset(void); 128void mixer_reset(void);
129 129
130/* Set output samplerate */
131void mixer_set_frequency(unsigned int samplerate);
132
133/* Get output samplerate */
134unsigned 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. */
79extern const unsigned long audio_master_sampr_list[SAMPR_NUM_FREQ]; 85extern 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 */
85enum hw_freq_indexes 93enum 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 */
191extern const unsigned long hw_freq_sampr[HW_NUM_FREQ]; 197extern 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 */
196enum rec_freq_indexes 239enum 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) */
343extern 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
318extern 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
329unsigned int pcm_sampr_to_hw_sampr(unsigned int samplerate, 376unsigned 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 */
419unsigned 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 */
419void pcm_apply_settings(void) 425void 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
35static 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;
65static struct mixer_channel * active_channels[PCM_MIXER_NUM_CHANNELS+1] IBSS_ATTR; 66static 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)
69static unsigned int idle_counter = 0; 70static 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 */
444void 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 */
458unsigned int mixer_get_frequency(void)
459{
460 return mixer_sampr;
461}