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 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;
+}