summaryrefslogtreecommitdiff
path: root/firmware/export/enc_base.h
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/export/enc_base.h')
-rw-r--r--firmware/export/enc_base.h204
1 files changed, 72 insertions, 132 deletions
diff --git a/firmware/export/enc_base.h b/firmware/export/enc_base.h
index f5dfb65f2a..7228dc4c83 100644
--- a/firmware/export/enc_base.h
+++ b/firmware/export/enc_base.h
@@ -9,7 +9,7 @@
9 * 9 *
10 * Base declarations for working with software encoders 10 * Base declarations for working with software encoders
11 * 11 *
12 * Copyright (C) 2006 Michael Sevakis 12 * Copyright (C) 2006-2013 Michael Sevakis
13 * 13 *
14 * This program is free software; you can redistribute it and/or 14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License 15 * modify it under the terms of the GNU General Public License
@@ -24,7 +24,9 @@
24#ifndef ENC_BASE_H 24#ifndef ENC_BASE_H
25#define ENC_BASE_H 25#define ENC_BASE_H
26 26
27/** encoder config structures **/ 27#include <sys/types.h>
28
29/** Encoder config structures **/
28 30
29/** aiff_enc.codec **/ 31/** aiff_enc.codec **/
30struct aiff_enc_config 32struct aiff_enc_config
@@ -57,18 +59,22 @@ struct aiff_enc_config
57 59
58/* MPEG 1 */ 60/* MPEG 1 */
59#define MPEG1_SAMPR_CAPS (SAMPR_CAP_32 | SAMPR_CAP_48 | SAMPR_CAP_44) 61#define MPEG1_SAMPR_CAPS (SAMPR_CAP_32 | SAMPR_CAP_48 | SAMPR_CAP_44)
60#define MPEG1_BITR_CAPS (MP3_BITR_CAP_32 | MP3_BITR_CAP_40 | MP3_BITR_CAP_48 | \ 62#define MPEG1_BITR_CAPS (MP3_BITR_CAP_32 | MP3_BITR_CAP_40 | \
61 MP3_BITR_CAP_56 | MP3_BITR_CAP_64 | MP3_BITR_CAP_80 | \ 63 MP3_BITR_CAP_48 | MP3_BITR_CAP_56 | \
62 MP3_BITR_CAP_96 | MP3_BITR_CAP_112 | MP3_BITR_CAP_128 | \ 64 MP3_BITR_CAP_64 | MP3_BITR_CAP_80 | \
63 MP3_BITR_CAP_160 | MP3_BITR_CAP_192 | MP3_BITR_CAP_224 | \ 65 MP3_BITR_CAP_96 | MP3_BITR_CAP_112 | \
66 MP3_BITR_CAP_128 | MP3_BITR_CAP_160 | \
67 MP3_BITR_CAP_192 | MP3_BITR_CAP_224 | \
64 MP3_BITR_CAP_256 | MP3_BITR_CAP_320) 68 MP3_BITR_CAP_256 | MP3_BITR_CAP_320)
65 69
66/* MPEG 2 */ 70/* MPEG 2 */
67#define MPEG2_SAMPR_CAPS (SAMPR_CAP_22 | SAMPR_CAP_24 | SAMPR_CAP_16) 71#define MPEG2_SAMPR_CAPS (SAMPR_CAP_22 | SAMPR_CAP_24 | SAMPR_CAP_16)
68#define MPEG2_BITR_CAPS (MP3_BITR_CAP_8 | MP3_BITR_CAP_16 | MP3_BITR_CAP_24 | \ 72#define MPEG2_BITR_CAPS (MP3_BITR_CAP_8 | MP3_BITR_CAP_16 | \
69 MP3_BITR_CAP_32 | MP3_BITR_CAP_40 | MP3_BITR_CAP_48 | \ 73 MP3_BITR_CAP_24 | MP3_BITR_CAP_32 | \
70 MP3_BITR_CAP_56 | MP3_BITR_CAP_64 | MP3_BITR_CAP_80 | \ 74 MP3_BITR_CAP_40 | MP3_BITR_CAP_48 | \
71 MP3_BITR_CAP_96 | MP3_BITR_CAP_112 | MP3_BITR_CAP_128 | \ 75 MP3_BITR_CAP_56 | MP3_BITR_CAP_64 | \
76 MP3_BITR_CAP_80 | MP3_BITR_CAP_96 | \
77 MP3_BITR_CAP_112 | MP3_BITR_CAP_128 | \
72 MP3_BITR_CAP_144 | MP3_BITR_CAP_160) 78 MP3_BITR_CAP_144 | MP3_BITR_CAP_160)
73 79
74#if 0 80#if 0
@@ -131,6 +137,7 @@ struct wavpack_enc_config
131#endif 137#endif
132}; 138};
133 139
140/* General config information about any encoder */
134struct encoder_config 141struct encoder_config
135{ 142{
136 union 143 union
@@ -149,144 +156,77 @@ struct encoder_config
149}; 156};
150 157
151/** Encoder chunk macros and definitions **/ 158/** Encoder chunk macros and definitions **/
152#define CHUNKF_START_FILE 0x0001ul /* This chunk starts a new file */
153#define CHUNKF_END_FILE 0x0002ul /* This chunk ends the current file */
154#define CHUNKF_PRERECORD 0x0010ul /* This chunk is prerecord data,
155 a new file could start anytime */
156#define CHUNKF_ABORT 0x0020ul /* Encoder should not finish this
157 chunk */
158#define CHUNKF_ERROR (~0ul ^ (~0ul >> 1)) /* An error has occured
159 (passed to/from encoder). Use the
160 sign bit to check (long)flags < 0. */
161#define CHUNKF_ALLFLAGS (0x0033ul | CHUNKF_ERROR)
162
163/* Header at the beginning of every encoder chunk */
164#ifdef DEBUG
165#define H_TO_BE32 htobe32
166#define ENC_CHUNK_MAGIC H_TO_BE32(('P' << 24) | ('T' << 16) | ('Y' << 8) | 'R')
167#endif
168struct enc_chunk_hdr
169{
170#ifdef DEBUG
171 unsigned long id; /* overflow detection - 'PTYR' - acronym for
172 "PTYR Tells You Right" ;) */
173#endif
174 unsigned long flags; /* in/out: flags used by encoder and file
175 writing */
176 size_t enc_size; /* out: amount of encoder data written to
177 chunk */
178 unsigned long num_pcm; /* out: number of PCM samples eaten during
179 processing
180 (<= size of allocated buffer) */
181 unsigned char *enc_data; /* out: pointer to enc_size_written bytes
182 of encoded audio data in chunk */
183 /* Encoder defined data follows header. Can be audio data + any other
184 stuff the encoder needs to handle on a per chunk basis */
185};
186 159
187/* Paranoia: be sure header size is 4-byte aligned */ 160/* What sort of data does the header describe? */
188#define ENC_CHUNK_HDR_SIZE \ 161enum CHUNK_T
189 ALIGN_UP_P2(sizeof (struct enc_chunk_hdr), 2)
190/* Skip the chunk header and return data */
191#define ENC_CHUNK_SKIP_HDR(t, hdr) \
192 ((typeof (t))((char *)hdr + ENC_CHUNK_HDR_SIZE))
193/* Cast p to struct enc_chunk_hdr * */
194#define ENC_CHUNK_HDR(p) \
195 ((struct enc_chunk_hdr *)(p))
196
197enum enc_events
198{ 162{
199 /* File writing events - data points to enc_file_event_data */ 163 CHUNK_T_DATA = 0x0, /* Encoded audio data */
200 ENC_START_FILE = 0, /* a new file has been opened and no data has yet 164 CHUNK_T_STREAM_START = 0x1, /* Stream start marker */
201 been written */ 165 CHUNK_T_STREAM_END = 0x2, /* Stream end marker */
202 ENC_WRITE_CHUNK, /* write the current chunk to disk */ 166 CHUNK_T_WRAP = 0x3 /* Buffer early wrap marker */
203 ENC_END_FILE, /* current file about to be closed and all valid
204 data has been written */
205 /* Encoder buffer events - data points to enc_buffer_event_data */
206 ENC_REC_NEW_STREAM, /* Take steps to finish current stream and start
207 new */
208}; 167};
209 168
210/** 169/* Header for every buffer slot and chunk */
211 * encoder can write extra data to the file such as headers or more encoded 170union enc_chunk_hdr
212 * samples and must update sizes and samples accordingly.
213 */
214struct enc_file_event_data
215{ 171{
216 struct enc_chunk_hdr *chunk; /* Current chunk */ 172 struct
217 size_t new_enc_size; /* New size of chunk */ 173 {
218 unsigned long new_num_pcm; /* New number of pcm in chunk */ 174 uint32_t type : 2; /* Chunk type (CHUNK_T_*) */
219 const char *filename; /* filename to open if ENC_START_FILE */ 175 uint32_t err : 1; /* Encoder error */
220 int rec_file; /* Current file or < 0 if none */ 176 uint32_t pre : 1; /* Chunk is prerecorded data */
221 unsigned long num_pcm_samples; /* Current pcm sample count written to 177 uint32_t aux0 : 1; /* Aux flag 0 - for encoder */
222 file so far. */ 178 uint32_t unused : 3; /* */
223}; 179 uint32_t size : 24; /* size of data */
180 };
181 uint32_t zero; /* Zero-out struct access */
182 intptr_t reserved1; /* Want it at least pointer-sized */
183} __attribute__((__may_alias__));
184
185#define ENC_HDR_SIZE (sizeof (union enc_chunk_hdr))
224 186
225/** 187/* When hdr.type is CHUNK_T_STREAM_START */
226 * encoder may add some data to the end of the last and start of the next 188struct enc_chunk_file
227 * but must never yield when called so any encoding done should be absolutely
228 * minimal.
229 */
230struct enc_buffer_event_data
231{ 189{
232 unsigned long flags; /* in: One or more of: 190 union enc_chunk_hdr hdr; /* This chunk's header */
233 * CHUNKF_PRERECORD 191 /* hdr.size = slot count of chunk */
234 * CHUNKF_END_FILE 192 char path[]; /* NULL-terminated path of file */
235 * CHUNKF_START_FILE 193} __attribute__((__may_alias__));
236 */
237 struct enc_chunk_hdr *pre_chunk; /* in: pointer to first prerecord
238 * chunk
239 */
240 struct enc_chunk_hdr *chunk; /* in,out: chunk were split occurs -
241 * first chunk of start
242 */
243};
244 194
245/** Callbacks called by encoder codec **/ 195/* If flags = CHUNK_T_STREAM_END, just the header exists */
246 196
247/* parameters passed to encoder by enc_get_inputs */ 197/* When hdr.type is CHUNK_T_DATA */
248struct enc_inputs 198struct enc_chunk_data
249{ 199{
250 unsigned long sample_rate; /* out - pcm frequency */ 200 union enc_chunk_hdr hdr; /* IN,OUT: This chunk's header */
251 int num_channels; /* out - number of audio channels */ 201 /* hdr.size = total size of data[] */
252 int rec_mono_mode; /* out - how to create mono */ 202 uint32_t pcm_count; /* OUT: number of PCM samples encoded */
253 struct encoder_config *config; /* out - encoder settings */ 203 uint8_t data[]; /* OUT: encoded audio data */
254}; 204} __attribute__((__may_alias__));
255 205
256void enc_get_inputs(struct enc_inputs *inputs); 206/* CHUNK_T_STREAM_END and CHUNK_T_WRAP consist of only the header */
257 207
258/* parameters pass from encoder to enc_set_parameters */ 208#define ENC_FILE_HDR(hdr) ((struct enc_chunk_file *)(hdr))
259struct enc_parameters 209#define ENC_DATA_HDR(hdr) ((struct enc_chunk_data *)(hdr))
210
211/* Audio and encoder stream parameters */
212struct enc_inputs
260{ 213{
261 /* IN parameters */ 214 /* IN parameters */
262 int afmt; /* AFMT_* id - sanity checker */ 215 unsigned long sample_rate; /* PCM samplerate setting */
263 size_t chunk_size; /* max chunk size required */ 216 int num_channels; /* Number of audio channels */
264 unsigned long enc_sample_rate; /* actual sample rate used by encoder 217 struct encoder_config *config; /* Encoder settings */
265 (for recorded time calculation) */
266 size_t reserve_bytes; /* number of bytes to reserve immediately
267 following chunks */
268 void (*events_callback)(enum enc_events event,
269 void *data); /* pointer to events callback */
270 /* OUT parameters */
271 unsigned char *enc_buffer; /* pointer to enc_buffer */
272 size_t buf_chunk_size; /* size of chunks in enc_buffer */
273 int num_chunks; /* number of chunks allotted to encoder */
274 unsigned char *reserve_buffer; /* pointer to reserve_bytes bytes */
275};
276 218
277/* set the encoder dimensions - called by encoder codec at initialization 219 /* IN,OUT parameters */
278 and termination */ 220 unsigned long enc_sample_rate; /* Actual sample rate accepted by encoder
279void enc_set_parameters(struct enc_parameters *params); 221 (for recorded time calculation) */
280/* returns pointer to next write chunk in circular buffer */ 222};
281struct enc_chunk_hdr * enc_get_chunk(void);
282/* releases the current chunk into the available chunks */
283void enc_finish_chunk(void);
284 223
285#define PCM_MAX_FEED_SIZE 20000 /* max pcm size passed to encoder */ 224enum enc_callback_reason
225{
226 ENC_CB_INPUTS, /* 'params' is struct enc_inputs * */
227 ENC_CB_STREAM, /* 'params' is union enc_chunk_hdr * */
228};
286 229
287/* passes a pointer to next chunk of unprocessed wav data */ 230typedef int (* enc_callback_t)(enum enc_callback_reason reason, void *params);
288unsigned char * enc_get_pcm_data(size_t size);
289/* puts some pcm data back in the queue */
290size_t enc_unget_pcm_data(size_t size);
291 231
292#endif /* ENC_BASE_H */ 232#endif /* ENC_BASE_H */