summaryrefslogtreecommitdiff
path: root/firmware/export
diff options
context:
space:
mode:
authorMichael Sevakis <jethead71@rockbox.org>2006-11-06 18:18:05 +0000
committerMichael Sevakis <jethead71@rockbox.org>2006-11-06 18:18:05 +0000
commit5efee7c94adb691799becb605002e85e13bf11e5 (patch)
treec8f3e198cf40b5fad4f50ee558195ee906c261c5 /firmware/export
parent0f5cb94aa4a334366a746fcbb22f3335ca413265 (diff)
downloadrockbox-5efee7c94adb691799becb605002e85e13bf11e5.zip
rockbox-5efee7c94adb691799becb605002e85e13bf11e5.tar.gz
rockbox-5efee7c94adb691799becb605002e85e13bf11e5.tar.bz2
rockbox-5efee7c94adb691799becb605002e85e13bf11e5.tar.xz
Forgot to use cvs add on a few new files in the fresh checkout I used. woops.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@11453 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/export')
-rw-r--r--firmware/export/enc_base.h270
-rw-r--r--firmware/export/general.h38
-rw-r--r--firmware/export/pcm_sampr.h310
3 files changed, 618 insertions, 0 deletions
diff --git a/firmware/export/enc_base.h b/firmware/export/enc_base.h
new file mode 100644
index 0000000..85101ac
--- /dev/null
+++ b/firmware/export/enc_base.h
@@ -0,0 +1,270 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Base declarations for working with software encoders
+ *
+ * Copyright (C) 2006 Michael Sevakis
+ *
+ * All files in this archive are subject to the GNU General Public License.
+ * See the file COPYING in the source tree root for full license agreement.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+
+#ifndef ENC_BASE_H
+#define ENC_BASE_H
+
+/** encoder config structures **/
+
+/** mp3_enc.codec **/
+#define MP3_BITR_CAP_8 (1 << 0)
+#define MP3_BITR_CAP_16 (1 << 1)
+#define MP3_BITR_CAP_24 (1 << 2)
+#define MP3_BITR_CAP_32 (1 << 3)
+#define MP3_BITR_CAP_40 (1 << 4)
+#define MP3_BITR_CAP_48 (1 << 5)
+#define MP3_BITR_CAP_56 (1 << 6)
+#define MP3_BITR_CAP_64 (1 << 7)
+#define MP3_BITR_CAP_80 (1 << 8)
+#define MP3_BITR_CAP_96 (1 << 9)
+#define MP3_BITR_CAP_112 (1 << 10)
+#define MP3_BITR_CAP_128 (1 << 11)
+#define MP3_BITR_CAP_144 (1 << 12)
+#define MP3_BITR_CAP_160 (1 << 13)
+#define MP3_BITR_CAP_192 (1 << 14)
+#define MP3_BITR_CAP_224 (1 << 15)
+#define MP3_BITR_CAP_256 (1 << 16)
+#define MP3_BITR_CAP_320 (1 << 17)
+#define MP3_ENC_NUM_BITR 18
+
+/* MPEG 1 */
+#define MPEG1_SAMPR_CAPS (SAMPR_CAP_32 | SAMPR_CAP_48 | SAMPR_CAP_44)
+#define MPEG1_BITR_CAPS (MP3_BITR_CAP_32 | MP3_BITR_CAP_40 | MP3_BITR_CAP_48 | \
+ MP3_BITR_CAP_56 | MP3_BITR_CAP_64 | MP3_BITR_CAP_80 | \
+ MP3_BITR_CAP_96 | MP3_BITR_CAP_112 | MP3_BITR_CAP_128 | \
+ MP3_BITR_CAP_160 | MP3_BITR_CAP_192 | MP3_BITR_CAP_224 | \
+ MP3_BITR_CAP_256 | MP3_BITR_CAP_320)
+
+/* MPEG 2 */
+#define MPEG2_SAMPR_CAPS (SAMPR_CAP_22 | SAMPR_CAP_24 | SAMPR_CAP_16)
+#define MPEG2_BITR_CAPS (MP3_BITR_CAP_8 | MP3_BITR_CAP_16 | MP3_BITR_CAP_24 | \
+ MP3_BITR_CAP_32 | MP3_BITR_CAP_40 | MP3_BITR_CAP_48 | \
+ MP3_BITR_CAP_56 | MP3_BITR_CAP_64 | MP3_BITR_CAP_80 | \
+ MP3_BITR_CAP_96 | MP3_BITR_CAP_112 | MP3_BITR_CAP_128 | \
+ MP3_BITR_CAP_144 | MP3_BITR_CAP_160)
+
+#if 0
+/* MPEG 2.5 */
+#define MPEG2_5_SAMPR_CAPS (SAMPR_CAP_8 | SAMPR_CAP_12 | SAMPR_CAP_11)
+#define MPEG2_5_BITR_CAPS MPEG2_BITR_CAPS
+#endif
+
+/* Assume 44100 is always available and therefore MPEG1 */
+
+/* HAVE_MPEG* defines mainly apply to the bitrate menu */
+#if (REC_SAMPR_CAPS & MPEG2_SAMPR_CAPS) || defined (HAVE_SPDIF_IN)
+#define HAVE_MPEG2_SAMPR
+#endif
+
+#if 0
+#if (REC_SAMPR_CAPS & MPEG2_5_SAMPR_CAPS) || defined (HAVE_SPDIF_IN)
+#define HAVE_MPEG2_5_SAMPR
+#endif
+#endif /* 0 */
+
+#define MP3_ENC_SAMPR_CAPS (MPEG1_SAMPR_CAPS | MPEG2_SAMPR_CAPS)
+
+/* This number is count of full encoder set */
+#define MP3_ENC_NUM_SAMPR 6
+
+extern const unsigned long mp3_enc_sampr[MP3_ENC_NUM_SAMPR];
+extern const unsigned long mp3_enc_bitr[MP3_ENC_NUM_BITR];
+
+struct mp3_enc_config
+{
+ unsigned long bitrate;
+};
+
+#define MP3_ENC_BITRATE_CFG_DEFAULT 11 /* 128 */
+#define MP3_ENC_BITRATE_CFG_VALUE_LIST "8,16,24,32,40,48,56,64,80,96," \
+ "112,128,144,160,192,224,256,320"
+
+/** wav_enc.codec **/
+#define WAV_ENC_SAMPR_CAPS SAMPR_CAP_ALL
+
+struct wav_enc_config
+{
+#if 0
+ unsigned long sample_depth;
+#endif
+};
+
+/** wavpack_enc.codec **/
+#define WAVPACK_ENC_SAMPR_CAPS SAMPR_CAP_ALL
+
+struct wavpack_enc_config
+{
+#if 0
+ unsigned long sample_depth;
+#endif
+};
+
+struct encoder_config
+{
+ union
+ {
+ /* states which *_enc_config member is valid */
+ int rec_format; /* REC_FORMAT_* value */
+ int afmt; /* AFMT_* value */
+ };
+
+ union
+ {
+ struct mp3_enc_config mp3_enc;
+ struct wavpack_enc_config wavpack_enc;
+ struct wav_enc_config wav_enc;
+ };
+};
+
+/** Encoder chunk macros and definitions **/
+#define CHUNKF_START_FILE 0x0001 /* This chunk starts a new file */
+#define CHUNKF_END_FILE 0x0002 /* This chunk ends the current file */
+#define CHUNKF_PRERECORD 0x0010 /* This chunk is prerecord data,
+ a new file could start anytime */
+#define CHUNKF_ABORT 0x0020 /* Encoder should not finish this
+ chunk */
+#define CHUNKF_ERROR 0x80000000 /* An error has occured (passed to/
+ from encoder). Use the sign bit to
+ check (long)flags < 0. */
+
+/* Header at the beginning of every encoder chunk */
+struct enc_chunk_hdr
+{
+ unsigned long flags; /* in/out: flags used by encoder and file
+ writing */
+ size_t enc_size; /* out: amount of encoder data written to
+ chunk */
+ unsigned long num_pcm; /* out: number of PCM samples eaten during
+ processing
+ (<= size of allocated buffer) */
+ unsigned char *enc_data; /* out: pointer to enc_size_written bytes
+ of encoded audio data in chunk */
+ /* Encoder defined data follows header. Can be audio data + any other
+ stuff the encoder needs to handle on a per chunk basis */
+};
+
+/* Paranoia: be sure header size is 4-byte aligned */
+#define ENC_CHUNK_HDR_SIZE \
+ ALIGN_UP_P2(sizeof (struct enc_chunk_hdr), 2)
+/* Skip the chunk header and return data */
+#define ENC_CHUNK_SKIP_HDR(t, hdr) \
+ ((typeof (t))((char *)hdr + ENC_CHUNK_HDR_SIZE))
+/* Cast p to struct enc_chunk_hdr * */
+#define ENC_CHUNK_HDR(p) \
+ ((struct enc_chunk_hdr *)(p))
+
+enum enc_events
+{
+ /* File writing events - data points to enc_file_event_data */
+ ENC_START_FILE = 0, /* a new file has been opened and no data has yet
+ been written */
+ ENC_WRITE_CHUNK, /* write the current chunk to disk */
+ ENC_END_FILE, /* current file about to be closed and all valid
+ data has been written */
+ /* Encoder buffer events - data points to enc_buffer_event_data */
+ ENC_REC_NEW_STREAM, /* Take steps to finish current stream and start
+ new */
+};
+
+/**
+ * encoder can write extra data to the file such as headers or more encoded
+ * samples and must update sizes and samples accordingly.
+ */
+struct enc_file_event_data
+{
+ struct enc_chunk_hdr *chunk; /* Current chunk */
+ size_t new_enc_size; /* New size of chunk */
+ unsigned long new_num_pcm; /* New number of pcm in chunk */
+ const char *filename; /* filename to open if ENC_START_FILE */
+ int rec_file; /* Current file or < 0 if none */
+ unsigned long num_pcm_samples; /* Current pcm sample count written to
+ file so far. */
+};
+
+/**
+ * encoder may add some data to the end of the last and start of the next
+ * but must never yield when called so any encoding done should be absolutely
+ * minimal.
+ */
+struct enc_buffer_event_data
+{
+ unsigned long flags; /* in: One or more of:
+ * CHUNKF_PRERECORD
+ * CHUNKF_END_FILE
+ * CHUNKF_START_FILE
+ */
+ struct enc_chunk_hdr *pre_chunk; /* in: pointer to first prerecord
+ * chunk
+ */
+ struct enc_chunk_hdr *chunk; /* in,out: chunk were split occurs -
+ * first chunk of start
+ */
+};
+
+/** Callbacks called by encoder codec **/
+
+/* parameters passed to encoder by enc_get_inputs */
+struct enc_inputs
+{
+ unsigned long sample_rate; /* out - pcm frequency */
+ int num_channels; /* out - number of audio channels */
+ struct encoder_config *config; /* out - encoder settings */
+};
+
+void enc_get_inputs(struct enc_inputs *inputs);
+
+/* parameters pass from encoder to enc_set_parameters */
+struct enc_parameters
+{
+ /* IN parameters */
+ int afmt; /* AFMT_* id - sanity checker */
+ size_t chunk_size; /* max chunk size required */
+ unsigned long enc_sample_rate; /* actual sample rate used by encoder
+ (for recorded time calculation) */
+ size_t reserve_bytes; /* number of bytes to reserve immediately
+ following chunks */
+ void (*events_callback)(enum enc_events event,
+ void *data); /* pointer to events callback */
+ /* OUT parameters */
+ unsigned char *enc_buffer; /* pointer to enc_buffer */
+ size_t buf_chunk_size; /* size of chunks in enc_buffer */
+ int num_chunks; /* number of chunks allotted to encoder */
+ unsigned char *reserve_buffer; /* pointer to reserve_bytes bytes */
+};
+
+/* set the encoder dimensions - called by encoder codec at initialization
+ and termination */
+void enc_set_parameters(struct enc_parameters *params);
+/* returns pointer to next write chunk in circular buffer */
+struct enc_chunk_hdr * enc_get_chunk(void);
+/* releases the current chunk into the available chunks */
+void enc_finish_chunk(void);
+/* checks near empty state on pcm input buffer */
+int enc_pcm_buf_near_empty(void);
+
+#define PCM_MAX_FEED_SIZE 20000 /* max pcm size passed to encoder */
+
+/* passes a pointer to next chunk of unprocessed wav data */
+unsigned char * enc_get_pcm_data(size_t size);
+/* puts some pcm data back in the queue */
+size_t enc_unget_pcm_data(size_t size);
+
+#endif /* ENC_BASE_H */
diff --git a/firmware/export/general.h b/firmware/export/general.h
new file mode 100644
index 0000000..427e277
--- /dev/null
+++ b/firmware/export/general.h
@@ -0,0 +1,38 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2006 by Michael Sevakis
+ *
+ * All files in this archive are subject to the GNU General Public License.
+ * See the file COPYING in the source tree root for full license agreement.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+
+#ifndef GENERAL_H
+#define GENERAL_H
+
+#include <stdbool.h>
+
+/* round a signed/unsigned 32bit value to the closest of a list of values */
+/* returns the index of the closest value */
+int round_value_to_list32(unsigned long value,
+ const unsigned long list[],
+ int count,
+ bool signd);
+
+int make_list_from_caps32(unsigned long src_mask,
+ const unsigned long *src_list,
+ unsigned long caps_mask,
+ unsigned long *caps_list);
+
+
+#endif /* GENERAL_H */
diff --git a/firmware/export/pcm_sampr.h b/firmware/export/pcm_sampr.h
new file mode 100644
index 0000000..c4a399b
--- /dev/null
+++ b/firmware/export/pcm_sampr.h
@@ -0,0 +1,310 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2006 by Michael Sevakis
+ *
+ * All files in this archive are subject to the GNU General Public License.
+ * See the file COPYING in the source tree root for full license agreement.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+
+#ifndef PCM_SAMPR_H
+#define PCM_SAMPR_H
+
+/* These must be macros for comparison with SAMPR_CAP_* flags by the
+ preprocessor. Add samplerate index in descending order renumbering
+ the ones later in the list if any */
+#define FREQ_96 0
+#define FREQ_88 1
+#define FREQ_64 2
+#define FREQ_48 3
+#define FREQ_44 4
+#define FREQ_32 5
+#define FREQ_24 6
+#define FREQ_22 7
+#define FREQ_16 8
+#define FREQ_12 9
+#define FREQ_11 10
+#define FREQ_8 11
+#define SAMPR_NUM_FREQ 12
+
+/* sample rate values in HZ */
+#define SAMPR_96 96000
+#define SAMPR_88 88200
+#define SAMPR_64 64000
+#define SAMPR_48 48000
+#define SAMPR_44 44100
+#define SAMPR_32 32000
+#define SAMPR_24 24000
+#define SAMPR_22 22050
+#define SAMPR_16 16000
+#define SAMPR_12 12000
+#define SAMPR_11 11025
+#define SAMPR_8 8000
+
+/* sample rate capability bits */
+#define SAMPR_CAP_96 (1 << FREQ_96)
+#define SAMPR_CAP_88 (1 << FREQ_88)
+#define SAMPR_CAP_64 (1 << FREQ_64)
+#define SAMPR_CAP_48 (1 << FREQ_48)
+#define SAMPR_CAP_44 (1 << FREQ_44)
+#define SAMPR_CAP_32 (1 << FREQ_32)
+#define SAMPR_CAP_24 (1 << FREQ_24)
+#define SAMPR_CAP_22 (1 << FREQ_22)
+#define SAMPR_CAP_16 (1 << FREQ_16)
+#define SAMPR_CAP_12 (1 << FREQ_12)
+#define SAMPR_CAP_11 (1 << FREQ_11)
+#define SAMPR_CAP_8 (1 << FREQ_8)
+#define SAMPR_CAP_ALL (SAMPR_CAP_96 | SAMPR_CAP_88 | SAMPR_CAP_64 | \
+ SAMPR_CAP_48 | SAMPR_CAP_44 | SAMPR_CAP_32 | \
+ SAMPR_CAP_24 | SAMPR_CAP_22 | SAMPR_CAP_16 | \
+ SAMPR_CAP_12 | SAMPR_CAP_11 | SAMPR_CAP_8)
+
+/* Master list of all "standard" rates supported. */
+extern const unsigned long audio_master_sampr_list[SAMPR_NUM_FREQ];
+
+/** Hardware sample rates **/
+
+/* Enumeration of supported frequencies where 0 is the highest rate
+ supported and REC_NUM_FREQUENCIES is the number available */
+enum hw_freq_indexes
+{
+ __HW_FREQ_START_INDEX = -1, /* Make sure first in list is 0 */
+
+/* 96000 */
+#if (HW_SAMPR_CAPS & SAMPR_CAP_96) /* Macros and enums for each FREQ: */
+ HW_FREQ_96, /* Index in enumeration */
+#define HW_HAVE_96 /* Defined if this FREQ is defined */
+#define HW_HAVE_96_(...) __VA_ARGS__ /* Output its parameters for this FREQ */
+#else
+#define HW_HAVE_96_(...) /* Discards its parameters for this FREQ */
+#endif
+/* 88200 */
+#if (HW_SAMPR_CAPS & SAMPR_CAP_88)
+ HW_FREQ_88,
+#define HW_HAVE_88
+#define HW_HAVE_88_(...) __VA_ARGS__
+#else
+#define HW_HAVE_88_(...)
+#endif
+/* 64000 */
+#if (HW_SAMPR_CAPS & SAMPR_CAP_64)
+ HW_FREQ_64,
+#define HW_HAVE_64
+#define HW_HAVE_64_(...) __VA_ARGS__
+#else
+#define HW_HAVE_64_(...)
+#endif
+/* 48000 */
+#if (HW_SAMPR_CAPS & SAMPR_CAP_48)
+ HW_FREQ_48,
+#define HW_HAVE_48
+#define HW_HAVE_48_(...) __VA_ARGS__
+#else
+#define HW_HAVE_48_(...)
+#endif
+/* 44100 */
+ HW_FREQ_44,
+#define HW_HAVE_44
+#define HW_HAVE_44_(...) __VA_ARGS__
+/* 32000 */
+#if (HW_SAMPR_CAPS & SAMPR_CAP_32)
+ HW_FREQ_32,
+#define HW_HAVE_32
+#define HW_HAVE_32_(...) __VA_ARGS__
+#else
+#define HW_HAVE_32_(...)
+#endif
+/* 24000 */
+#if (HW_SAMPR_CAPS & SAMPR_CAP_24)
+ HW_FREQ_24,
+#define HW_HAVE_24
+#define HW_HAVE_24_(...) __VA_ARGS__
+#else
+#define HW_HAVE_24_(...)
+#endif
+/* 22050 */
+#if (HW_SAMPR_CAPS & SAMPR_CAP_22)
+ HW_FREQ_22,
+#define HW_HAVE_22
+#define HW_HAVE_22_(...) __VA_ARGS__
+#else
+#define HW_HAVE_22_(...)
+#endif
+/* 16000 */
+#if (HW_SAMPR_CAPS & SAMPR_CAP_16)
+ HW_FREQ_16,
+#define HW_HAVE_16
+#define HW_HAVE_16_(...) __VA_ARGS__
+#else
+#define HW_HAVE_16_(...)
+#endif
+/* 12000 */
+#if (HW_SAMPR_CAPS & SAMPR_CAP_12)
+ HW_FREQ_12,
+#define HW_HAVE_12
+#define HW_HAVE_12_(...) __VA_ARGS__
+#else
+#define HW_HAVE_12_(...)
+#endif
+/* 11025 */
+#if (HW_SAMPR_CAPS & SAMPR_CAP_11)
+ HW_FREQ_11,
+#define HW_HAVE_11
+#define HW_HAVE_11_(...) __VA_ARGS__
+#else
+#define HW_HAVE_11_(...)
+#endif
+/* 8000 */
+#if (HW_SAMPR_CAPS & SAMPR_CAP_8 )
+ HW_FREQ_8,
+#define HW_HAVE_8
+#define HW_HAVE_8_(...) __VA_ARGS__
+#else
+#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];
+
+#ifdef HAVE_RECORDING
+/* Enumeration of supported frequencies where 0 is the highest rate
+ supported and REC_NUM_FREQUENCIES is the number available */
+enum rec_freq_indexes
+{
+ __REC_FREQ_START_INDEX = -1, /* Make sure first in list is 0 */
+
+/* 96000 */
+#if (REC_SAMPR_CAPS & SAMPR_CAP_96) /* Macros and enums for each FREQ: */
+ REC_FREQ_96, /* Index in enumeration */
+#define REC_HAVE_96 /* Defined if this FREQ is defined */
+#define REC_HAVE_96_(...) __VA_ARGS__ /* Output its parameters for this FREQ */
+#else
+#define REC_HAVE_96_(...) /* Discards its parameters for this FREQ */
+#endif
+/* 88200 */
+#if (REC_SAMPR_CAPS & SAMPR_CAP_88)
+ REC_FREQ_88,
+#define REC_HAVE_88
+#define REC_HAVE_88_(...) __VA_ARGS__
+#else
+#define REC_HAVE_88_(...)
+#endif
+/* 64000 */
+#if (REC_SAMPR_CAPS & SAMPR_CAP_64)
+ REC_FREQ_64,
+#define REC_HAVE_64
+#define REC_HAVE_64_(...) __VA_ARGS__
+#else
+#define REC_HAVE_64_(...)
+#endif
+/* 48000 */
+#if (REC_SAMPR_CAPS & SAMPR_CAP_48)
+ REC_FREQ_48,
+#define REC_HAVE_48
+#define REC_HAVE_48_(...) __VA_ARGS__
+#else
+#define REC_HAVE_48_(...)
+#endif
+/* 44100 */
+#if (REC_SAMPR_CAPS & SAMPR_CAP_44)
+ REC_FREQ_44,
+#define REC_HAVE_44
+#define REC_HAVE_44_(...) __VA_ARGS__
+#else
+#define REC_HAVE_44_(...)
+#endif
+/* 32000 */
+#if (REC_SAMPR_CAPS & SAMPR_CAP_32)
+ REC_FREQ_32,
+#define REC_HAVE_32
+#define REC_HAVE_32_(...) __VA_ARGS__
+#else
+#define REC_HAVE_32_(...)
+#endif
+/* 24000 */
+#if (REC_SAMPR_CAPS & SAMPR_CAP_24)
+ REC_FREQ_24,
+#define REC_HAVE_24
+#define REC_HAVE_24_(...) __VA_ARGS__
+#else
+#define REC_HAVE_24_(...)
+#endif
+/* 22050 */
+#if (REC_SAMPR_CAPS & SAMPR_CAP_22)
+ REC_FREQ_22,
+#define REC_HAVE_22
+#define REC_HAVE_22_(...) __VA_ARGS__
+#else
+#define REC_HAVE_22_(...)
+#endif
+/* 16000 */
+#if (REC_SAMPR_CAPS & SAMPR_CAP_16)
+ REC_FREQ_16,
+#define REC_HAVE_16
+#define REC_HAVE_16_(...) __VA_ARGS__
+#else
+#define REC_HAVE_16_(...)
+#endif
+/* 12000 */
+#if (REC_SAMPR_CAPS & SAMPR_CAP_12)
+ REC_FREQ_12,
+#define REC_HAVE_12
+#define REC_HAVE_12_(...) __VA_ARGS__
+#else
+#define REC_HAVE_12_(...)
+#endif
+/* 11025 */
+#if (REC_SAMPR_CAPS & SAMPR_CAP_11)
+ REC_FREQ_11,
+#define REC_HAVE_11
+#define REC_HAVE_11_(...) __VA_ARGS__
+#else
+#define REC_HAVE_11_(...)
+#endif
+/* 8000 */
+#if (REC_SAMPR_CAPS & SAMPR_CAP_8 )
+ REC_FREQ_8,
+#define REC_HAVE_8
+#define REC_HAVE_8_(...) __VA_ARGS__
+#else
+#define REC_HAVE_8_(...)
+#endif
+ REC_NUM_FREQ,
+ /* This should always come out I reckon */
+ REC_FREQ_DEFAULT = REC_FREQ_44,
+ /* Get the minimum bitcount needed to save the range of values */
+ REC_FREQ_CFG_NUM_BITS = (REC_NUM_FREQ > 8 ?
+ 4 : (REC_NUM_FREQ > 4 ?
+ 3 : (REC_NUM_FREQ > 2 ?
+ 2 : 1
+ )
+ )
+ ),
+}; /* enum rec_freq_indexes */
+
+#define REC_FREQ_CFG_VAL_LIST &REC_HAVE_96_(",96") REC_HAVE_88_(",88") \
+ REC_HAVE_64_(",64") REC_HAVE_48_(",48") \
+ REC_HAVE_44_(",44") REC_HAVE_32_(",32") \
+ REC_HAVE_24_(",24") REC_HAVE_22_(",22") \
+ 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 */
+
+#endif /* PCM_SAMPR_H */