diff options
Diffstat (limited to 'firmware')
-rw-r--r-- | firmware/export/audio.h | 5 | ||||
-rw-r--r-- | firmware/export/enc_base.h | 204 |
2 files changed, 73 insertions, 136 deletions
diff --git a/firmware/export/audio.h b/firmware/export/audio.h index 293956cb37..24e8e9a0e7 100644 --- a/firmware/export/audio.h +++ b/firmware/export/audio.h | |||
@@ -212,10 +212,7 @@ unsigned long audio_num_recorded_bytes(void); | |||
212 | 212 | ||
213 | #if CONFIG_CODEC == SWCODEC | 213 | #if CONFIG_CODEC == SWCODEC |
214 | /* SWCODEC recording functions */ | 214 | /* SWCODEC recording functions */ |
215 | /* playback.c */ | 215 | unsigned long audio_prerecorded_time(void); |
216 | bool audio_load_encoder(int afmt); | ||
217 | void audio_remove_encoder(void); | ||
218 | unsigned char *audio_get_recording_buffer(size_t *buffer_size); | ||
219 | #endif /* CONFIG_CODEC == SWCODEC */ | 216 | #endif /* CONFIG_CODEC == SWCODEC */ |
220 | 217 | ||
221 | #endif /* HAVE_RECORDING */ | 218 | #endif /* HAVE_RECORDING */ |
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 **/ |
30 | struct aiff_enc_config | 32 | struct 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 */ | ||
134 | struct encoder_config | 141 | struct 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 | ||
168 | struct 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 \ | 161 | enum 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 | |||
197 | enum 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 | 170 | union enc_chunk_hdr |
212 | * samples and must update sizes and samples accordingly. | ||
213 | */ | ||
214 | struct 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 | 188 | struct enc_chunk_file |
227 | * but must never yield when called so any encoding done should be absolutely | ||
228 | * minimal. | ||
229 | */ | ||
230 | struct 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 */ |
248 | struct enc_inputs | 198 | struct 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 | ||
256 | void 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)) |
259 | struct enc_parameters | 209 | #define ENC_DATA_HDR(hdr) ((struct enc_chunk_data *)(hdr)) |
210 | |||
211 | /* Audio and encoder stream parameters */ | ||
212 | struct 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 |
279 | void enc_set_parameters(struct enc_parameters *params); | 221 | (for recorded time calculation) */ |
280 | /* returns pointer to next write chunk in circular buffer */ | 222 | }; |
281 | struct enc_chunk_hdr * enc_get_chunk(void); | ||
282 | /* releases the current chunk into the available chunks */ | ||
283 | void enc_finish_chunk(void); | ||
284 | 223 | ||
285 | #define PCM_MAX_FEED_SIZE 20000 /* max pcm size passed to encoder */ | 224 | enum 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 */ | 230 | typedef int (* enc_callback_t)(enum enc_callback_reason reason, void *params); |
288 | unsigned char * enc_get_pcm_data(size_t size); | ||
289 | /* puts some pcm data back in the queue */ | ||
290 | size_t enc_unget_pcm_data(size_t size); | ||
291 | 231 | ||
292 | #endif /* ENC_BASE_H */ | 232 | #endif /* ENC_BASE_H */ |