blob: 55bbd11a414349a1a5e544ecc97e7913a628209f [file] [log] [blame]
Sylvain Munautcca11552010-10-24 18:32:44 +02001/* EFR (GSM 06.60) codec */
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 <gapk/codecs.h>
Harald Welte7a046242014-05-08 19:18:01 +020021#include <gapk/benchmark.h>
Sylvain Munautcca11552010-10-24 18:32:44 +020022
Sylvain Munaut8552b9d2010-11-11 13:57:41 +010023#include "config.h"
24
25
26#ifdef HAVE_OPENCORE_AMRNB
27
28#include <stdlib.h>
29
Sylvain Munautdb837252012-12-08 19:14:11 +010030#include <opencore-amrnb/interf_dec.h>
31#include <opencore-amrnb/interf_enc.h>
Sylvain Munaut8552b9d2010-11-11 13:57:41 +010032
33
34struct codec_efr_state {
35 void *encoder;
36 void *decoder;
37};
38
39
40static void *
41codec_efr_init(void)
42{
43 struct codec_efr_state *st;
44
45 st = calloc(1, sizeof(*st));
46 if (!st)
47 return NULL;
48
49 st->encoder = Encoder_Interface_init(0);
50 st->decoder = Decoder_Interface_init();
51
52 return (void *)st;
53}
54
55static void
56codec_efr_exit(void *state)
57{
58 struct codec_efr_state *st = state;
59
60 Decoder_Interface_exit(st->decoder);
61 Encoder_Interface_exit(st->encoder);
62
63 return;
64}
65
66static int
67codec_efr_encode(void *state, uint8_t *cod, const uint8_t *pcm)
68{
69 struct codec_efr_state *st = state;
70 int rv;
71
Harald Welte7a046242014-05-08 19:18:01 +020072 BENCHMARK_START;
Sylvain Munaut8552b9d2010-11-11 13:57:41 +010073 rv = Encoder_Interface_Encode(
74 st->encoder,
75 MR122,
76 (const short*) pcm,
77 (unsigned char*) cod,
78 1
79 );
Harald Welte7a046242014-05-08 19:18:01 +020080 BENCHMARK_STOP(CODEC_EFR, 1);
Sylvain Munaut8552b9d2010-11-11 13:57:41 +010081
Sylvain Munautf624d182010-11-12 20:53:53 +010082 return rv != 32;
Sylvain Munaut8552b9d2010-11-11 13:57:41 +010083}
84
85static int
86codec_efr_decode(void *state, uint8_t *pcm, const uint8_t *cod)
87{
88 struct codec_efr_state *st = state;
89
Harald Welte7a046242014-05-08 19:18:01 +020090 BENCHMARK_START;
Sylvain Munaut8552b9d2010-11-11 13:57:41 +010091 Decoder_Interface_Decode(
92 st->decoder,
93 (const unsigned char*) cod,
94 (short *) pcm,
95 0
96 );
Harald Welte7a046242014-05-08 19:18:01 +020097 BENCHMARK_STOP(CODEC_EFR, 0);
Sylvain Munaut8552b9d2010-11-11 13:57:41 +010098
99 return 0;
100}
101
102#endif /* HAVE_OPENCORE_AMRNB */
103
104
Sylvain Munautcca11552010-10-24 18:32:44 +0200105const struct codec_desc codec_efr_desc = {
106 .type = CODEC_EFR,
107 .name = "efr",
108 .description = "GSM 06.60 Enhanced Full Rate codec",
109 .canon_frame_len = 31,
Sylvain Munaut8552b9d2010-11-11 13:57:41 +0100110#ifdef HAVE_OPENCORE_AMRNB
111 .codec_enc_format_type = FMT_AMR_EFR,
112 .codec_dec_format_type = FMT_AMR_EFR,
113 .codec_init = codec_efr_init,
114 .codec_exit = codec_efr_exit,
115 .codec_encode = codec_efr_encode,
116 .codec_decode = codec_efr_decode,
117#endif
Sylvain Munautcca11552010-10-24 18:32:44 +0200118};