diff options
Diffstat (limited to 'firmware/export/enc_base.h')
-rw-r--r-- | firmware/export/enc_base.h | 270 |
1 files changed, 270 insertions, 0 deletions
diff --git a/firmware/export/enc_base.h b/firmware/export/enc_base.h new file mode 100644 index 0000000000..85101ac7fd --- /dev/null +++ b/firmware/export/enc_base.h | |||
@@ -0,0 +1,270 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Base declarations for working with software encoders | ||
11 | * | ||
12 | * Copyright (C) 2006 Michael Sevakis | ||
13 | * | ||
14 | * All files in this archive are subject to the GNU General Public License. | ||
15 | * See the file COPYING in the source tree root for full license agreement. | ||
16 | * | ||
17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
18 | * KIND, either express or implied. | ||
19 | * | ||
20 | ****************************************************************************/ | ||
21 | |||
22 | #ifndef ENC_BASE_H | ||
23 | #define ENC_BASE_H | ||
24 | |||
25 | /** encoder config structures **/ | ||
26 | |||
27 | /** mp3_enc.codec **/ | ||
28 | #define MP3_BITR_CAP_8 (1 << 0) | ||
29 | #define MP3_BITR_CAP_16 (1 << 1) | ||
30 | #define MP3_BITR_CAP_24 (1 << 2) | ||
31 | #define MP3_BITR_CAP_32 (1 << 3) | ||
32 | #define MP3_BITR_CAP_40 (1 << 4) | ||
33 | #define MP3_BITR_CAP_48 (1 << 5) | ||
34 | #define MP3_BITR_CAP_56 (1 << 6) | ||
35 | #define MP3_BITR_CAP_64 (1 << 7) | ||
36 | #define MP3_BITR_CAP_80 (1 << 8) | ||
37 | #define MP3_BITR_CAP_96 (1 << 9) | ||
38 | #define MP3_BITR_CAP_112 (1 << 10) | ||
39 | #define MP3_BITR_CAP_128 (1 << 11) | ||
40 | #define MP3_BITR_CAP_144 (1 << 12) | ||
41 | #define MP3_BITR_CAP_160 (1 << 13) | ||
42 | #define MP3_BITR_CAP_192 (1 << 14) | ||
43 | #define MP3_BITR_CAP_224 (1 << 15) | ||
44 | #define MP3_BITR_CAP_256 (1 << 16) | ||
45 | #define MP3_BITR_CAP_320 (1 << 17) | ||
46 | #define MP3_ENC_NUM_BITR 18 | ||
47 | |||
48 | /* MPEG 1 */ | ||
49 | #define MPEG1_SAMPR_CAPS (SAMPR_CAP_32 | SAMPR_CAP_48 | SAMPR_CAP_44) | ||
50 | #define MPEG1_BITR_CAPS (MP3_BITR_CAP_32 | MP3_BITR_CAP_40 | MP3_BITR_CAP_48 | \ | ||
51 | MP3_BITR_CAP_56 | MP3_BITR_CAP_64 | MP3_BITR_CAP_80 | \ | ||
52 | MP3_BITR_CAP_96 | MP3_BITR_CAP_112 | MP3_BITR_CAP_128 | \ | ||
53 | MP3_BITR_CAP_160 | MP3_BITR_CAP_192 | MP3_BITR_CAP_224 | \ | ||
54 | MP3_BITR_CAP_256 | MP3_BITR_CAP_320) | ||
55 | |||
56 | /* MPEG 2 */ | ||
57 | #define MPEG2_SAMPR_CAPS (SAMPR_CAP_22 | SAMPR_CAP_24 | SAMPR_CAP_16) | ||
58 | #define MPEG2_BITR_CAPS (MP3_BITR_CAP_8 | MP3_BITR_CAP_16 | MP3_BITR_CAP_24 | \ | ||
59 | MP3_BITR_CAP_32 | MP3_BITR_CAP_40 | MP3_BITR_CAP_48 | \ | ||
60 | MP3_BITR_CAP_56 | MP3_BITR_CAP_64 | MP3_BITR_CAP_80 | \ | ||
61 | MP3_BITR_CAP_96 | MP3_BITR_CAP_112 | MP3_BITR_CAP_128 | \ | ||
62 | MP3_BITR_CAP_144 | MP3_BITR_CAP_160) | ||
63 | |||
64 | #if 0 | ||
65 | /* MPEG 2.5 */ | ||
66 | #define MPEG2_5_SAMPR_CAPS (SAMPR_CAP_8 | SAMPR_CAP_12 | SAMPR_CAP_11) | ||
67 | #define MPEG2_5_BITR_CAPS MPEG2_BITR_CAPS | ||
68 | #endif | ||
69 | |||
70 | /* Assume 44100 is always available and therefore MPEG1 */ | ||
71 | |||
72 | /* HAVE_MPEG* defines mainly apply to the bitrate menu */ | ||
73 | #if (REC_SAMPR_CAPS & MPEG2_SAMPR_CAPS) || defined (HAVE_SPDIF_IN) | ||
74 | #define HAVE_MPEG2_SAMPR | ||
75 | #endif | ||
76 | |||
77 | #if 0 | ||
78 | #if (REC_SAMPR_CAPS & MPEG2_5_SAMPR_CAPS) || defined (HAVE_SPDIF_IN) | ||
79 | #define HAVE_MPEG2_5_SAMPR | ||
80 | #endif | ||
81 | #endif /* 0 */ | ||
82 | |||
83 | #define MP3_ENC_SAMPR_CAPS (MPEG1_SAMPR_CAPS | MPEG2_SAMPR_CAPS) | ||
84 | |||
85 | /* This number is count of full encoder set */ | ||
86 | #define MP3_ENC_NUM_SAMPR 6 | ||
87 | |||
88 | extern const unsigned long mp3_enc_sampr[MP3_ENC_NUM_SAMPR]; | ||
89 | extern const unsigned long mp3_enc_bitr[MP3_ENC_NUM_BITR]; | ||
90 | |||
91 | struct mp3_enc_config | ||
92 | { | ||
93 | unsigned long bitrate; | ||
94 | }; | ||
95 | |||
96 | #define MP3_ENC_BITRATE_CFG_DEFAULT 11 /* 128 */ | ||
97 | #define MP3_ENC_BITRATE_CFG_VALUE_LIST "8,16,24,32,40,48,56,64,80,96," \ | ||
98 | "112,128,144,160,192,224,256,320" | ||
99 | |||
100 | /** wav_enc.codec **/ | ||
101 | #define WAV_ENC_SAMPR_CAPS SAMPR_CAP_ALL | ||
102 | |||
103 | struct wav_enc_config | ||
104 | { | ||
105 | #if 0 | ||
106 | unsigned long sample_depth; | ||
107 | #endif | ||
108 | }; | ||
109 | |||
110 | /** wavpack_enc.codec **/ | ||
111 | #define WAVPACK_ENC_SAMPR_CAPS SAMPR_CAP_ALL | ||
112 | |||
113 | struct wavpack_enc_config | ||
114 | { | ||
115 | #if 0 | ||
116 | unsigned long sample_depth; | ||
117 | #endif | ||
118 | }; | ||
119 | |||
120 | struct encoder_config | ||
121 | { | ||
122 | union | ||
123 | { | ||
124 | /* states which *_enc_config member is valid */ | ||
125 | int rec_format; /* REC_FORMAT_* value */ | ||
126 | int afmt; /* AFMT_* value */ | ||
127 | }; | ||
128 | |||
129 | union | ||
130 | { | ||
131 | struct mp3_enc_config mp3_enc; | ||
132 | struct wavpack_enc_config wavpack_enc; | ||
133 | struct wav_enc_config wav_enc; | ||
134 | }; | ||
135 | }; | ||
136 | |||
137 | /** Encoder chunk macros and definitions **/ | ||
138 | #define CHUNKF_START_FILE 0x0001 /* This chunk starts a new file */ | ||
139 | #define CHUNKF_END_FILE 0x0002 /* This chunk ends the current file */ | ||
140 | #define CHUNKF_PRERECORD 0x0010 /* This chunk is prerecord data, | ||
141 | a new file could start anytime */ | ||
142 | #define CHUNKF_ABORT 0x0020 /* Encoder should not finish this | ||
143 | chunk */ | ||
144 | #define CHUNKF_ERROR 0x80000000 /* An error has occured (passed to/ | ||
145 | from encoder). Use the sign bit to | ||
146 | check (long)flags < 0. */ | ||
147 | |||
148 | /* Header at the beginning of every encoder chunk */ | ||
149 | struct enc_chunk_hdr | ||
150 | { | ||
151 | unsigned long flags; /* in/out: flags used by encoder and file | ||
152 | writing */ | ||
153 | size_t enc_size; /* out: amount of encoder data written to | ||
154 | chunk */ | ||
155 | unsigned long num_pcm; /* out: number of PCM samples eaten during | ||
156 | processing | ||
157 | (<= size of allocated buffer) */ | ||
158 | unsigned char *enc_data; /* out: pointer to enc_size_written bytes | ||
159 | of encoded audio data in chunk */ | ||
160 | /* Encoder defined data follows header. Can be audio data + any other | ||
161 | stuff the encoder needs to handle on a per chunk basis */ | ||
162 | }; | ||
163 | |||
164 | /* Paranoia: be sure header size is 4-byte aligned */ | ||
165 | #define ENC_CHUNK_HDR_SIZE \ | ||
166 | ALIGN_UP_P2(sizeof (struct enc_chunk_hdr), 2) | ||
167 | /* Skip the chunk header and return data */ | ||
168 | #define ENC_CHUNK_SKIP_HDR(t, hdr) \ | ||
169 | ((typeof (t))((char *)hdr + ENC_CHUNK_HDR_SIZE)) | ||
170 | /* Cast p to struct enc_chunk_hdr * */ | ||
171 | #define ENC_CHUNK_HDR(p) \ | ||
172 | ((struct enc_chunk_hdr *)(p)) | ||
173 | |||
174 | enum enc_events | ||
175 | { | ||
176 | /* File writing events - data points to enc_file_event_data */ | ||
177 | ENC_START_FILE = 0, /* a new file has been opened and no data has yet | ||
178 | been written */ | ||
179 | ENC_WRITE_CHUNK, /* write the current chunk to disk */ | ||
180 | ENC_END_FILE, /* current file about to be closed and all valid | ||
181 | data has been written */ | ||
182 | /* Encoder buffer events - data points to enc_buffer_event_data */ | ||
183 | ENC_REC_NEW_STREAM, /* Take steps to finish current stream and start | ||
184 | new */ | ||
185 | }; | ||
186 | |||
187 | /** | ||
188 | * encoder can write extra data to the file such as headers or more encoded | ||
189 | * samples and must update sizes and samples accordingly. | ||
190 | */ | ||
191 | struct enc_file_event_data | ||
192 | { | ||
193 | struct enc_chunk_hdr *chunk; /* Current chunk */ | ||
194 | size_t new_enc_size; /* New size of chunk */ | ||
195 | unsigned long new_num_pcm; /* New number of pcm in chunk */ | ||
196 | const char *filename; /* filename to open if ENC_START_FILE */ | ||
197 | int rec_file; /* Current file or < 0 if none */ | ||
198 | unsigned long num_pcm_samples; /* Current pcm sample count written to | ||
199 | file so far. */ | ||
200 | }; | ||
201 | |||
202 | /** | ||
203 | * encoder may add some data to the end of the last and start of the next | ||
204 | * but must never yield when called so any encoding done should be absolutely | ||
205 | * minimal. | ||
206 | */ | ||
207 | struct enc_buffer_event_data | ||
208 | { | ||
209 | unsigned long flags; /* in: One or more of: | ||
210 | * CHUNKF_PRERECORD | ||
211 | * CHUNKF_END_FILE | ||
212 | * CHUNKF_START_FILE | ||
213 | */ | ||
214 | struct enc_chunk_hdr *pre_chunk; /* in: pointer to first prerecord | ||
215 | * chunk | ||
216 | */ | ||
217 | struct enc_chunk_hdr *chunk; /* in,out: chunk were split occurs - | ||
218 | * first chunk of start | ||
219 | */ | ||
220 | }; | ||
221 | |||
222 | /** Callbacks called by encoder codec **/ | ||
223 | |||
224 | /* parameters passed to encoder by enc_get_inputs */ | ||
225 | struct enc_inputs | ||
226 | { | ||
227 | unsigned long sample_rate; /* out - pcm frequency */ | ||
228 | int num_channels; /* out - number of audio channels */ | ||
229 | struct encoder_config *config; /* out - encoder settings */ | ||
230 | }; | ||
231 | |||
232 | void enc_get_inputs(struct enc_inputs *inputs); | ||
233 | |||
234 | /* parameters pass from encoder to enc_set_parameters */ | ||
235 | struct enc_parameters | ||
236 | { | ||
237 | /* IN parameters */ | ||
238 | int afmt; /* AFMT_* id - sanity checker */ | ||
239 | size_t chunk_size; /* max chunk size required */ | ||
240 | unsigned long enc_sample_rate; /* actual sample rate used by encoder | ||
241 | (for recorded time calculation) */ | ||
242 | size_t reserve_bytes; /* number of bytes to reserve immediately | ||
243 | following chunks */ | ||
244 | void (*events_callback)(enum enc_events event, | ||
245 | void *data); /* pointer to events callback */ | ||
246 | /* OUT parameters */ | ||
247 | unsigned char *enc_buffer; /* pointer to enc_buffer */ | ||
248 | size_t buf_chunk_size; /* size of chunks in enc_buffer */ | ||
249 | int num_chunks; /* number of chunks allotted to encoder */ | ||
250 | unsigned char *reserve_buffer; /* pointer to reserve_bytes bytes */ | ||
251 | }; | ||
252 | |||
253 | /* set the encoder dimensions - called by encoder codec at initialization | ||
254 | and termination */ | ||
255 | void enc_set_parameters(struct enc_parameters *params); | ||
256 | /* returns pointer to next write chunk in circular buffer */ | ||
257 | struct enc_chunk_hdr * enc_get_chunk(void); | ||
258 | /* releases the current chunk into the available chunks */ | ||
259 | void enc_finish_chunk(void); | ||
260 | /* checks near empty state on pcm input buffer */ | ||
261 | int enc_pcm_buf_near_empty(void); | ||
262 | |||
263 | #define PCM_MAX_FEED_SIZE 20000 /* max pcm size passed to encoder */ | ||
264 | |||
265 | /* passes a pointer to next chunk of unprocessed wav data */ | ||
266 | unsigned char * enc_get_pcm_data(size_t size); | ||
267 | /* puts some pcm data back in the queue */ | ||
268 | size_t enc_unget_pcm_data(size_t size); | ||
269 | |||
270 | #endif /* ENC_BASE_H */ | ||