Asterisk - The Open Source Telephony Project  18.5.0
codec_codec2.c
Go to the documentation of this file.
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 2016, Alexander Traud
5  *
6  * Alexander Traud <[email protected]>
7  *
8  * See http://www.asterisk.org for more information about
9  * the Asterisk project. Please do not directly contact
10  * any of the maintainers of this project for assistance;
11  * the project provides a web site, mailing lists and IRC
12  * channels for your use.
13  *
14  * This program is free software, distributed under the terms of
15  * the GNU General Public License Version 2. See the LICENSE file
16  * at the top of the source tree.
17  */
18 
19 /*! \file
20  *
21  * \brief Translate between signed linear and Codec 2
22  *
23  * \author Alexander Traud <[email protected]>
24  *
25  * \note http://www.rowetel.com/codec2.html
26  *
27  * \ingroup codecs
28  */
29 
30 /*** MODULEINFO
31  <depend>codec2</depend>
32  <support_level>core</support_level>
33  ***/
34 
35 #include "asterisk.h"
36 
37 #include "asterisk/codec.h" /* for AST_MEDIA_TYPE_AUDIO */
38 #include "asterisk/frame.h" /* for ast_frame */
39 #include "asterisk/linkedlists.h" /* for AST_LIST_NEXT, etc */
40 #include "asterisk/logger.h" /* for ast_log, etc */
41 #include "asterisk/module.h"
42 #include "asterisk/rtp_engine.h" /* ast_rtp_engine_(un)load_format */
43 #include "asterisk/translate.h" /* for ast_trans_pvt, etc */
44 
45 #include <codec2/codec2.h>
46 
47 #define BUFFER_SAMPLES 8000
48 #define CODEC2_SAMPLES 160 /* consider codec2_samples_per_frame(.) */
49 #define CODEC2_FRAME_LEN 6 /* consider codec2_bits_per_frame(.) */
50 
51 /* Sample frame data */
52 #include "asterisk/slin.h"
53 #include "ex_codec2.h"
54 
56  struct CODEC2 *state; /* May be encoder or decoder */
58 };
59 
60 static int codec2_new(struct ast_trans_pvt *pvt)
61 {
62  struct codec2_translator_pvt *tmp = pvt->pvt;
63 
64  tmp->state = codec2_create(CODEC2_MODE_2400);
65 
66  if (!tmp->state) {
67  ast_log(LOG_ERROR, "Error creating Codec 2 conversion\n");
68  return -1;
69  }
70 
71  return 0;
72 }
73 
74 /*! \brief decode and store in outbuf. */
75 static int codec2tolin_framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
76 {
77  struct codec2_translator_pvt *tmp = pvt->pvt;
78  int x;
79 
80  for (x = 0; x < f->datalen; x += CODEC2_FRAME_LEN) {
81  unsigned char *src = f->data.ptr + x;
82  int16_t *dst = pvt->outbuf.i16 + pvt->samples;
83 
84  codec2_decode(tmp->state, dst, src);
85 
86  pvt->samples += CODEC2_SAMPLES;
87  pvt->datalen += CODEC2_SAMPLES * 2;
88  }
89 
90  return 0;
91 }
92 
93 /*! \brief store samples into working buffer for later decode */
94 static int lintocodec2_framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
95 {
96  struct codec2_translator_pvt *tmp = pvt->pvt;
97 
98  memcpy(tmp->buf + pvt->samples, f->data.ptr, f->datalen);
99  pvt->samples += f->samples;
100 
101  return 0;
102 }
103 
104 /*! \brief encode and produce a frame */
105 static struct ast_frame *lintocodec2_frameout(struct ast_trans_pvt *pvt)
106 {
107  struct codec2_translator_pvt *tmp = pvt->pvt;
108  struct ast_frame *result = NULL;
109  struct ast_frame *last = NULL;
110  int samples = 0; /* output samples */
111 
112  while (pvt->samples >= CODEC2_SAMPLES) {
113  struct ast_frame *current;
114 
115  /* Encode a frame of data */
116  codec2_encode(tmp->state, pvt->outbuf.uc, tmp->buf + samples);
117 
118  samples += CODEC2_SAMPLES;
119  pvt->samples -= CODEC2_SAMPLES;
120 
122 
123  if (!current) {
124  continue;
125  } else if (last) {
126  AST_LIST_NEXT(last, frame_list) = current;
127  } else {
128  result = current;
129  }
130  last = current;
131  }
132 
133  /* Move the data at the end of the buffer to the front */
134  if (samples) {
135  memmove(tmp->buf, tmp->buf + samples, pvt->samples * 2);
136  }
137 
138  return result;
139 }
140 
141 static void codec2_destroy_stuff(struct ast_trans_pvt *pvt)
142 {
143  struct codec2_translator_pvt *tmp = pvt->pvt;
144 
145  if (tmp->state) {
146  codec2_destroy(tmp->state);
147  }
148 }
149 
150 static struct ast_translator codec2tolin = {
151  .name = "codec2tolin",
152  .src_codec = {
153  .name = "codec2",
154  .type = AST_MEDIA_TYPE_AUDIO,
155  .sample_rate = 8000,
156  },
157  .dst_codec = {
158  .name = "slin",
159  .type = AST_MEDIA_TYPE_AUDIO,
160  .sample_rate = 8000,
161  },
162  .format = "slin",
163  .newpvt = codec2_new,
164  .framein = codec2tolin_framein,
165  .destroy = codec2_destroy_stuff,
166  .sample = codec2_sample,
167  .desc_size = sizeof(struct codec2_translator_pvt),
168  .buffer_samples = BUFFER_SAMPLES,
169  .buf_size = BUFFER_SAMPLES * 2,
170 };
171 
172 static struct ast_translator lintocodec2 = {
173  .name = "lintocodec2",
174  .src_codec = {
175  .name = "slin",
176  .type = AST_MEDIA_TYPE_AUDIO,
177  .sample_rate = 8000,
178  },
179  .dst_codec = {
180  .name = "codec2",
181  .type = AST_MEDIA_TYPE_AUDIO,
182  .sample_rate = 8000,
183  },
184  .format = "codec2",
185  .newpvt = codec2_new,
186  .framein = lintocodec2_framein,
187  .frameout = lintocodec2_frameout,
188  .destroy = codec2_destroy_stuff,
189  .sample = slin8_sample,
190  .desc_size = sizeof(struct codec2_translator_pvt),
191  .buffer_samples = BUFFER_SAMPLES,
193 };
194 
195 static int unload_module(void)
196 {
197  int res = 0;
198 
200  res |= ast_unregister_translator(&lintocodec2);
201  res |= ast_unregister_translator(&codec2tolin);
202 
203  return res;
204 }
205 
206 static int load_module(void)
207 {
208  int res = 0;
209 
210  res |= ast_register_translator(&codec2tolin);
211  res |= ast_register_translator(&lintocodec2);
213 
214  if (res) {
215  unload_module();
217  }
218 
220 }
221 
222 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Codec 2 Coder/Decoder");
struct ast_frame * ast_trans_frameout(struct ast_trans_pvt *pvt, int datalen, int samples)
generic frameout function
Definition: translate.c:438
int datalen
actual space used in outbuf
Definition: translate.h:218
static struct ast_translator codec2tolin
Definition: codec_codec2.c:150
struct CODEC2 * state
Definition: codec_codec2.c:56
#define AST_MODULE_INFO_STANDARD(keystr, desc)
Definition: module.h:567
Asterisk main include file. File version handling, generic pbx functions.
int16_t buf[BUFFER_SAMPLES]
Definition: codec_codec2.c:57
Descriptor of a translator.
Definition: translate.h:137
short int16_t
Definition: db.h:59
Support for translation of data formats. translate.c.
static struct ast_frame * lintocodec2_frameout(struct ast_trans_pvt *pvt)
encode and produce a frame
Definition: codec_codec2.c:105
static int tmp()
Definition: bt_open.c:389
#define AST_LIST_NEXT(elm, field)
Returns the next entry in the list after the given entry.
Definition: linkedlists.h:438
Codec API.
unsigned char * uc
Definition: translate.h:222
static struct ast_frame * slin8_sample(void)
Definition: slin.h:64
static int lintocodec2_framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
store samples into working buffer for later decode
Definition: codec_codec2.c:94
#define NULL
Definition: resample.c:96
#define BUFFER_SAMPLES
Definition: codec_codec2.c:47
void * pvt
Definition: translate.h:219
static int unload_module(void)
Definition: codec_codec2.c:195
int ast_rtp_engine_unload_format(struct ast_format *format)
Formats requiring the use of a format attribute interface must have that interface registered in orde...
Definition: rtp_engine.c:3245
int16_t * i16
Definition: translate.h:223
#define ast_log
Definition: astobj2.c:42
struct sla_ringing_trunk * last
Definition: app_meetme.c:1092
#define ast_register_translator(t)
See __ast_register_translator()
Definition: translate.h:257
Asterisk internal frame definitions.
int ast_unregister_translator(struct ast_translator *t)
Unregister a translator Unregisters the given tranlator.
Definition: translate.c:1333
A set of macros to manage forward-linked lists.
struct ast_format * ast_format_codec2
Built-in cached Codec 2 format.
Definition: format_cache.c:231
union ast_trans_pvt::@327 outbuf
#define LOG_ERROR
Definition: logger.h:285
static struct ast_translator lintocodec2
Definition: codec_codec2.c:172
Default structure for translators, with the basic fields and buffers, all allocated as part of the sa...
Definition: translate.h:213
static struct ast_frame * codec2_sample(void)
Definition: ex_codec2.h:17
#define CODEC2_SAMPLES
Definition: codec_codec2.c:48
static int load_module(void)
Definition: codec_codec2.c:206
Module has failed to load, may be in an inconsistent state.
Definition: module.h:78
static int codec2_new(struct ast_trans_pvt *pvt)
Definition: codec_codec2.c:60
8-bit raw data
Support for logging to various files, console and syslog Configuration in file logger.conf.
#define CODEC2_FRAME_LEN
Definition: codec_codec2.c:49
static PGresult * result
Definition: cel_pgsql.c:88
Data structure associated with a single frame of data.
static void codec2_destroy_stuff(struct ast_trans_pvt *pvt)
Definition: codec_codec2.c:141
int ast_rtp_engine_load_format(struct ast_format *format)
Custom formats declared in codecs.conf at startup must be communicated to the rtp_engine so their mim...
Definition: rtp_engine.c:3229
union ast_frame::@263 data
static int codec2tolin_framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
decode and store in outbuf.
Definition: codec_codec2.c:75
#define ASTERISK_GPL_KEY
The text the key() function should return.
Definition: module.h:46
Pluggable RTP Architecture.
Asterisk module definitions.
char name[80]
Definition: translate.h:138