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.