FreeCalypso > hg > gsm-codec-lib
comparison doc/AMR-library-API @ 478:936a08cc73ce
doc/AMR-library-API: describe the decoder
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Sun, 19 May 2024 21:32:31 +0000 |
parents | c84bf526c7eb |
children | 616b7ba1135b |
comparison
equal
deleted
inserted
replaced
477:4c9222d95647 | 478:936a08cc73ce |
---|---|
245 to our first function. | 245 to our first function. |
246 | 246 |
247 After this transformation, call EFR_params2frame() from libgsmefr (see | 247 After this transformation, call EFR_params2frame() from libgsmefr (see |
248 EFR-library-API) with param[] array in struct amr_param_frame as input. | 248 EFR-library-API) with param[] array in struct amr_param_frame as input. |
249 | 249 |
250 Using the AMR decoder | 250 Using the AMR decoder: native interface |
251 ===================== | 251 ======================================= |
252 | 252 |
253 The internal native form of the stateful AMR decoder engine is: | |
254 | |
255 void amr_decode_frame(struct amr_decoder_state *st, | |
256 const struct amr_param_frame *frame, int16_t *pcm); | |
257 | |
258 The input frame is given as struct amr_param_frame, same structure as is used | |
259 for the output of the encoder. However, the required input to | |
260 amr_decode_frame() is different from amr_encode_frame() output: | |
261 | |
262 * The 'type' member of the struct must be a code from enum RXFrameType, *not* | |
263 enum TXFrameType! | |
264 | |
265 * All 3GPP-defined Rx frame types are allowed. | |
266 | |
267 * The 'mode' member of the input struct is ignored if the Rx frame type is | |
268 RX_NO_DATA, but must be valid for every other frame type. | |
269 | |
270 If frame->type is not RX_NO_DATA, frame->mode is interpreted as follows: | |
271 | |
272 * The 3 least significant bits (mask 0x07) are taken to indicate the codec mode | |
273 used for this frame; | |
274 | |
275 * The most significant bit (mask 0x80) has meaning only if the mode is MR122 | |
276 and frame->type is RX_SPEECH_GOOD. Under these conditions, if this bit is | |
277 set, the DHF check is modified to match against the bit pattern of EFR DHF | |
278 instead of regular MR122 DHF. | |
279 | |
280 amr_decode_frame() contains no guards against invalid (undefined) frame types | |
281 in frame->type, or against any of the codec parameters being out of range. | |
282 struct amr_param_frame coming into this function must come only from trusted | |
283 sources inside the application program, usually from one of the provided input | |
284 format conversion functions. | |
285 | |
286 Decoder homing frame check | |
287 -------------------------- | |
288 | |
289 The definition of AMR decoder per 3GPP includes two mandatory checks for the | |
290 possibility of the input frame being one of the defined per-mode decoder homing | |
291 frames (DHFs): one check at the beginning of the decoder, checking only up to | |
292 the first subframe and acting only when the current state is homed, and the | |
293 second check at the end of the decoder, checking all parameters (the full frame) | |
294 and resetting the decoder on match. | |
295 | |
296 This DHF check operation, called from those two places in the stateful decoder | |
297 as just described, is factored out into its own function that is exported as | |
298 part of the public API: | |
299 | |
300 int amr_check_dhf(const struct amr_param_frame *frame, int first_sub_only); | |
301 | |
302 struct amr_param_frame needs to be passed to amr_check_dhf() as if it was | |
303 amr_decode_frame(); the latter function in fact calls amr_check_dhf() on its | |
304 input. The Boolean flag argument (first_sub_only) tells the function to check | |
305 only to the end of the first subframe if nonzero, or check the entire frame if | |
306 zero. The return value is 1 if the input matches DHF, 0 otherwise. | |
307 | |
308 frame->type must be RX_SPEECH_GOOD for the frame to be a DHF candidate, and the | |
309 interpretation of frame->mode, including the special mode of matching against | |
310 EFR DHF, is implemented in this function. | |
311 | |
312 Using the AMR decoder: input preparation | |
313 ======================================== | |
314 | |
315 Stateless utility functions are provided for preparing decoder inputs, | |
316 converting from RFC 4867 or 3GPP test sequence format into the internal form | |
317 described above. | |
318 | |
319 Decoding RFC 4867 input | |
320 ----------------------- | |
321 | |
322 If the entire RFC 4867 frame (read from .amr storage format or received in RTP | |
323 as an octet-aligned payload) is already in memory, decode it with this function: | |
324 | |
325 int amr_frame_from_ietf(const uint8_t *bytes, struct amr_param_frame *frame); | |
326 | |
327 The string of bytes input to this function must begin with the ToC octet. Out | |
328 of this ToC octet, only bits falling under the mask 0x7C (FT and Q bit fields) | |
329 are checked. The remaining 3 bits are not checked: in the case of .amr storage | |
330 format, RFC 4867 describes these bits as "padding" (P bits) and stipulates that | |
331 they MUST be ignored by readers. However, in the case of RTP payloads received | |
332 in a live session, the uppermost bit of the ToC octet becomes F rather than P, | |
333 and it is the responsibility of the application to ensure that F=0: multiframe | |
334 payloads are NOT supported. | |
335 | |
336 FT in the input frame may be [0,7] (MR475 through MR122), 8 (MRDTX) or 15 | |
337 (AMR_FT_NODATA). In all of these cases amr_frame_from_ietf() succeeds and | |
338 returns 0 to indicate so; the resulting struct amr_param_frame is then good to | |
339 be passed to amr_decode_frame(). OTOH, if FT falls into the invalid range of | |
340 [9,14], amr_frame_from_ietf() returns -1 to indicate invalid input. | |
341 | |
342 Applications that read from a .amr file will need to read just the ToC (aka | |
343 frame header) octet and decode it to determine how many additional octets need | |
344 to be read to absorb one frame. Similarly, RTP applications may need to | |
345 validate incoming payloada by cross-checking between the FT indicated in the | |
346 ToC octet and the received payload length. Both applications can use this | |
347 function: | |
348 | |
349 int amr_ietf_grok_first_octet(uint8_t fo); | |
350 | |
351 The argument is the first octet, and the function only considers the FT field | |
352 thereof. The return value is: | |
353 | |
354 -1 for invalid FT [9,14] | |
355 0 for FT=15 (the ToC octet is the entirety of the payload) | |
356 >0 for valid FT [0,8], indicating the number of additional bytes to be read | |
357 | |
358 Decoding 3GPP test sequence input | |
359 --------------------------------- | |
360 | |
361 To decode a frame from 3GPP .cod file format, call this function: | |
362 | |
363 int amr_frame_from_tseq(const uint16_t *cod, int use_rxtype, | |
364 struct amr_param_frame *frame); | |
365 | |
366 The argument 'use_rxtype' should be 1 if the input uses Rx frame types (enum | |
367 RXFrameType) or 0 if it uses Tx frame types (enum TXFrameType); this argument | |
368 directly corresponds to -rxframetype command line option in the reference | |
369 decoder program from 3GPP. | |
370 | |
371 Unlike raw amr_decode_frame(), amr_frame_from_tseq() does guard against invalid | |
372 input. The return value from this function is: | |
373 | |
374 0 means the input was good and the output is good to pass to amr_decode_frame(); | |
375 -1 means the frame type field in the input is invalid; | |
376 -2 means the mode field in the input is invalid. | |
377 | |
378 Frame type conversion | |
379 --------------------- | |
380 | |
381 The operation of mapping from enum TXFrameType to enum RXFrameType, optionally | |
382 but very commonly invoked from amr_frame_from_tseq(), is factored out into its | |
383 own function, exported as part of the public API: | |
384 | |
385 int amr_txtype_to_rxtype(enum TXFrameType tx_type, enum RXFrameType *rx_type); | |
386 | |
387 The return value is 0 if tx_type is valid and *rx_type has been filled | |
388 accordingly, or -1 if tx_type is invalid. |