d018c9011ea6bff48cbcce2e6df4ea64a7e27c72
[lcr.git] / libgsmhr / libgsmhr.c
1 /* HR (GSM 06.20) codec wrapper */
2
3 /*
4  * This file is part of gapk (GSM Audio Pocket Knife).
5  *
6  * gapk is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * gapk is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with gapk.  If not, see <http://www.gnu.org/licenses/>.
18  */
19
20 #include <stdint.h>
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24
25 #include <gsmhr/gsmhr.h>
26
27 #include "refsrc/typedefs.h"
28 #include "refsrc/homing.h"
29 #include "refsrc/sp_dec.h"
30 #include "refsrc/sp_enc.h"
31
32
33 #define EXPORT __attribute__((visibility("default")))
34
35
36 struct gsmhr {
37         int dec_reset_flg;
38 };
39
40 EXPORT struct gsmhr *
41 gsmhr_init(void)
42 {
43         struct gsmhr *state;
44
45         state = calloc(1, sizeof(struct gsmhr));
46         if (!state)
47                 return NULL;
48
49         state->dec_reset_flg = 1;
50
51         return state;
52 }
53
54 EXPORT void
55 gsmhr_exit(struct gsmhr *state)
56 {
57         free(state);
58 }
59
60 EXPORT int
61 gsmhr_encode(struct gsmhr *state, int16_t *hr_params, const int16_t *pcm)
62 {
63         int enc_reset_flg;
64         Shortword pcm_b[F_LEN];
65
66         memcpy(pcm_b, pcm, F_LEN*sizeof(int16_t));
67
68         enc_reset_flg = encoderHomingFrameTest(pcm_b);
69
70         speechEncoder(pcm_b, hr_params);
71
72         if (enc_reset_flg)
73                 resetEnc();
74
75         return 0;
76 }
77
78 EXPORT int
79 gsmhr_decode(struct gsmhr *state, int16_t *pcm, const int16_t *hr_params)
80 {
81 #define WHOLE_FRAME             18
82 #define TO_FIRST_SUBFRAME        9
83
84         int dec_reset_flg;
85         Shortword hr_params_b[22];
86
87         memcpy(hr_params_b, hr_params, 22*sizeof(int16_t));
88
89         if (state->dec_reset_flg)
90                 dec_reset_flg = decoderHomingFrameTest(hr_params_b, TO_FIRST_SUBFRAME);
91         else
92                 dec_reset_flg = 0;
93
94         if (dec_reset_flg && state->dec_reset_flg) {
95                 int i;
96                 for (i=0; i<F_LEN; i++)
97                         pcm[i] = EHF_MASK;
98         } else {
99                 speechDecoder(hr_params_b, pcm);
100         }
101
102         if (!state->dec_reset_flg)
103                 dec_reset_flg = decoderHomingFrameTest(hr_params_b, WHOLE_FRAME);
104
105         if (dec_reset_flg)
106                 resetDec();
107
108         state->dec_reset_flg = dec_reset_flg;
109
110         return 0;
111 }