1 /* wrap.c -- API wrappers for the selected codecs.
3 * "Een beetje van jezelf, een beetje is magisch."
4 * (Maar wij kunnen het zonder GSM of MSG.)
6 * This file is part of 0cpm Firmerware.
8 * 0cpm Firmerware is Copyright (c)2011 Rick van Rein, OpenFortress.
10 * 0cpm Firmerware is free software: you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License as
12 * published by the Free Software Foundation, version 3.
14 * 0cpm Firmerware is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with 0cpm Firmerware. If not, see <http://www.gnu.org/licenses/>.
27 #include <0cpm/codec.h>
31 * Codecs pack and unpack media streams for delivery over RTP.
32 * The abilities of codecs are negotiated using SDP-descriptions,
33 * commonly sent in the body of a SIP or SAP message.
37 * The codec-wrapper functionality aligns the internal API used
38 * by the 0cpm Firmerware with codec software used from other
39 * open source projects.
44 /********** PAYLOAD TYPE ALLOCATIONS **********/
46 // Pay Mime-type Rate Registry
48 // 0 audio/PCMU 8000 IANA
49 // 8 audio/PCMA 8000 IANA
50 // 99 audio/L16 var. LOCAL (arbitrary sample rate)
51 // 98 text/t140 1000 LOCAL
52 // 100 text/red 1000 LOCAL
53 // 101 audio/telephone-event 8000 LOCAL (but commonly used)
54 // 110 audio/G726-32 8000 LOCAL
55 // 111 audio/AAL2-G726-32 8000 LOCAL
56 // 125 audio/x-codec2 2550 LOCAL
57 // 124 audio/x-codec2 2400 LOCAL
58 // 123 audio/x-codec2 2000 LOCAL
59 // 122 audio/x-codec2 1500 LOCAL
60 // 121 audio/x-codec2 1000? RESERVED
61 // 126 audio/speex var. LOCAL
62 // 127 audio/vorbis var. LOCAL
66 /********** G.711 DEFINITIONS **********/
68 #ifdef CONFIG_CODEC_G711
71 static void g711_init_ulaw (struct codec *hdl, uint32_t samplerate) {
72 g711_init (&hdl->state.state_g711, G711_ULAW);
76 static void g711_init_alaw (struct codec *hdl, uint32_t samplerate) {
77 g711_init (&hdl->state.state_g711, G711_ALAW);
80 static void g711_finish (struct codec *hdl) {
81 g711_release (&hdl->state.state_g711);
84 static void g711_transform_encode (struct codec *hdl,
85 int16_t *pcm, uint16_t *pcmlen,
86 uint8_t *pkt, uint16_t *pktlen) {
87 uint16_t len = *pcmlen;
88 if (*pktlen < *pcmlen) {
91 len = g711_encode (&hdl->state.state_g711, pkt, pcm, len);
92 *pcmlen = *pktlen = len;
95 static void g711_transform_decode (struct codec *hdl,
96 int16_t *pcm, uint16_t *pcmlen,
97 uint8_t *pkt, uint16_t *pktlen) {
98 uint16_t len = *pcmlen;
99 if (*pktlen < *pcmlen) {
102 len = g711_decode (&hdl->state.state_g711, pcm, pkt, len);
103 *pcmlen = *pktlen = len;
106 struct codec_fun encoder_g711_ulaw = {
107 "audio", "PCMU", NULL,
109 g711_init_ulaw, g711_finish, g711_transform_encode,
113 struct codec_fun decoder_g711_ulaw = {
114 "audio", "PCMU", NULL,
116 g711_init_ulaw, g711_finish, g711_transform_decode,
120 struct codec_fun encoder_g711_alaw = {
121 "audio", "PCMA", NULL,
123 g711_init_alaw, g711_finish, g711_transform_encode,
127 struct codec_fun decoder_g711_alaw = {
128 "audio", "PCMA", NULL,
130 g711_init_alaw, g711_finish, g711_transform_decode,
138 /********** G.722 DEFINITIONS **********/
140 #ifdef CONFIG_CODEC_G722
142 static void g722_init_encode (struct codec *hdl, uint32_t samplerate) {
143 g722_encode_init (&hdl->state.state_g722_encode, 64000, 0);
146 static void g722_init_decode (struct codec *hdl, uint32_t samplerate) {
147 g722_decode_init (&hdl->state.state_g722_decode, 64000, 0);
150 static void g722_finish_encode (struct codec *hdl) {
151 g722_encode_release (&hdl->state.state_g722_encode);
154 static void g722_finish_decode (struct codec *hdl) {
155 g722_decode_release (&hdl->state.state_g722_decode);
158 static void g722_transform_encode (struct codec *hdl,
159 int16_t *pcm, uint16_t *pcmlen,
160 uint8_t *pkt, uint16_t *pktlen) {
161 uint16_t len = *pcmlen;
162 if (*pktlen < *pcmlen) {
165 len = g722_encode (&hdl->state.state_g722_encode, pkt, pcm, len);
166 *pcmlen = *pktlen = len;
169 static void g722_transform_decode (struct codec *hdl,
170 int16_t *pcm, uint16_t *pcmlen,
171 uint8_t *pkt, uint16_t *pktlen) {
172 uint16_t len = *pcmlen;
173 if (*pktlen < *pcmlen) {
176 len = g722_decode (&hdl->state.state_g722_decode, pcm, pkt, len);
177 *pcmlen = *pktlen = len;
180 struct codec_fun encoder_g722_historically_incorrect = {
181 "audio", "G722", NULL,
183 g722_init_encode, g722_finish_encode, g722_transform_encode,
184 8000 /*history error*/, 9
186 struct codec_fun decoder_g722_historically_incorrect = {
187 "audio", "G722", NULL,
189 g722_init_decode, g722_finish_decode, g722_transform_decode,
190 8000 /*history error*/, 9
192 struct codec_fun encoder_g722 = {
193 "audio", "G722", NULL,
195 g722_init_encode, g722_finish_encode, g722_transform_encode,
198 struct codec_fun decoder_g722 = {
199 "audio", "G722", NULL,
201 g722_init_decode, g722_finish_decode, g722_transform_decode,
208 /********** G.726 DEFINITIONS **********/
211 #ifdef CONFIG_CODEC_G726
214 static void g726_init_encode (struct codec *hdl, uint32_t samplerate) {
215 /* TODO: G726_ENCODING_ULAW... and/or _ALAW? RTP profile? */
216 g726_init (&hdl->state.state_g726_encode, 32000, G726_ENCODING_ULAW, G726_PACKING_LEFT);
219 static void g726_init_decode (struct codec *hdl, uint32_t samplerate) {
220 /* TODO: G726_ENCODING_ULAW... and/or _ALAW? RTP profile? */
221 g726_init (&hdl->state.state_g726_decode, 32000, G726_ENCODING_ULAW, G726_PACKING_LEFT);
224 static void g726aal2_init_encode (struct codec *hdl, uint32_t samplerate) {
225 /* TODO: G726_ENCODING_ULAW... and/or _ALAW? RTP profile? */
226 g726_init (&hdl->state.state_g726_encode, 32000, G726_ENCODING_ULAW, G726_PACKING_RIGHT);
229 static void g726aal2_init_decode (struct codec *hdl, uint32_t samplerate) {
230 /* TODO: G726_ENCODING_ULAW... and/or _ALAW? RTP profile? */
231 g726_init (&hdl->state.state_g726_decode, 32000, G726_ENCODING_ULAW, G726_PACKING_RIGHT);
235 static void g726_finish_encode (struct codec *hdl) {
236 g726_release (&hdl->state.state_g726_encode);
239 static void g726_finish_decode (struct codec *hdl) {
240 g726_release (&hdl->state.state_g726_decode);
243 static void g726_transform_encode (struct codec *hdl,
244 int16_t *pcm, uint16_t *pcmlen,
245 uint8_t *pkt, uint16_t *pktlen) {
246 uint16_t len = *pcmlen;
247 if (*pktlen < *pcmlen) {
250 len = g726_encode (&hdl->state.state_g726_encode, pkt, pcm, len);
251 *pcmlen = *pktlen = len;
254 static void g726_transform_decode (struct codec *hdl,
255 int16_t *pcm, uint16_t *pcmlen,
256 uint8_t *pkt, uint16_t *pktlen) {
257 uint16_t len = *pcmlen;
258 if (*pktlen < *pcmlen) {
261 len = g726_decode (&hdl->state.state_g726_decode, pcm, pkt, len);
262 *pcmlen = *pktlen = len;
267 struct codec_fun encoder_g726 = {
268 "audio", "G726-32", NULL,
270 g726_init_encode, g726_finish_encode, g726_transform_encode,
273 struct codec_fun decoder_g726 = {
274 "audio", "G726-32", NULL,
276 g726_init_decode, g726_finish_decode, g726_transform_decode,
280 struct codec_fun encoder_g726aal2 = {
281 "audio", "AAL2-G726-32", NULL,
283 g726aal2_init_encode, g726_finish_encode, g726_transform_encode,
286 struct codec_fun decoder_g726aal2 = {
287 "audio", "AAL2-G726-32", NULL,
289 g726aal2_init_decode, g726_finish_decode, g726_transform_decode,
296 /********** SPEEX DEFINITIONS **********/
298 #if defined (CONFIG_CODEC_SPEEX_NARROWBAND) || defined (CONFIG_CODEC_SPEEX_WIDEBAND) || defined (CONFIG_CODEC_SPEEX_ULTRAWIDEBAND)
300 void speex_init_encode (struct codec *hdl, uint32_t samplerate) {
301 speex_encoder_init (&hdl->state.state_speex_encode);
303 void speex_finish_encode (struct codec *hdl) {
304 speex_encoder_destroy (&hdl->state.state_speex_encode);
306 void speex_transform_encode (struct codec *hdl,
307 uint16_t *pcm, uint16_t *pcmlen,
308 uint8_t *pkt, uint16_t *pktlen) {
309 speex_encode (&hdl->state.state_speex_encode, NULL /*TODO*/);
311 void speex_init_decode (struct codec *hdl, uint32_t samplerate) {
312 speex_decoder_init (&hdl->state.state_speex_decode);
314 void speex_finish_decode (struct codec *hdl) {
315 speex_decoder_destroy (&hdl->state.state_speex_decode);
317 void speex_transform_decode (struct codec *hdl, uint16_t *pktlen) {
318 speex_decode (&hdl->state.state_speex_decode, NULL /*TODO*/);
323 #ifdef CONFIG_CODEC_SPEEX_NARROWBAND
324 struct codec_fun encoder_speex_narrow = {
325 "audio", "speex", "mode=any;vbr=on;cng=on",
327 speex_init_encode, speex_finish_encode, speex_transform_encode,
330 struct codec_fun decoder_speex_narrow = {
331 "audio", "speex", "mode=any;vbr=on;cng=on",
333 speex_init_decode, speex_finish_decode, speex_transform_decode,
338 #ifdef CONFIG_CODEC_SPEEX_WIDEBAND
339 struct codec_fun encoder_speex_wide = {
340 "audio", "speex", "mode=any;vbr=on;cng=on",
342 speex_init_encode, speex_finish_encode, speex_transform_encode,
345 struct codec_fun decoder_speex_wide = {
346 "audio", "speex", "mode=any;vbr=on;cng=on",
348 speex_init_decode, speex_finish_decode, speex_transform_decode,
353 #ifdef CONFIG_CODEC_SPEEX_ULTRAWIDEBAND
354 struct codec_fun encoder_speex_ultra = {
355 "audio", "speex", "mode=any;vbr=on;cng=on",
357 speex_init_encode, speex_finish_encode, speex_transform_encode,
360 struct codec_fun decoder_speex_ultra = {
361 "audio", "speex", "mode=any;vbr=on;cng=on",
363 speex_init_decode, speex_finish_decode, speex_transform_decode,
369 /********** CODEC2 DEFINITIONS **********/
371 static void codec2_init (struct codec *hdl, uint32_t samplerate) {
372 //TODO// Static allocation
373 codec2_create (&hdl->state.codec2_state);
376 static void codec2_finish (struct codec *hdl, uint32_t samplerate) {
377 codec2_destroy (&hdl->state.codec2_state);
380 static void codec2_transform_encode (struct codec *hdl,
381 int16_t *pcm, uint16_t *pcmlen,
382 uint8_t *pkt, uint16_t *pktlen) {
383 codec2_encode (hdl, pkt, pcm);
384 *pcmlen = CODEC2_SAMPLES_PER_FRAME;
385 *pktlen = (CODEC2_BITS_PER_FRAME + 7) >> 3;
388 static void codec2_transform_decode (struct codec *hdl,
389 int16_t *pcm, uint16_t *pcmlen,
390 uint8_t *pkt, uint16_t *pktlen) {
391 codec2_decode (hdl, pcm, pkt);
392 *pcmlen = CODEC2_SAMPLES_PER_FRAME;
393 *pktlen = (CODEC2_BITS_PER_FRAME + 7) >> 3;
397 #ifdef CONFIG_CODEC_CODEC2
398 struct codec_fun encoder_codec2_1500 = {
399 "audio", "x-codec2", NULL,
401 codec2_init, codec2_finish, codec2_transform_encode,
404 struct codec_fun decoder_codec2_1500 = {
405 "audio", "x-codec2", NULL,
407 codec2_init, codec2_finish, codec2_transform_decode,
410 struct codec_fun encoder_codec2_2000 = {
411 "audio", "x-codec2", NULL,
413 codec2_init, codec2_finish, codec2_transform_encode,
416 struct codec_fun decoder_codec2_2000 = {
417 "audio", "x-codec2", NULL,
419 codec2_init, codec2_finish, codec2_transform_decode,
422 struct codec_fun encoder_codec2_2400 = {
423 "audio", "x-codec2", NULL,
425 codec2_init, codec2_finish, codec2_transform_encode,
428 struct codec_fun decoder_codec2_2400 = {
429 "audio", "x-codec2", NULL,
431 codec2_init, codec2_finish, codec2_transform_decode,
434 struct codec_fun encoder_codec2_2550 = {
435 "audio", "x-codec2", NULL,
437 codec2_init, codec2_finish, codec2_transform_encode,
440 struct codec_fun decoder_codec2_2550 = {
441 "audio", "x-codec2", NULL,
443 codec2_init, codec2_finish, codec2_transform_decode,
449 /********** TELEPHONE EVENT DEFINITIONS **********/
451 #ifdef CONFIG_SIP_PHONE
452 struct codec_fun encodor_televt = {
453 "audio", "telephone-event", "0-16",
455 NULL, NULL, NULL, /*TODO*/
458 struct codec_fun decoder_televt = {
459 "audio", "telephone-event", "0-16",
461 NULL, NULL, NULL, /*TODO*/
466 /********** REALTIME TEXT DEFINITIONS **********/
468 #ifdef CONFIG_CODEC_RTT
469 struct codec_fun encoder_rtt = {
470 "text", "t140", "cps=1000",
472 NULL, NULL, NULL, /*TODO*/
475 struct codec_fun decoder_rtt = {
476 "text", "t140", "cps=1000",
478 NULL, NULL, NULL, /*TODO*/
481 struct codec_fun encoder_rtt_red = {
482 "text", "red", "98/98/98",
484 NULL, NULL, NULL, /*TODO*/
487 struct codec_fun decoder_rtt_red = {
488 "text", "red", "98/98/98",
490 NULL, NULL, NULL, /*TODO*/
495 #ifdef CONFIG_MULTICAST_CODEC_RTT
496 struct codec_fun decoder_mcast_rtt = {
497 "text", "t140", "cps=1000",
499 NULL, NULL, NULL, /*TODO*/
502 struct codec_fun decoder_mcast_rtt_red = {
503 "text", "red", "98/98/98",
505 NULL, NULL, NULL, /*TODO*/
510 #ifdef CONFIG_MULTICAST_CODEC_L16
511 struct codec_fun decoder_mcast_l16 = {
512 "audio", "L16", NULL,
514 NULL, NULL, NULL, /*TODO*/
519 #ifdef CONFIG_MULTICAST_CODEC_VORBIS
520 struct codec_fun decoder_mcast_vorbis = {
521 "audio", "vorbis", "configuration=TODO:RFC5215",
523 NULL, NULL, NULL, /*TODO*/
530 /********** SDP SUPPORT THROUGH CODEC LIST STRUCTURES **********/
532 struct codec_fun *codec_phone_audio_encoders [] = {
533 #ifdef CONFIG_CODEC_SPEEX_ULTRAWIDEBAND
534 &encoder_speex_ultra,
536 #ifdef CONFIG_CODEC_SPEEX_WIDEBAND
539 #ifdef CONFIG_CODEC_G722
541 &encoder_g722_historically_incorrect,
543 #ifdef CONFIG_CODEC_SPEEX_NARROWBAND
544 &encoder_speex_narrow,
546 #ifdef CONFIG_CODEC_G726
549 #ifdef CONFIG_CODEC_G711
550 &encoder_g711_ulaw, /* 14 bits */
551 &encoder_g711_alaw, /* 13 bits */
553 #ifdef CONFIG_CODEC_CODEC2
556 #ifdef CONFIG_SIP_PHONE
562 struct codec_fun *codec_phone_audio_decoders [] = {
563 #ifdef CONFIG_CODEC_SPEEX_ULTRAWIDEBAND
564 &decoder_speex_ultra,
566 #ifdef CONFIG_CODEC_SPEEX_WIDEBAND
569 #ifdef CONFIG_CODEC_G722
571 &decoder_g722_historically_incorrect,
573 #ifdef CONFIG_CODEC_SPEEX_NARROWBAND
574 &decoder_speex_narrow,
576 #ifdef CONFIG_CODEC_G726
579 #ifdef CONFIG_CODEC_G711
580 &decoder_g711_ulaw, /* 14 bits */
581 &decoder_g711_alaw, /* 13 bits */
583 #ifdef CONFIG_CODEC_CODEC2
586 #ifdef CONFIG_SIP_PHONE
592 struct codec_fun *codec_phone_video_encoders [] = {
596 struct codec_fun *codec_phone_video_decoders [] = {
600 struct codec_fun *codec_phone_text_encoders [] = {
601 #ifdef CONFIG_CODEC_RTT
608 struct codec_fun *codec_phone_text_decoders [] = {
609 #ifdef CONFIG_CODEC_RTT
616 struct codec_fun *codec_mcast_audio_decoders [] = {
617 #ifdef CONFIG_MULTICAST_CODEC_L16
620 #ifdef CONFIG_MULTICAST_CODEC_VORBIS
621 &decoder_mcast_vorbis,
623 #ifdef CONFIG_MULTICAST_CODEC_SPEEX
624 &decoder_mcast_speex,
629 struct codec_fun *codec_mcast_video_decoders [] = {
633 struct codec_fun *codec_mcast_text_decoders [] = {
634 #ifdef CONFIG_CODEC_RTT