1
/* $Id: ilbc.c 3664 2011-07-19 03:42:28Z nanang $ */
3
* Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
4
* Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
6
* This program 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 2 of the License, or
9
* (at your option) any later version.
11
* This program 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.
16
* You should have received a copy of the GNU General Public License
17
* along with this program; if not, write to the Free Software
18
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20
#include <pjmedia-codec/ilbc.h>
21
#include <pjmedia-codec/types.h>
22
#include <pjmedia/codec.h>
23
#include <pjmedia/errno.h>
24
#include <pjmedia/endpoint.h>
25
#include <pjmedia/plc.h>
26
#include <pjmedia/port.h>
27
#include <pjmedia/silencedet.h>
28
#include <pj/assert.h>
31
#include <pj/string.h>
34
#if defined(PJMEDIA_ILBC_CODEC_USE_COREAUDIO)&& PJMEDIA_ILBC_CODEC_USE_COREAUDIO
35
#include <AudioToolbox/AudioToolbox.h>
36
#define iLBC_Enc_Inst_t AudioConverterRef
37
#define iLBC_Dec_Inst_t AudioConverterRef
40
#include "../../third_party/ilbc/iLBC_encode.h"
41
#include "../../third_party/ilbc/iLBC_decode.h"
45
* Only build this file if PJMEDIA_HAS_ILBC_CODEC != 0
47
#if defined(PJMEDIA_HAS_ILBC_CODEC) && PJMEDIA_HAS_ILBC_CODEC != 0
50
#define THIS_FILE "ilbc.c"
51
#define CLOCK_RATE 8000
52
#define DEFAULT_MODE 30
55
/* Prototypes for iLBC factory */
56
static pj_status_t ilbc_test_alloc(pjmedia_codec_factory *factory,
57
const pjmedia_codec_info *id );
58
static pj_status_t ilbc_default_attr(pjmedia_codec_factory *factory,
59
const pjmedia_codec_info *id,
60
pjmedia_codec_param *attr );
61
static pj_status_t ilbc_enum_codecs(pjmedia_codec_factory *factory,
63
pjmedia_codec_info codecs[]);
64
static pj_status_t ilbc_alloc_codec(pjmedia_codec_factory *factory,
65
const pjmedia_codec_info *id,
66
pjmedia_codec **p_codec);
67
static pj_status_t ilbc_dealloc_codec(pjmedia_codec_factory *factory,
68
pjmedia_codec *codec );
70
/* Prototypes for iLBC implementation. */
71
static pj_status_t ilbc_codec_init(pjmedia_codec *codec,
73
static pj_status_t ilbc_codec_open(pjmedia_codec *codec,
74
pjmedia_codec_param *attr );
75
static pj_status_t ilbc_codec_close(pjmedia_codec *codec );
76
static pj_status_t ilbc_codec_modify(pjmedia_codec *codec,
77
const pjmedia_codec_param *attr );
78
static pj_status_t ilbc_codec_parse(pjmedia_codec *codec,
81
const pj_timestamp *ts,
83
pjmedia_frame frames[]);
84
static pj_status_t ilbc_codec_encode(pjmedia_codec *codec,
85
const struct pjmedia_frame *input,
86
unsigned output_buf_len,
87
struct pjmedia_frame *output);
88
static pj_status_t ilbc_codec_decode(pjmedia_codec *codec,
89
const struct pjmedia_frame *input,
90
unsigned output_buf_len,
91
struct pjmedia_frame *output);
92
static pj_status_t ilbc_codec_recover(pjmedia_codec *codec,
93
unsigned output_buf_len,
94
struct pjmedia_frame *output);
96
/* Definition for iLBC codec operations. */
97
static pjmedia_codec_op ilbc_op =
109
/* Definition for iLBC codec factory operations. */
110
static pjmedia_codec_factory_op ilbc_factory_op =
117
&pjmedia_codec_ilbc_deinit
121
static struct ilbc_factory
123
pjmedia_codec_factory base;
124
pjmedia_endpt *endpt;
131
/* iLBC codec private data. */
136
char obj_name[PJ_MAX_OBJ_NAME];
137
pjmedia_silence_det *vad;
138
pj_bool_t vad_enabled;
139
pj_bool_t plc_enabled;
140
pj_timestamp last_tx;
145
unsigned enc_frame_size;
146
unsigned enc_samples_per_frame;
147
float enc_block[BLOCKL_MAX];
151
unsigned dec_frame_size;
152
unsigned dec_samples_per_frame;
153
float dec_block[BLOCKL_MAX];
155
#if defined(PJMEDIA_ILBC_CODEC_USE_COREAUDIO)&& PJMEDIA_ILBC_CODEC_USE_COREAUDIO
156
unsigned enc_total_packets;
158
unsigned enc_buffer_offset;
160
unsigned dec_total_packets;
162
unsigned dec_buffer_offset;
166
static pj_str_t STR_MODE = {"mode", 4};
169
* Initialize and register iLBC codec factory to pjmedia endpoint.
171
PJ_DEF(pj_status_t) pjmedia_codec_ilbc_init( pjmedia_endpt *endpt,
174
pjmedia_codec_mgr *codec_mgr;
177
PJ_ASSERT_RETURN(endpt != NULL, PJ_EINVAL);
178
PJ_ASSERT_RETURN(mode==0 || mode==20 || mode==30, PJ_EINVAL);
180
/* Create iLBC codec factory. */
181
ilbc_factory.base.op = &ilbc_factory_op;
182
ilbc_factory.base.factory_data = NULL;
183
ilbc_factory.endpt = endpt;
188
ilbc_factory.mode = mode;
191
ilbc_factory.bps = 15200;
193
ilbc_factory.bps = 13333;
196
/* Get the codec manager. */
197
codec_mgr = pjmedia_endpt_get_codec_mgr(endpt);
199
return PJ_EINVALIDOP;
201
/* Register codec factory to endpoint. */
202
status = pjmedia_codec_mgr_register_factory(codec_mgr,
204
if (status != PJ_SUCCESS)
215
* Unregister iLBC codec factory from pjmedia endpoint and deinitialize
216
* the iLBC codec library.
218
PJ_DEF(pj_status_t) pjmedia_codec_ilbc_deinit(void)
220
pjmedia_codec_mgr *codec_mgr;
224
/* Get the codec manager. */
225
codec_mgr = pjmedia_endpt_get_codec_mgr(ilbc_factory.endpt);
227
return PJ_EINVALIDOP;
229
/* Unregister iLBC codec factory. */
230
status = pjmedia_codec_mgr_unregister_factory(codec_mgr,
237
* Check if factory can allocate the specified codec.
239
static pj_status_t ilbc_test_alloc( pjmedia_codec_factory *factory,
240
const pjmedia_codec_info *info )
242
const pj_str_t ilbc_tag = { "iLBC", 4};
244
PJ_UNUSED_ARG(factory);
245
PJ_ASSERT_RETURN(factory==&ilbc_factory.base, PJ_EINVAL);
248
/* Type MUST be audio. */
249
if (info->type != PJMEDIA_TYPE_AUDIO)
250
return PJMEDIA_CODEC_EUNSUP;
252
/* Check encoding name. */
253
if (pj_stricmp(&info->encoding_name, &ilbc_tag) != 0)
254
return PJMEDIA_CODEC_EUNSUP;
256
/* Check clock-rate */
257
if (info->clock_rate != CLOCK_RATE)
258
return PJMEDIA_CODEC_EUNSUP;
260
/* Channel count must be one */
261
if (info->channel_cnt != 1)
262
return PJMEDIA_CODEC_EUNSUP;
264
/* Yes, this should be iLBC! */
270
* Generate default attribute.
272
static pj_status_t ilbc_default_attr (pjmedia_codec_factory *factory,
273
const pjmedia_codec_info *id,
274
pjmedia_codec_param *attr )
276
PJ_UNUSED_ARG(factory);
277
PJ_ASSERT_RETURN(factory==&ilbc_factory.base, PJ_EINVAL);
280
PJ_ASSERT_RETURN(pj_stricmp2(&id->encoding_name, "iLBC")==0, PJ_EINVAL);
282
pj_bzero(attr, sizeof(pjmedia_codec_param));
284
attr->info.clock_rate = CLOCK_RATE;
285
attr->info.channel_cnt = 1;
286
attr->info.avg_bps = ilbc_factory.bps;
287
attr->info.max_bps = 15200;
288
attr->info.pcm_bits_per_sample = 16;
289
attr->info.frm_ptime = (short)ilbc_factory.mode;
290
attr->info.pt = PJMEDIA_RTP_PT_ILBC;
292
attr->setting.frm_per_pkt = 1;
293
attr->setting.vad = 1;
294
attr->setting.plc = 1;
295
attr->setting.penh = 1;
296
attr->setting.dec_fmtp.cnt = 1;
297
attr->setting.dec_fmtp.param[0].name = STR_MODE;
298
if (ilbc_factory.mode == 30)
299
attr->setting.dec_fmtp.param[0].val = pj_str("30");
301
attr->setting.dec_fmtp.param[0].val = pj_str("20");
307
* Enum codecs supported by this factory (i.e. only iLBC!).
309
static pj_status_t ilbc_enum_codecs(pjmedia_codec_factory *factory,
311
pjmedia_codec_info codecs[])
313
PJ_UNUSED_ARG(factory);
314
PJ_ASSERT_RETURN(factory==&ilbc_factory.base, PJ_EINVAL);
316
PJ_ASSERT_RETURN(codecs && *count > 0, PJ_EINVAL);
318
pj_bzero(&codecs[0], sizeof(pjmedia_codec_info));
320
codecs[0].encoding_name = pj_str("iLBC");
321
codecs[0].pt = PJMEDIA_RTP_PT_ILBC;
322
codecs[0].type = PJMEDIA_TYPE_AUDIO;
323
codecs[0].clock_rate = 8000;
324
codecs[0].channel_cnt = 1;
332
* Allocate a new iLBC codec instance.
334
static pj_status_t ilbc_alloc_codec(pjmedia_codec_factory *factory,
335
const pjmedia_codec_info *id,
336
pjmedia_codec **p_codec)
339
struct ilbc_codec *codec;
341
PJ_ASSERT_RETURN(factory && id && p_codec, PJ_EINVAL);
342
PJ_ASSERT_RETURN(factory == &ilbc_factory.base, PJ_EINVAL);
344
pool = pjmedia_endpt_create_pool(ilbc_factory.endpt, "iLBC%p",
346
PJ_ASSERT_RETURN(pool != NULL, PJ_ENOMEM);
348
codec = PJ_POOL_ZALLOC_T(pool, struct ilbc_codec);
349
codec->base.op = &ilbc_op;
350
codec->base.factory = factory;
353
pj_ansi_snprintf(codec->obj_name, sizeof(codec->obj_name),
356
*p_codec = &codec->base;
364
static pj_status_t ilbc_dealloc_codec( pjmedia_codec_factory *factory,
365
pjmedia_codec *codec )
367
struct ilbc_codec *ilbc_codec;
369
PJ_ASSERT_RETURN(factory && codec, PJ_EINVAL);
370
PJ_UNUSED_ARG(factory);
371
PJ_ASSERT_RETURN(factory == &ilbc_factory.base, PJ_EINVAL);
373
ilbc_codec = (struct ilbc_codec*) codec;
375
#if defined(PJMEDIA_ILBC_CODEC_USE_COREAUDIO)&& PJMEDIA_ILBC_CODEC_USE_COREAUDIO
376
if (ilbc_codec->enc) {
377
AudioConverterDispose(ilbc_codec->enc);
378
ilbc_codec->enc = NULL;
380
if (ilbc_codec->dec) {
381
AudioConverterDispose(ilbc_codec->dec);
382
ilbc_codec->dec = NULL;
386
pj_pool_release(ilbc_codec->pool);
394
static pj_status_t ilbc_codec_init(pjmedia_codec *codec,
397
PJ_UNUSED_ARG(codec);
405
static pj_status_t ilbc_codec_open(pjmedia_codec *codec,
406
pjmedia_codec_param *attr )
408
struct ilbc_codec *ilbc_codec = (struct ilbc_codec*)codec;
411
pj_uint16_t dec_fmtp_mode = DEFAULT_MODE,
412
enc_fmtp_mode = DEFAULT_MODE;
414
#if defined(PJMEDIA_ILBC_CODEC_USE_COREAUDIO)&& PJMEDIA_ILBC_CODEC_USE_COREAUDIO
415
AudioStreamBasicDescription srcFormat, dstFormat;
418
srcFormat.mSampleRate = attr->info.clock_rate;
419
srcFormat.mFormatID = kAudioFormatLinearPCM;
420
srcFormat.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger
421
| kLinearPCMFormatFlagIsPacked;
422
srcFormat.mBitsPerChannel = attr->info.pcm_bits_per_sample;
423
srcFormat.mChannelsPerFrame = attr->info.channel_cnt;
424
srcFormat.mBytesPerFrame = srcFormat.mChannelsPerFrame
425
* srcFormat.mBitsPerChannel >> 3;
426
srcFormat.mFramesPerPacket = 1;
427
srcFormat.mBytesPerPacket = srcFormat.mBytesPerFrame *
428
srcFormat.mFramesPerPacket;
430
memset(&dstFormat, 0, sizeof(dstFormat));
431
dstFormat.mSampleRate = attr->info.clock_rate;
432
dstFormat.mFormatID = kAudioFormatiLBC;
433
dstFormat.mChannelsPerFrame = attr->info.channel_cnt;
436
pj_assert(ilbc_codec != NULL);
437
pj_assert(ilbc_codec->enc_ready == PJ_FALSE &&
438
ilbc_codec->dec_ready == PJ_FALSE);
440
/* Get decoder mode */
441
for (i = 0; i < attr->setting.dec_fmtp.cnt; ++i) {
442
if (pj_stricmp(&attr->setting.dec_fmtp.param[i].name, &STR_MODE) == 0)
444
dec_fmtp_mode = (pj_uint16_t)
445
pj_strtoul(&attr->setting.dec_fmtp.param[i].val);
450
/* Decoder mode must be set */
451
PJ_ASSERT_RETURN(dec_fmtp_mode == 20 || dec_fmtp_mode == 30,
452
PJMEDIA_CODEC_EINMODE);
454
/* Get encoder mode */
455
for (i = 0; i < attr->setting.enc_fmtp.cnt; ++i) {
456
if (pj_stricmp(&attr->setting.enc_fmtp.param[i].name, &STR_MODE) == 0)
458
enc_fmtp_mode = (pj_uint16_t)
459
pj_strtoul(&attr->setting.enc_fmtp.param[i].val);
464
PJ_ASSERT_RETURN(enc_fmtp_mode==20 || enc_fmtp_mode==30,
465
PJMEDIA_CODEC_EINMODE);
467
/* Both sides of a bi-directional session MUST use the same "mode" value.
468
* In this point, possible values are only 20 or 30, so when encoder and
469
* decoder modes are not same, just use the default mode, it is 30.
471
if (enc_fmtp_mode != dec_fmtp_mode) {
472
enc_fmtp_mode = dec_fmtp_mode = DEFAULT_MODE;
473
PJ_LOG(4,(ilbc_codec->obj_name,
474
"Normalized iLBC encoder and decoder modes to %d",
478
/* Update some attributes based on negotiated mode. */
479
attr->info.avg_bps = (dec_fmtp_mode == 30? 13333 : 15200);
480
attr->info.frm_ptime = dec_fmtp_mode;
483
#if defined(PJMEDIA_ILBC_CODEC_USE_COREAUDIO)&& PJMEDIA_ILBC_CODEC_USE_COREAUDIO
484
dstFormat.mFramesPerPacket = CLOCK_RATE * enc_fmtp_mode / 1000;
485
dstFormat.mBytesPerPacket = (enc_fmtp_mode == 20? 38 : 50);
487
/* Use AudioFormat API to fill out the rest of the description */
488
size = sizeof(dstFormat);
489
AudioFormatGetProperty(kAudioFormatProperty_FormatInfo,
490
0, NULL, &size, &dstFormat);
492
if (AudioConverterNew(&srcFormat, &dstFormat, &ilbc_codec->enc) != noErr)
493
return PJMEDIA_CODEC_EFAILED;
494
ilbc_codec->enc_frame_size = (enc_fmtp_mode == 20? 38 : 50);
496
ilbc_codec->enc_frame_size = initEncode(&ilbc_codec->enc, enc_fmtp_mode);
498
ilbc_codec->enc_samples_per_frame = CLOCK_RATE * enc_fmtp_mode / 1000;
499
ilbc_codec->enc_ready = PJ_TRUE;
502
#if defined(PJMEDIA_ILBC_CODEC_USE_COREAUDIO)&& PJMEDIA_ILBC_CODEC_USE_COREAUDIO
503
if (AudioConverterNew(&dstFormat, &srcFormat, &ilbc_codec->dec) != noErr)
504
return PJMEDIA_CODEC_EFAILED;
505
ilbc_codec->dec_samples_per_frame = CLOCK_RATE * dec_fmtp_mode / 1000;
507
ilbc_codec->dec_samples_per_frame = initDecode(&ilbc_codec->dec,
511
ilbc_codec->dec_frame_size = (dec_fmtp_mode == 20? 38 : 50);
512
ilbc_codec->dec_ready = PJ_TRUE;
515
ilbc_codec->plc_enabled = (attr->setting.plc != 0);
517
/* Create silence detector. */
518
ilbc_codec->vad_enabled = (attr->setting.vad != 0);
519
status = pjmedia_silence_det_create(ilbc_codec->pool, CLOCK_RATE,
520
ilbc_codec->enc_samples_per_frame,
522
if (status != PJ_SUCCESS)
525
/* Init last_tx (not necessary because of zalloc, but better
526
* be safe in case someone remove zalloc later.
528
pj_set_timestamp32(&ilbc_codec->last_tx, 0, 0);
530
PJ_LOG(5,(ilbc_codec->obj_name,
531
"iLBC codec opened, mode=%d", dec_fmtp_mode));
540
static pj_status_t ilbc_codec_close( pjmedia_codec *codec )
542
struct ilbc_codec *ilbc_codec = (struct ilbc_codec*)codec;
544
PJ_UNUSED_ARG(codec);
546
PJ_LOG(5,(ilbc_codec->obj_name, "iLBC codec closed"));
552
* Modify codec settings.
554
static pj_status_t ilbc_codec_modify(pjmedia_codec *codec,
555
const pjmedia_codec_param *attr )
557
struct ilbc_codec *ilbc_codec = (struct ilbc_codec*)codec;
559
ilbc_codec->plc_enabled = (attr->setting.plc != 0);
560
ilbc_codec->vad_enabled = (attr->setting.vad != 0);
566
* Get frames in the packet.
568
static pj_status_t ilbc_codec_parse( pjmedia_codec *codec,
571
const pj_timestamp *ts,
573
pjmedia_frame frames[])
575
struct ilbc_codec *ilbc_codec = (struct ilbc_codec*)codec;
578
PJ_ASSERT_RETURN(frame_cnt, PJ_EINVAL);
581
while (pkt_size >= ilbc_codec->dec_frame_size && count < *frame_cnt) {
582
frames[count].type = PJMEDIA_FRAME_TYPE_AUDIO;
583
frames[count].buf = pkt;
584
frames[count].size = ilbc_codec->dec_frame_size;
585
frames[count].timestamp.u64 = ts->u64 + count *
586
ilbc_codec->dec_samples_per_frame;
588
pkt = ((char*)pkt) + ilbc_codec->dec_frame_size;
589
pkt_size -= ilbc_codec->dec_frame_size;
598
#if defined(PJMEDIA_ILBC_CODEC_USE_COREAUDIO)&& PJMEDIA_ILBC_CODEC_USE_COREAUDIO
599
static OSStatus encodeDataProc (
600
AudioConverterRef inAudioConverter,
601
UInt32 *ioNumberDataPackets,
602
AudioBufferList *ioData,
603
AudioStreamPacketDescription **outDataPacketDescription,
607
struct ilbc_codec *ilbc_codec = (struct ilbc_codec*)inUserData;
609
/* Initialize in case of failure */
610
ioData->mBuffers[0].mData = NULL;
611
ioData->mBuffers[0].mDataByteSize = 0;
613
if (ilbc_codec->enc_total_packets < *ioNumberDataPackets) {
614
*ioNumberDataPackets = ilbc_codec->enc_total_packets;
617
if (*ioNumberDataPackets) {
618
ioData->mBuffers[0].mData = ilbc_codec->enc_buffer +
619
ilbc_codec->enc_buffer_offset;
620
ioData->mBuffers[0].mDataByteSize = *ioNumberDataPackets *
621
ilbc_codec->enc_samples_per_frame
623
ilbc_codec->enc_buffer_offset += ioData->mBuffers[0].mDataByteSize;
626
ilbc_codec->enc_total_packets -= *ioNumberDataPackets;
630
static OSStatus decodeDataProc (
631
AudioConverterRef inAudioConverter,
632
UInt32 *ioNumberDataPackets,
633
AudioBufferList *ioData,
634
AudioStreamPacketDescription **outDataPacketDescription,
638
struct ilbc_codec *ilbc_codec = (struct ilbc_codec*)inUserData;
640
/* Initialize in case of failure */
641
ioData->mBuffers[0].mData = NULL;
642
ioData->mBuffers[0].mDataByteSize = 0;
644
if (ilbc_codec->dec_total_packets < *ioNumberDataPackets) {
645
*ioNumberDataPackets = ilbc_codec->dec_total_packets;
648
if (*ioNumberDataPackets) {
649
ioData->mBuffers[0].mData = ilbc_codec->dec_buffer +
650
ilbc_codec->dec_buffer_offset;
651
ioData->mBuffers[0].mDataByteSize = *ioNumberDataPackets *
652
ilbc_codec->dec_frame_size;
653
ilbc_codec->dec_buffer_offset += ioData->mBuffers[0].mDataByteSize;
656
ilbc_codec->dec_total_packets -= *ioNumberDataPackets;
664
static pj_status_t ilbc_codec_encode(pjmedia_codec *codec,
665
const struct pjmedia_frame *input,
666
unsigned output_buf_len,
667
struct pjmedia_frame *output)
669
struct ilbc_codec *ilbc_codec = (struct ilbc_codec*)codec;
672
#if defined(PJMEDIA_ILBC_CODEC_USE_COREAUDIO)&& PJMEDIA_ILBC_CODEC_USE_COREAUDIO
675
AudioBufferList theABL;
678
pj_assert(ilbc_codec && input && output);
680
pcm_in = (pj_int16_t*)input->buf;
681
nsamples = input->size >> 1;
683
PJ_ASSERT_RETURN(nsamples % ilbc_codec->enc_samples_per_frame == 0,
684
PJMEDIA_CODEC_EPCMFRMINLEN);
685
PJ_ASSERT_RETURN(output_buf_len >= ilbc_codec->enc_frame_size * nsamples /
686
ilbc_codec->enc_samples_per_frame,
687
PJMEDIA_CODEC_EFRMTOOSHORT);
690
if (ilbc_codec->vad_enabled) {
691
pj_bool_t is_silence;
692
pj_int32_t silence_period;
694
silence_period = pj_timestamp_diff32(&ilbc_codec->last_tx,
697
is_silence = pjmedia_silence_det_detect(ilbc_codec->vad,
698
(const pj_int16_t*)input->buf,
702
(PJMEDIA_CODEC_MAX_SILENCE_PERIOD == -1 ||
703
silence_period < PJMEDIA_CODEC_MAX_SILENCE_PERIOD*8000/1000))
705
output->type = PJMEDIA_FRAME_TYPE_NONE;
708
output->timestamp = input->timestamp;
711
ilbc_codec->last_tx = input->timestamp;
717
#if defined(PJMEDIA_ILBC_CODEC_USE_COREAUDIO)&& PJMEDIA_ILBC_CODEC_USE_COREAUDIO
718
npackets = nsamples / ilbc_codec->enc_samples_per_frame;
720
theABL.mNumberBuffers = 1;
721
theABL.mBuffers[0].mNumberChannels = 1;
722
theABL.mBuffers[0].mDataByteSize = output_buf_len;
723
theABL.mBuffers[0].mData = output->buf;
725
ilbc_codec->enc_total_packets = npackets;
726
ilbc_codec->enc_buffer = (char *)input->buf;
727
ilbc_codec->enc_buffer_offset = 0;
729
err = AudioConverterFillComplexBuffer(ilbc_codec->enc, encodeDataProc,
730
ilbc_codec, &npackets,
733
output->size = npackets * ilbc_codec->enc_frame_size;
736
while (nsamples >= ilbc_codec->enc_samples_per_frame) {
739
/* Convert to float */
740
for (i=0; i<ilbc_codec->enc_samples_per_frame; ++i) {
741
ilbc_codec->enc_block[i] = (float) (*pcm_in++);
744
iLBC_encode((unsigned char *)output->buf + output->size,
745
ilbc_codec->enc_block,
748
output->size += ilbc_codec->enc.no_of_bytes;
749
nsamples -= ilbc_codec->enc_samples_per_frame;
753
output->type = PJMEDIA_FRAME_TYPE_AUDIO;
754
output->timestamp = input->timestamp;
762
static pj_status_t ilbc_codec_decode(pjmedia_codec *codec,
763
const struct pjmedia_frame *input,
764
unsigned output_buf_len,
765
struct pjmedia_frame *output)
767
struct ilbc_codec *ilbc_codec = (struct ilbc_codec*)codec;
768
#if defined(PJMEDIA_ILBC_CODEC_USE_COREAUDIO)&& PJMEDIA_ILBC_CODEC_USE_COREAUDIO
771
AudioBufferList theABL;
776
pj_assert(ilbc_codec != NULL);
777
PJ_ASSERT_RETURN(input && output, PJ_EINVAL);
779
if (output_buf_len < (ilbc_codec->dec_samples_per_frame << 1))
780
return PJMEDIA_CODEC_EPCMTOOSHORT;
782
if (input->size != ilbc_codec->dec_frame_size)
783
return PJMEDIA_CODEC_EFRMINLEN;
785
/* Decode to temporary buffer */
786
#if defined(PJMEDIA_ILBC_CODEC_USE_COREAUDIO)&& PJMEDIA_ILBC_CODEC_USE_COREAUDIO
787
npackets = input->size / ilbc_codec->dec_frame_size *
788
ilbc_codec->dec_samples_per_frame;
790
theABL.mNumberBuffers = 1;
791
theABL.mBuffers[0].mNumberChannels = 1;
792
theABL.mBuffers[0].mDataByteSize = output_buf_len;
793
theABL.mBuffers[0].mData = output->buf;
795
ilbc_codec->dec_total_packets = npackets;
796
ilbc_codec->dec_buffer = (char *)input->buf;
797
ilbc_codec->dec_buffer_offset = 0;
799
err = AudioConverterFillComplexBuffer(ilbc_codec->dec, decodeDataProc,
800
ilbc_codec, &npackets,
803
output->size = npackets * (ilbc_codec->dec_samples_per_frame << 1);
806
iLBC_decode(ilbc_codec->dec_block, (unsigned char*) input->buf,
807
&ilbc_codec->dec, 1);
809
/* Convert decodec samples from float to short */
810
for (i=0; i<ilbc_codec->dec_samples_per_frame; ++i) {
811
((short*)output->buf)[i] = (short)ilbc_codec->dec_block[i];
813
output->size = (ilbc_codec->dec_samples_per_frame << 1);
816
output->type = PJMEDIA_FRAME_TYPE_AUDIO;
817
output->timestamp = input->timestamp;
824
* Recover lost frame.
826
static pj_status_t ilbc_codec_recover(pjmedia_codec *codec,
827
unsigned output_buf_len,
828
struct pjmedia_frame *output)
830
struct ilbc_codec *ilbc_codec = (struct ilbc_codec*)codec;
831
#if defined(PJMEDIA_ILBC_CODEC_USE_COREAUDIO)&& PJMEDIA_ILBC_CODEC_USE_COREAUDIO
834
AudioBufferList theABL;
839
pj_assert(ilbc_codec != NULL);
840
PJ_ASSERT_RETURN(output, PJ_EINVAL);
842
if (output_buf_len < (ilbc_codec->dec_samples_per_frame << 1))
843
return PJMEDIA_CODEC_EPCMTOOSHORT;
845
/* Decode to temporary buffer */
846
#if defined(PJMEDIA_ILBC_CODEC_USE_COREAUDIO)&& PJMEDIA_ILBC_CODEC_USE_COREAUDIO
849
theABL.mNumberBuffers = 1;
850
theABL.mBuffers[0].mNumberChannels = 1;
851
theABL.mBuffers[0].mDataByteSize = output_buf_len;
852
theABL.mBuffers[0].mData = output->buf;
854
ilbc_codec->dec_total_packets = npackets;
855
ilbc_codec->dec_buffer_offset = 0;
856
if (ilbc_codec->dec_buffer) {
857
err = AudioConverterFillComplexBuffer(ilbc_codec->dec, decodeDataProc,
858
ilbc_codec, &npackets,
861
output->size = npackets *
862
(ilbc_codec->dec_samples_per_frame << 1);
865
output->size = npackets * (ilbc_codec->dec_samples_per_frame << 1);
866
pj_bzero(output->buf, output->size);
869
iLBC_decode(ilbc_codec->dec_block, NULL, &ilbc_codec->dec, 0);
871
/* Convert decodec samples from float to short */
872
for (i=0; i<ilbc_codec->dec_samples_per_frame; ++i) {
873
((short*)output->buf)[i] = (short)ilbc_codec->dec_block[i];
875
output->size = (ilbc_codec->dec_samples_per_frame << 1);
877
output->type = PJMEDIA_FRAME_TYPE_AUDIO;
883
#endif /* PJMEDIA_HAS_ILBC_CODEC */