Asterisk - The Open Source Telephony Project GIT-master-f3e88d3
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 <pabstraud@compuserve.com>
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 <pabstraud@compuserve.com>
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
60static 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. */
75static 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 */
94static 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 */
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
119 pvt->samples -= CODEC2_SAMPLES;
120
122
123 if (!current) {
124 continue;
125 } else if (last) {
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
141static 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
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
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
195static int unload_module(void)
196{
197 int res = 0;
198
202
203 return res;
204}
205
206static int load_module(void)
207{
208 int res = 0;
209
213
214 if (res) {
217 }
218
220}
221
struct sla_ringing_trunk * last
Definition: app_sla.c:332
Asterisk main include file. File version handling, generic pbx functions.
#define ast_log
Definition: astobj2.c:42
static int tmp()
Definition: bt_open.c:389
static PGresult * result
Definition: cel_pgsql.c:84
Codec API.
@ AST_MEDIA_TYPE_AUDIO
Definition: codec.h:32
static struct ast_frame * lintocodec2_frameout(struct ast_trans_pvt *pvt)
encode and produce a frame
Definition: codec_codec2.c:105
static struct ast_translator codec2tolin
Definition: codec_codec2.c:150
#define BUFFER_SAMPLES
Definition: codec_codec2.c:47
static int codec2_new(struct ast_trans_pvt *pvt)
Definition: codec_codec2.c:60
#define CODEC2_SAMPLES
Definition: codec_codec2.c:48
static void codec2_destroy_stuff(struct ast_trans_pvt *pvt)
Definition: codec_codec2.c:141
static struct ast_translator lintocodec2
Definition: codec_codec2.c:172
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
static int codec2tolin_framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
decode and store in outbuf.
Definition: codec_codec2.c:75
static int load_module(void)
Definition: codec_codec2.c:206
#define CODEC2_FRAME_LEN
Definition: codec_codec2.c:49
static int unload_module(void)
Definition: codec_codec2.c:195
short int16_t
Definition: db.h:59
8-bit raw data
static struct ast_frame * codec2_sample(void)
Definition: ex_codec2.h:17
struct ast_format * ast_format_codec2
Built-in cached Codec 2 format.
Definition: format_cache.c:226
Asterisk internal frame definitions.
Support for logging to various files, console and syslog Configuration in file logger....
#define LOG_ERROR
A set of macros to manage forward-linked lists.
#define AST_LIST_NEXT(elm, field)
Returns the next entry in the list after the given entry.
Definition: linkedlists.h:439
size_t current
Definition: main/cli.c:113
Asterisk module definitions.
#define AST_MODULE_INFO_STANDARD(keystr, desc)
Definition: module.h:581
#define ASTERISK_GPL_KEY
The text the key() function should return.
Definition: module.h:46
@ AST_MODULE_LOAD_SUCCESS
Definition: module.h:70
@ AST_MODULE_LOAD_DECLINE
Module has failed to load, may be in an inconsistent state.
Definition: module.h:78
#define NULL
Definition: resample.c:96
Pluggable RTP Architecture.
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:3384
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:3368
static struct ast_frame * slin8_sample(void)
Definition: slin.h:64
Data structure associated with a single frame of data.
union ast_frame::@226 data
Default structure for translators, with the basic fields and buffers, all allocated as part of the sa...
Definition: translate.h:213
void * pvt
Definition: translate.h:219
unsigned char * uc
Definition: translate.h:222
int datalen
actual space used in outbuf
Definition: translate.h:218
union ast_trans_pvt::@287 outbuf
int16_t * i16
Definition: translate.h:223
Descriptor of a translator.
Definition: translate.h:137
char name[80]
Definition: translate.h:138
int16_t buf[BUFFER_SAMPLES]
Definition: codec_codec2.c:57
struct CODEC2 * state
Definition: codec_codec2.c:56
Support for translation of data formats. translate.c.
#define ast_register_translator(t)
See __ast_register_translator()
Definition: translate.h:258
int ast_unregister_translator(struct ast_translator *t)
Unregister a translator Unregisters the given translator.
Definition: translate.c:1350
struct ast_frame * ast_trans_frameout(struct ast_trans_pvt *pvt, int datalen, int samples)
generic frameout function
Definition: translate.c:439