FreeCalypso > hg > gsm-codec-lib
annotate doc/EFR-library-API @ 242:f081a6850fb5
libgsmfrp: new refined implementation
The previous implementation exhibited the following defects,
which are now fixed:
1) The last received valid SID was cached forever for the purpose of
handling future invalid SIDs - we could have received some valid
SID ages ago, then lots of speech or NO_DATA, and if we then get
an invalid SID, we would resurrect the last valid SID from ancient
history - a bad design. In our new design, we handle invalid SID
based on the current state, much like BFI.
2) GSM 06.11 spec says clearly that after the second lost SID
(received BFI=1 && TAF=1 in CN state) we need to gradually decrease
the output level, rather than jump directly to emitting silence
frames - we previously failed to implement such logic.
3) Per GSM 06.12 section 5.2, Xmaxc should be the same in all 4 subframes
in a SID frame. What should we do if we receive an otherwise valid
SID frame with different Xmaxc? Our previous approach would
replicate this Xmaxc oddity in every subsequent generated CN frame,
which is rather bad. In our new design, the very first CN frame
(which can be seen as a transformation of the SID frame itself)
retains the original 4 distinct Xmaxc, but all subsequent CN frames
are based on the Xmaxc from the last subframe of the most recent SID.
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Tue, 09 May 2023 05:16:31 +0000 |
parents | fe5aceaf51e0 |
children | 9208db14b4b9 |
rev | line source |
---|---|
123
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
1 The external public interface to Themyscira libgsmefr consists of a single |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
2 header file <gsm_efr.h>; it should be installed in the same system include |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
3 directory as <gsm.h> from classic libgsm (1990s free software product) for the |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
4 original FR codec, and the API of libgsmefr is modeled after that of libgsm. |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
5 |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
6 The dialect of C we chose for libgsmefr is ANSI C (function prototypes), const |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
7 qualifier is used where appropriate, and the interface is defined in terms of |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
8 <stdint.h> types; <gsm_efr.h> includes <stdint.h>. |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
9 |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
10 State allocation and freeing |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
11 ============================ |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
12 |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
13 In order to use the EFR encoder, you will need to allocate an encoder state |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
14 structure, and to use the EFR decoder, you will need to allocate a decoder state |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
15 structure. The necessary state allocation functions are: |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
16 |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
17 extern struct EFR_encoder_state *EFR_encoder_create(int dtx); |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
18 extern struct EFR_decoder_state *EFR_decoder_create(void); |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
19 |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
20 struct EFR_encoder_state and struct EFR_decoder_state are opaque structures to |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
21 library users: you only get pointers which you remember and pass around, but |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
22 <gsm_efr.h> does not give you full definitions of these structs. As a library |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
23 user, you don't even get to know the size of these structs, hence the necessary |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
24 malloc() operation happens inside EFR_encoder_create() and EFR_decoder_create(). |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
25 However, each structure is malloc'ed as a single chunk, hence when you are done |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
26 with it, simply call free() to relinquish each encoder or decoder state |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
27 instance. |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
28 |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
29 EFR_encoder_create() and EFR_decoder_create() functions can fail if the malloc() |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
30 call inside fails, in which case the two libgsmefr functions in question return |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
31 NULL. |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
32 |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
33 The dtx argument to EFR_encoder_create() is a Boolean flag represented as an |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
34 int; it tells the EFR encoder whether it should operate with DTX enabled (run |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
35 GSM 06.82 VAD and emit SID frames instead of speech frames per GSM 06.81) or DTX |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
36 disabled (skip VAD and always emit speech frames). |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
37 |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
38 Using the EFR encoder |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
39 ===================== |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
40 |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
41 To encode one 20 ms audio frame per EFR, call EFR_encode_frame(): |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
42 |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
43 extern void EFR_encode_frame(struct EFR_encoder_state *st, const int16_t *pcm, |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
44 uint8_t *frame, int *sp, int *vad); |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
45 |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
46 You need to provide an encoder state structure allocated earlier with |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
47 EFR_encoder_create(), a block of 160 linear PCM samples, and an output buffer of |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
48 31 bytes (EFR_RTP_FRAME_LEN constant also defined in <gsm_efr.h>) into which the |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
49 encoded EFR frame will be written; the frame format is that defined in ETSI TS |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
50 101 318 for EFR in RTP, including the 0xC signature in the upper nibble of the |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
51 first byte. |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
52 |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
53 The last two arguments of type (int *) are optional pointers to extra output |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
54 flags SP and VAD, defined in GSM 06.81 section 5.1.1; either pointer or both of |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
55 them can be NULL if these extra output flags aren't needed. Both of these flags |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
56 are needed in order to test our libgsmefr encoder implementation against |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
57 official ETSI test sequences (GSM 06.54), but they typically aren't needed |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
58 otherwise. |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
59 |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
60 Using the EFR decoder |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
61 ===================== |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
62 |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
63 The main interface to our EFR decoder is this function: |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
64 |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
65 extern void EFR_decode_frame(struct EFR_decoder_state *st, const uint8_t *frame, |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
66 int bfi, int taf, int16_t *pcm); |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
67 |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
68 The inputs consist of 244 bits of frame payload (the 4 upper bits of the first |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
69 byte are ignored - there is NO enforcement of 0xC signature in our frame |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
70 decoder) and BFI and TAF flags defined in GSM 06.81 section 6.1.1. Note the |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
71 absence of a SID flag argument: EFR_decode_frame() calls our own utility |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
72 function EFR_sid_classify() to determine SID from the frame itself per the rules |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
73 of GSM 06.81 section 6.1.1. |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
74 |
161
fe5aceaf51e0
doc/EFR-library-API: document new handling of BFI with no data
Mychaela Falconia <falcon@freecalypso.org>
parents:
130
diff
changeset
|
75 The canonical EFR decoder always expects frame bits input to be present, even |
fe5aceaf51e0
doc/EFR-library-API: document new handling of BFI with no data
Mychaela Falconia <falcon@freecalypso.org>
parents:
130
diff
changeset
|
76 during BFI condtions! More specifically, if a BFI=1 decoding call comes in when |
fe5aceaf51e0
doc/EFR-library-API: document new handling of BFI with no data
Mychaela Falconia <falcon@freecalypso.org>
parents:
130
diff
changeset
|
77 the decoder is in comfort noise generation state (after a SID), then all frame |
fe5aceaf51e0
doc/EFR-library-API: document new handling of BFI with no data
Mychaela Falconia <falcon@freecalypso.org>
parents:
130
diff
changeset
|
78 bits passed along with BFI=1 are ignored as one would naturally expect for |
fe5aceaf51e0
doc/EFR-library-API: document new handling of BFI with no data
Mychaela Falconia <falcon@freecalypso.org>
parents:
130
diff
changeset
|
79 frames that typically aren't transmitted at all - but if a BFI=1 decoding call |
fe5aceaf51e0
doc/EFR-library-API: document new handling of BFI with no data
Mychaela Falconia <falcon@freecalypso.org>
parents:
130
diff
changeset
|
80 comes in when the decoder is in regular speech mode, the canonical decoder will |
fe5aceaf51e0
doc/EFR-library-API: document new handling of BFI with no data
Mychaela Falconia <falcon@freecalypso.org>
parents:
130
diff
changeset
|
81 use the "fixed codebook excitation pulses" part of the erroneous frame (one |
fe5aceaf51e0
doc/EFR-library-API: document new handling of BFI with no data
Mychaela Falconia <falcon@freecalypso.org>
parents:
130
diff
changeset
|
82 declared to be garbage) as part of its decoding operation! (This part |
fe5aceaf51e0
doc/EFR-library-API: document new handling of BFI with no data
Mychaela Falconia <falcon@freecalypso.org>
parents:
130
diff
changeset
|
83 constitutes 35 bits per subframe or 140 bits out of 244 per frame.) |
fe5aceaf51e0
doc/EFR-library-API: document new handling of BFI with no data
Mychaela Falconia <falcon@freecalypso.org>
parents:
130
diff
changeset
|
84 |
fe5aceaf51e0
doc/EFR-library-API: document new handling of BFI with no data
Mychaela Falconia <falcon@freecalypso.org>
parents:
130
diff
changeset
|
85 BFI with no data |
fe5aceaf51e0
doc/EFR-library-API: document new handling of BFI with no data
Mychaela Falconia <falcon@freecalypso.org>
parents:
130
diff
changeset
|
86 ================ |
fe5aceaf51e0
doc/EFR-library-API: document new handling of BFI with no data
Mychaela Falconia <falcon@freecalypso.org>
parents:
130
diff
changeset
|
87 |
fe5aceaf51e0
doc/EFR-library-API: document new handling of BFI with no data
Mychaela Falconia <falcon@freecalypso.org>
parents:
130
diff
changeset
|
88 Many EFR decoder applications will be faced with a situation where they receive |
fe5aceaf51e0
doc/EFR-library-API: document new handling of BFI with no data
Mychaela Falconia <falcon@freecalypso.org>
parents:
130
diff
changeset
|
89 a frame gap (no data at all), and they need to run the EFR decoder with BFI=1 - |
fe5aceaf51e0
doc/EFR-library-API: document new handling of BFI with no data
Mychaela Falconia <falcon@freecalypso.org>
parents:
130
diff
changeset
|
90 but the application doesn't have any frame-bits input. Yet the canonical EFR |
fe5aceaf51e0
doc/EFR-library-API: document new handling of BFI with no data
Mychaela Falconia <falcon@freecalypso.org>
parents:
130
diff
changeset
|
91 decoder requires *some* erroneous frame bits to be fed to it - so what gives? |
fe5aceaf51e0
doc/EFR-library-API: document new handling of BFI with no data
Mychaela Falconia <falcon@freecalypso.org>
parents:
130
diff
changeset
|
92 Our initial approach was to feed the decoder all zeros in the place of codec |
fe5aceaf51e0
doc/EFR-library-API: document new handling of BFI with no data
Mychaela Falconia <falcon@freecalypso.org>
parents:
130
diff
changeset
|
93 parameters - but further analysis reveals that approach to be bad. (To see for |
fe5aceaf51e0
doc/EFR-library-API: document new handling of BFI with no data
Mychaela Falconia <falcon@freecalypso.org>
parents:
130
diff
changeset
|
94 yourself, study the code in d1035pf.c and think what it will do when the input |
fe5aceaf51e0
doc/EFR-library-API: document new handling of BFI with no data
Mychaela Falconia <falcon@freecalypso.org>
parents:
130
diff
changeset
|
95 is fixed at all zeros.) Our new approach is to generate pseudorandom bits for |
fe5aceaf51e0
doc/EFR-library-API: document new handling of BFI with no data
Mychaela Falconia <falcon@freecalypso.org>
parents:
130
diff
changeset
|
96 these pulse parameters, as detailed below. |
fe5aceaf51e0
doc/EFR-library-API: document new handling of BFI with no data
Mychaela Falconia <falcon@freecalypso.org>
parents:
130
diff
changeset
|
97 |
fe5aceaf51e0
doc/EFR-library-API: document new handling of BFI with no data
Mychaela Falconia <falcon@freecalypso.org>
parents:
130
diff
changeset
|
98 If you find yourself in the situation of needing to feed BFI=1 with no frame |
fe5aceaf51e0
doc/EFR-library-API: document new handling of BFI with no data
Mychaela Falconia <falcon@freecalypso.org>
parents:
130
diff
changeset
|
99 data bits to the decoder, call the following function in the place of |
fe5aceaf51e0
doc/EFR-library-API: document new handling of BFI with no data
Mychaela Falconia <falcon@freecalypso.org>
parents:
130
diff
changeset
|
100 EFR_decode_frame(): |
123
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
101 |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
102 extern void EFR_decode_bfi_nodata(struct EFR_decoder_state *st, int taf, |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
103 int16_t *pcm); |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
104 |
161
fe5aceaf51e0
doc/EFR-library-API: document new handling of BFI with no data
Mychaela Falconia <falcon@freecalypso.org>
parents:
130
diff
changeset
|
105 This function begins by checking the internal state flag RX_SP_FLAG, indicating |
fe5aceaf51e0
doc/EFR-library-API: document new handling of BFI with no data
Mychaela Falconia <falcon@freecalypso.org>
parents:
130
diff
changeset
|
106 whether the decoder is in speech or comfort noise generation mode. If |
fe5aceaf51e0
doc/EFR-library-API: document new handling of BFI with no data
Mychaela Falconia <falcon@freecalypso.org>
parents:
130
diff
changeset
|
107 RX_SP_FLAG is set, indicating speech state, then the main body of the decoder |
fe5aceaf51e0
doc/EFR-library-API: document new handling of BFI with no data
Mychaela Falconia <falcon@freecalypso.org>
parents:
130
diff
changeset
|
108 will be making use of fixed codebook pulse parameters even for erroneous frames, |
fe5aceaf51e0
doc/EFR-library-API: document new handling of BFI with no data
Mychaela Falconia <falcon@freecalypso.org>
parents:
130
diff
changeset
|
109 and EFR_decode_bfi_nodata() will invoke a PRNG to fill in pseudorandom bits. |
fe5aceaf51e0
doc/EFR-library-API: document new handling of BFI with no data
Mychaela Falconia <falcon@freecalypso.org>
parents:
130
diff
changeset
|
110 If RX_SP_FLAG is clear, then the decoder is generating comfort noise following |
fe5aceaf51e0
doc/EFR-library-API: document new handling of BFI with no data
Mychaela Falconia <falcon@freecalypso.org>
parents:
130
diff
changeset
|
111 reception of a SID, and BFI conditions are fully expected because the |
fe5aceaf51e0
doc/EFR-library-API: document new handling of BFI with no data
Mychaela Falconia <falcon@freecalypso.org>
parents:
130
diff
changeset
|
112 transmitter is expected to be off. In this case EFR_decode_bfi_nodata() feeds |
fe5aceaf51e0
doc/EFR-library-API: document new handling of BFI with no data
Mychaela Falconia <falcon@freecalypso.org>
parents:
130
diff
changeset
|
113 all-zeros parameters to the main body of the decoder, as none of them will be |
fe5aceaf51e0
doc/EFR-library-API: document new handling of BFI with no data
Mychaela Falconia <falcon@freecalypso.org>
parents:
130
diff
changeset
|
114 used. |
123
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
115 |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
116 Stateless utility functions |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
117 =========================== |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
118 |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
119 All functions in this section are stateless (no encoder state or decoder state |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
120 structure is needed); they merely manipulate bit fields. |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
121 |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
122 extern void EFR_frame2params(const uint8_t *frame, int16_t *params); |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
123 |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
124 This function unpacks an EFR codec frame in ETSI TS 101 318 RTP encoding (the |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
125 upper nibble of the first byte is NOT checked, i.e., there is NO enforcement of |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
126 0xC signature) into an array of 57 (EFR_NUM_PARAMS) parameter words for the |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
127 codec. int16_t signed type is used for the params array (even though all |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
128 parameters are actually unsigned) in order to match the guts of ETSI-based EFR |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
129 codec, and EFR_frame2params() is called internally by EFR_decode_frame(). |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
130 |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
131 extern void EFR_params2frame(const int16_t *params, uint8_t *frame); |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
132 |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
133 This function takes an array of 57 (EFR_NUM_PARAMS) EFR codec parameter words |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
134 and packs them into a 31-byte (EFR_RTP_FRAME_LEN) frame in ETSI TS 101 318 |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
135 format. The 0xC signature is generated by this function, and every byte of the |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
136 output buffer is fully written without regard to any previous content. This |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
137 function is called internally by EFR_encode_frame(). |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
138 |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
139 extern int EFR_sid_classify(const uint8_t *frame); |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
140 |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
141 This function analyzes an RTP-encoded EFR frame (the upper nibble of the first |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
142 byte is NOT checked for 0xC signature) for the SID codeword of GSM 06.62 and |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
143 classifies the frame as SID=0, SID=1 or SID=2 per the rules of GSM 06.81 |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
144 section 6.1.1. |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
145 |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
146 extern void EFR_insert_sid_codeword(uint8_t *frame); |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
147 |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
148 This function inserts the SID codeword of GSM 06.62 into the frame in the |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
149 pointed-to buffer; specifically, the 95 bits that make up the SID field are all |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
150 set to 1s, but all other bits remain unchanged. This function is arguably least |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
151 useful to external users of libgsmefr, but it exists because of how the original |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
152 code from ETSI generates SID frames produced by the encoder in DTX mode. |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
153 |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
154 Parameter-based encoder and decoder functions |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
155 ============================================= |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
156 |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
157 The EFR_encode_frame() and EFR_decode_frame() functions described earlier in |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
158 this document constitute the most practically useful (intended for actual use) |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
159 interfaces to our EFR encoder and decoder, but they are actually wrappers around |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
160 these parameter-based functions: |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
161 |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
162 extern void EFR_encode_params(struct EFR_encoder_state *st, const int16_t *pcm, |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
163 int16_t *params, int *sp, int *vad); |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
164 |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
165 This function is similar to EFR_encode_frame(), but the output is an array of |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
166 57 (EFR_NUM_PARAMS) codec parameter words rather than a finished frame. The two |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
167 extra output flags are optional (pointers may be NULL) just like with |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
168 EFR_encode_frame(), but there is a catch: if the output frame is a SID (which |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
169 can only happen if DTX is enabled), the bits inside parameter words that would |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
170 correspond to SID codeword bits are NOT set, instead one MUST call |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
171 EFR_insert_sid_codeword() after packing the frame with EFR_params2frame(). The |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
172 wrapper in EFR_encode_frame() does exactly as described, and the overall logic |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
173 follows the original code structure from ETSI. |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
174 |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
175 extern void EFR_decode_params(struct EFR_decoder_state *st, |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
176 const int16_t *params, int bfi, int sid, int taf, |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
177 int16_t *pcm); |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
178 |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
179 This function is similar to EFR_decode_frame() with the frame input replaced |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
180 with params array input, but the SID classification per the rules of GSM 06.81 |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
181 section 6.1.1 needs to be provided by the caller. The wrapper in |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
182 EFR_decode_frame() calls both EFR_frame2params() and EFR_sid_classify() before |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
183 passing the work to EFR_decode_params(). |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
184 |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
185 State reset functions |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
186 ===================== |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
187 |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
188 extern void EFR_encoder_reset(struct EFR_encoder_state *st, int dtx); |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
189 extern void EFR_decoder_reset(struct EFR_decoder_state *st); |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
190 |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
191 These functions reset the state of the encoder or the decoder, respectively; |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
192 the entire state structure is fully initialized to the respective home state |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
193 defined in GSM 06.60 section 8.5 for the encoder or section 8.6 for the decoder. |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
194 |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
195 EFR_encoder_reset() is called internally by EFR_encoder_create() and by the |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
196 encoder itself when it encounters the ETSI-prescribed encoder homing frame; |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
197 EFR_decoder_reset() is called internally by EFR_decoder_create() and by the |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
198 decoder itself when it encounters the ETSI-prescribed decoder homing frame. |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
199 Therefore, there is generally no need for libgsmefr users to call these |
92fdb499b5c3
doc/EFR-library-API article written
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
200 functions directly - but they are made public for the sake of completeness. |
130
1c529bb31219
doc/EFR-library-API: explain dtx argument to EFR_encoder_reset()
Mychaela Falconia <falcon@freecalypso.org>
parents:
123
diff
changeset
|
201 |
1c529bb31219
doc/EFR-library-API: explain dtx argument to EFR_encoder_reset()
Mychaela Falconia <falcon@freecalypso.org>
parents:
123
diff
changeset
|
202 If you call EFR_encoder_reset() manually, you can change the DTX enable/disable |
1c529bb31219
doc/EFR-library-API: explain dtx argument to EFR_encoder_reset()
Mychaela Falconia <falcon@freecalypso.org>
parents:
123
diff
changeset
|
203 flag from its initial value given to EFR_encoder_create() - the new value of |
1c529bb31219
doc/EFR-library-API: explain dtx argument to EFR_encoder_reset()
Mychaela Falconia <falcon@freecalypso.org>
parents:
123
diff
changeset
|
204 this flag passed to EFR_encoder_reset() always takes effect. There is no |
1c529bb31219
doc/EFR-library-API: explain dtx argument to EFR_encoder_reset()
Mychaela Falconia <falcon@freecalypso.org>
parents:
123
diff
changeset
|
205 provision for changing this mode within an encoder session without a full reset. |