~ubuntu-branches/ubuntu/saucy/sflphone/saucy

« back to all changes in this revision

Viewing changes to sflphone-common/libs/pjproject/pjmedia/src/pjmedia-audiodev/symb_vas_dev.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Francois Marier
  • Date: 2010-12-24 16:33:55 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20101224163355-tkvvikqxbrbav6up
Tags: 0.9.11-1
* New upstream release
* Add new build dependencies on libwebkit-dev and libyaml-dev

* Bump Standards-Version up to 3.9.1
* Bump debhelper compatibility to 8
* Patch another typo in the upstream code (lintian notice)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/* $Id: symb_vas_dev.cpp 3025 2009-11-24 12:24:35Z nanang $ */
2
 
/* 
 
2
/*
3
3
 * Copyright (C) 2009 Teluu Inc. (http://www.teluu.com)
4
4
 *
5
5
 * This program is free software; you can redistribute it and/or modify
14
14
 *
15
15
 * You should have received a copy of the GNU General Public License
16
16
 * along with this program; if not, write to the Free Software
17
 
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
 
17
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18
18
 *
19
19
 *  Additional permission under GNU GPL version 3 section 7:
20
20
 *
51
51
#include <VoIPILBCDecoderIntfc.h>
52
52
#include <VoIPILBCEncoderIntfc.h>
53
53
 
54
 
/* AMR helper */  
 
54
/* AMR helper */
55
55
#include <pjmedia-codec/amr_helper.h>
56
56
 
57
 
/* Pack/unpack G.729 frame of S60 DSP codec, taken from:  
 
57
/* Pack/unpack G.729 frame of S60 DSP codec, taken from:
58
58
 * http://wiki.forum.nokia.com/index.php/TSS000776_-_Payload_conversion_for_G.729_audio_format
59
59
 */
60
60
#include "s60_g729_bitstream.h"
81
81
 
82
82
 
83
83
/* VAS factory */
84
 
struct vas_factory
85
 
{
 
84
struct vas_factory {
86
85
    pjmedia_aud_dev_factory      base;
87
86
    pj_pool_t                   *pool;
88
87
    pj_pool_factory             *pf;
95
94
 
96
95
 
97
96
/* VAS stream. */
98
 
struct vas_stream
99
 
{
 
97
struct vas_stream {
100
98
    // Base
101
99
    pjmedia_aud_stream   base;                  /**< Base class.        */
102
 
    
 
100
 
103
101
    // Pool
104
102
    pj_pool_t           *pool;                  /**< Memory pool.       */
105
103
 
122
120
    pj_uint16_t          rec_buf_len;           /**< Record buffer length. */
123
121
    void                *strm_data;             /**< Stream data.       */
124
122
 
125
 
    /* Resampling is needed, in case audio device is opened with clock rate 
 
123
    /* Resampling is needed, in case audio device is opened with clock rate
126
124
     * other than 8kHz (only for PCM format).
127
125
     */
128
126
    pjmedia_resample    *play_resample;         /**< Resampler for playback. */
139
137
 
140
138
 
141
139
/* Prototypes */
142
 
static pj_status_t factory_init(pjmedia_aud_dev_factory *f);
143
 
static pj_status_t factory_destroy(pjmedia_aud_dev_factory *f);
144
 
static unsigned    factory_get_dev_count(pjmedia_aud_dev_factory *f);
145
 
static pj_status_t factory_get_dev_info(pjmedia_aud_dev_factory *f, 
146
 
                                        unsigned index,
147
 
                                        pjmedia_aud_dev_info *info);
148
 
static pj_status_t factory_default_param(pjmedia_aud_dev_factory *f,
149
 
                                         unsigned index,
150
 
                                         pjmedia_aud_param *param);
151
 
static pj_status_t factory_create_stream(pjmedia_aud_dev_factory *f,
152
 
                                         const pjmedia_aud_param *param,
153
 
                                         pjmedia_aud_rec_cb rec_cb,
154
 
                                         pjmedia_aud_play_cb play_cb,
155
 
                                         void *user_data,
156
 
                                         pjmedia_aud_stream **p_aud_strm);
 
140
static pj_status_t factory_init (pjmedia_aud_dev_factory *f);
 
141
static pj_status_t factory_destroy (pjmedia_aud_dev_factory *f);
 
142
static unsigned    factory_get_dev_count (pjmedia_aud_dev_factory *f);
 
143
static pj_status_t factory_get_dev_info (pjmedia_aud_dev_factory *f,
 
144
        unsigned index,
 
145
        pjmedia_aud_dev_info *info);
 
146
static pj_status_t factory_default_param (pjmedia_aud_dev_factory *f,
 
147
        unsigned index,
 
148
        pjmedia_aud_param *param);
 
149
static pj_status_t factory_create_stream (pjmedia_aud_dev_factory *f,
 
150
        const pjmedia_aud_param *param,
 
151
        pjmedia_aud_rec_cb rec_cb,
 
152
        pjmedia_aud_play_cb play_cb,
 
153
        void *user_data,
 
154
        pjmedia_aud_stream **p_aud_strm);
157
155
 
158
 
static pj_status_t stream_get_param(pjmedia_aud_stream *strm,
159
 
                                    pjmedia_aud_param *param);
160
 
static pj_status_t stream_get_cap(pjmedia_aud_stream *strm,
161
 
                                  pjmedia_aud_dev_cap cap,
162
 
                                  void *value);
163
 
static pj_status_t stream_set_cap(pjmedia_aud_stream *strm,
164
 
                                  pjmedia_aud_dev_cap cap,
165
 
                                  const void *value);
166
 
static pj_status_t stream_start(pjmedia_aud_stream *strm);
167
 
static pj_status_t stream_stop(pjmedia_aud_stream *strm);
168
 
static pj_status_t stream_destroy(pjmedia_aud_stream *strm);
 
156
static pj_status_t stream_get_param (pjmedia_aud_stream *strm,
 
157
                                     pjmedia_aud_param *param);
 
158
static pj_status_t stream_get_cap (pjmedia_aud_stream *strm,
 
159
                                   pjmedia_aud_dev_cap cap,
 
160
                                   void *value);
 
161
static pj_status_t stream_set_cap (pjmedia_aud_stream *strm,
 
162
                                   pjmedia_aud_dev_cap cap,
 
163
                                   const void *value);
 
164
static pj_status_t stream_start (pjmedia_aud_stream *strm);
 
165
static pj_status_t stream_stop (pjmedia_aud_stream *strm);
 
166
static pj_status_t stream_destroy (pjmedia_aud_stream *strm);
169
167
 
170
168
 
171
169
/* Operations */
172
 
static pjmedia_aud_dev_factory_op factory_op =
173
 
{
 
170
static pjmedia_aud_dev_factory_op factory_op = {
174
171
    &factory_init,
175
172
    &factory_destroy,
176
173
    &factory_get_dev_count,
179
176
    &factory_create_stream
180
177
};
181
178
 
182
 
static pjmedia_aud_stream_op stream_op = 
183
 
{
 
179
static pjmedia_aud_stream_op stream_op = {
184
180
    &stream_get_param,
185
181
    &stream_get_cap,
186
182
    &stream_set_cap,
197
193
/*
198
194
 * Utility: print sound device error
199
195
 */
200
 
static void snd_perror(const char *title, TInt rc)
 
196
static void snd_perror (const char *title, TInt rc)
201
197
{
202
 
    PJ_LOG(1,(THIS_FILE, "%s (error code=%d)", title, rc));
 
198
    PJ_LOG (1, (THIS_FILE, "%s (error code=%d)", title, rc));
203
199
}
204
200
 
205
 
typedef void(*PjAudioCallback)(CVoIPDataBuffer *buf, void *user_data);
 
201
typedef void (*PjAudioCallback) (CVoIPDataBuffer *buf, void *user_data);
206
202
 
207
203
/*
208
204
 * Audio setting for CPjAudioEngine.
209
205
 */
210
206
class CPjAudioSetting
211
207
{
212
 
public:
213
 
    TVoIPCodecFormat     format;
214
 
    TInt                 mode;
215
 
    TBool                plc;
216
 
    TBool                vad;
217
 
    TBool                cng;
218
 
    TBool                loudspk;
 
208
    public:
 
209
        TVoIPCodecFormat         format;
 
210
        TInt             mode;
 
211
        TBool            plc;
 
212
        TBool            vad;
 
213
        TBool            cng;
 
214
        TBool            loudspk;
219
215
};
220
216
 
221
217
/*
222
218
 * Implementation: Symbian Input & Output Stream.
223
219
 */
224
220
class CPjAudioEngine :  public CBase,
225
 
                        public MVoIPDownlinkObserver,
226
 
                        public MVoIPUplinkObserver,
227
 
                        public MVoIPFormatObserver
 
221
        public MVoIPDownlinkObserver,
 
222
        public MVoIPUplinkObserver,
 
223
        public MVoIPFormatObserver
228
224
{
229
 
public:
230
 
    enum State
231
 
    {
232
 
        STATE_NULL,
233
 
        STATE_STARTING,
234
 
        STATE_READY,
235
 
        STATE_STREAMING
236
 
    };
237
 
 
238
 
    ~CPjAudioEngine();
239
 
 
240
 
    static CPjAudioEngine *NewL(struct vas_stream *parent_strm,
241
 
                                PjAudioCallback rec_cb,
242
 
                                PjAudioCallback play_cb,
243
 
                                void *user_data,
244
 
                                const CPjAudioSetting &setting);
245
 
 
246
 
    TInt Start();
247
 
    void Stop();
248
 
 
249
 
    TInt ActivateSpeaker(TBool active);
250
 
    
251
 
    TInt SetVolume(TInt vol) { return iVoIPDnlink->SetVolume(vol); }
252
 
    TInt GetVolume() { TInt vol;iVoIPDnlink->GetVolume(vol);return vol; }
253
 
    TInt GetMaxVolume() { TInt vol;iVoIPDnlink->GetMaxVolume(vol);return vol; }
254
 
    
255
 
    TInt SetGain(TInt gain) { return iVoIPUplink->SetGain(gain); }
256
 
    TInt GetGain() { TInt gain;iVoIPUplink->GetGain(gain);return gain; }
257
 
    TInt GetMaxGain() { TInt gain;iVoIPUplink->GetMaxGain(gain);return gain; }
258
 
 
259
 
    TBool IsStarted();
260
 
    
261
 
private:
262
 
    CPjAudioEngine(struct vas_stream *parent_strm,
263
 
                   PjAudioCallback rec_cb,
264
 
                   PjAudioCallback play_cb,
265
 
                   void *user_data,
266
 
                   const CPjAudioSetting &setting);
267
 
    void ConstructL();
268
 
 
269
 
    TInt InitPlay();
270
 
    TInt InitRec();
271
 
 
272
 
    TInt StartPlay();
273
 
    TInt StartRec();
274
 
 
275
 
    // From MVoIPDownlinkObserver
276
 
    void FillBuffer(const CVoIPAudioDownlinkStream& aSrc,
277
 
                            CVoIPDataBuffer* aBuffer);
278
 
    void Event(const CVoIPAudioDownlinkStream& aSrc,
279
 
                       TInt aEventType,
280
 
                       TInt aError);
281
 
 
282
 
    // From MVoIPUplinkObserver
283
 
    void EmptyBuffer(const CVoIPAudioUplinkStream& aSrc,
284
 
                             CVoIPDataBuffer* aBuffer);
285
 
    void Event(const CVoIPAudioUplinkStream& aSrc,
286
 
                       TInt aEventType,
287
 
                       TInt aError);
288
 
 
289
 
    // From MVoIPFormatObserver
290
 
    void Event(const CVoIPFormatIntfc& aSrc, TInt aEventType);
291
 
 
292
 
    State                        dn_state_;
293
 
    State                        up_state_;
294
 
    struct vas_stream           *parentStrm_;
295
 
    CPjAudioSetting              setting_;
296
 
    PjAudioCallback              rec_cb_;
297
 
    PjAudioCallback              play_cb_;
298
 
    void                        *user_data_;
299
 
 
300
 
    // VAS objects
301
 
    CVoIPUtilityFactory         *iFactory;
302
 
    CVoIPAudioDownlinkStream    *iVoIPDnlink;
303
 
    CVoIPAudioUplinkStream      *iVoIPUplink;
304
 
    CVoIPFormatIntfc            *enc_fmt_if;
305
 
    CVoIPFormatIntfc            *dec_fmt_if;
 
225
    public:
 
226
        enum State {
 
227
            STATE_NULL,
 
228
            STATE_STARTING,
 
229
            STATE_READY,
 
230
            STATE_STREAMING
 
231
        };
 
232
 
 
233
        ~CPjAudioEngine();
 
234
 
 
235
        static CPjAudioEngine *NewL (struct vas_stream *parent_strm,
 
236
                                     PjAudioCallback rec_cb,
 
237
                                     PjAudioCallback play_cb,
 
238
                                     void *user_data,
 
239
                                     const CPjAudioSetting &setting);
 
240
 
 
241
        TInt Start();
 
242
        void Stop();
 
243
 
 
244
        TInt ActivateSpeaker (TBool active);
 
245
 
 
246
        TInt SetVolume (TInt vol) {
 
247
            return iVoIPDnlink->SetVolume (vol);
 
248
        }
 
249
        TInt GetVolume() {
 
250
            TInt vol;
 
251
            iVoIPDnlink->GetVolume (vol);
 
252
            return vol;
 
253
        }
 
254
        TInt GetMaxVolume() {
 
255
            TInt vol;
 
256
            iVoIPDnlink->GetMaxVolume (vol);
 
257
            return vol;
 
258
        }
 
259
 
 
260
        TInt SetGain (TInt gain) {
 
261
            return iVoIPUplink->SetGain (gain);
 
262
        }
 
263
        TInt GetGain() {
 
264
            TInt gain;
 
265
            iVoIPUplink->GetGain (gain);
 
266
            return gain;
 
267
        }
 
268
        TInt GetMaxGain() {
 
269
            TInt gain;
 
270
            iVoIPUplink->GetMaxGain (gain);
 
271
            return gain;
 
272
        }
 
273
 
 
274
        TBool IsStarted();
 
275
 
 
276
    private:
 
277
        CPjAudioEngine (struct vas_stream *parent_strm,
 
278
                        PjAudioCallback rec_cb,
 
279
                        PjAudioCallback play_cb,
 
280
                        void *user_data,
 
281
                        const CPjAudioSetting &setting);
 
282
        void ConstructL();
 
283
 
 
284
        TInt InitPlay();
 
285
        TInt InitRec();
 
286
 
 
287
        TInt StartPlay();
 
288
        TInt StartRec();
 
289
 
 
290
        // From MVoIPDownlinkObserver
 
291
        void FillBuffer (const CVoIPAudioDownlinkStream& aSrc,
 
292
                         CVoIPDataBuffer* aBuffer);
 
293
        void Event (const CVoIPAudioDownlinkStream& aSrc,
 
294
                    TInt aEventType,
 
295
                    TInt aError);
 
296
 
 
297
        // From MVoIPUplinkObserver
 
298
        void EmptyBuffer (const CVoIPAudioUplinkStream& aSrc,
 
299
                          CVoIPDataBuffer* aBuffer);
 
300
        void Event (const CVoIPAudioUplinkStream& aSrc,
 
301
                    TInt aEventType,
 
302
                    TInt aError);
 
303
 
 
304
        // From MVoIPFormatObserver
 
305
        void Event (const CVoIPFormatIntfc& aSrc, TInt aEventType);
 
306
 
 
307
        State                    dn_state_;
 
308
        State                    up_state_;
 
309
        struct vas_stream               *parentStrm_;
 
310
        CPjAudioSetting          setting_;
 
311
        PjAudioCallback                  rec_cb_;
 
312
        PjAudioCallback                  play_cb_;
 
313
        void                    *user_data_;
 
314
 
 
315
        // VAS objects
 
316
        CVoIPUtilityFactory         *iFactory;
 
317
        CVoIPAudioDownlinkStream    *iVoIPDnlink;
 
318
        CVoIPAudioUplinkStream      *iVoIPUplink;
 
319
        CVoIPFormatIntfc                *enc_fmt_if;
 
320
        CVoIPFormatIntfc                *dec_fmt_if;
306
321
};
307
322
 
308
323
 
309
 
CPjAudioEngine* CPjAudioEngine::NewL(struct vas_stream *parent_strm,
310
 
                                     PjAudioCallback rec_cb,
311
 
                                     PjAudioCallback play_cb,
312
 
                                     void *user_data,
313
 
                                     const CPjAudioSetting &setting)
 
324
CPjAudioEngine* CPjAudioEngine::NewL (struct vas_stream *parent_strm,
 
325
                                      PjAudioCallback rec_cb,
 
326
                                      PjAudioCallback play_cb,
 
327
                                      void *user_data,
 
328
                                      const CPjAudioSetting &setting)
314
329
{
315
 
    CPjAudioEngine* self = new (ELeave) CPjAudioEngine(parent_strm,
316
 
                                                       rec_cb, play_cb,
317
 
                                                       user_data,
318
 
                                                       setting);
319
 
    CleanupStack::PushL(self);
 
330
    CPjAudioEngine* self = new (ELeave) CPjAudioEngine (parent_strm,
 
331
            rec_cb, play_cb,
 
332
            user_data,
 
333
            setting);
 
334
    CleanupStack::PushL (self);
320
335
    self->ConstructL();
321
 
    CleanupStack::Pop(self);
 
336
    CleanupStack::Pop (self);
322
337
    return self;
323
338
}
324
339
 
325
340
void CPjAudioEngine::ConstructL()
326
341
{
327
342
    TInt err;
328
 
    const TVersion ver(1, 0, 0); /* Not really used at this time */
 
343
    const TVersion ver (1, 0, 0); /* Not really used at this time */
329
344
 
330
 
    err = CVoIPUtilityFactory::CreateFactory(iFactory);
331
 
    User::LeaveIfError(err);
 
345
    err = CVoIPUtilityFactory::CreateFactory (iFactory);
 
346
    User::LeaveIfError (err);
332
347
 
333
348
    if (parentStrm_->param.dir != PJMEDIA_DIR_CAPTURE) {
334
 
        err = iFactory->CreateDownlinkStream(ver, 
335
 
                                             CVoIPUtilityFactory::EVoIPCall,
336
 
                                             iVoIPDnlink);
337
 
        User::LeaveIfError(err);
 
349
        err = iFactory->CreateDownlinkStream (ver,
 
350
                                              CVoIPUtilityFactory::EVoIPCall,
 
351
                                              iVoIPDnlink);
 
352
        User::LeaveIfError (err);
338
353
    }
339
354
 
340
355
    if (parentStrm_->param.dir != PJMEDIA_DIR_PLAYBACK) {
341
 
        err = iFactory->CreateUplinkStream(ver, 
342
 
                                           CVoIPUtilityFactory::EVoIPCall,
343
 
                                           iVoIPUplink);
344
 
        User::LeaveIfError(err);
 
356
        err = iFactory->CreateUplinkStream (ver,
 
357
                                            CVoIPUtilityFactory::EVoIPCall,
 
358
                                            iVoIPUplink);
 
359
        User::LeaveIfError (err);
345
360
    }
346
361
}
347
362
 
348
 
CPjAudioEngine::CPjAudioEngine(struct vas_stream *parent_strm,
349
 
                               PjAudioCallback rec_cb,
350
 
                               PjAudioCallback play_cb,
351
 
                               void *user_data,
352
 
                               const CPjAudioSetting &setting)
353
 
      : dn_state_(STATE_NULL),
354
 
        up_state_(STATE_NULL),
355
 
        parentStrm_(parent_strm),
356
 
        setting_(setting),
357
 
        rec_cb_(rec_cb),
358
 
        play_cb_(play_cb),
359
 
        user_data_(user_data),
360
 
        iFactory(NULL),
361
 
        iVoIPDnlink(NULL),
362
 
        iVoIPUplink(NULL),
363
 
        enc_fmt_if(NULL),
364
 
        dec_fmt_if(NULL)
 
363
CPjAudioEngine::CPjAudioEngine (struct vas_stream *parent_strm,
 
364
                                PjAudioCallback rec_cb,
 
365
                                PjAudioCallback play_cb,
 
366
                                void *user_data,
 
367
                                const CPjAudioSetting &setting)
 
368
        : dn_state_ (STATE_NULL),
 
369
        up_state_ (STATE_NULL),
 
370
        parentStrm_ (parent_strm),
 
371
        setting_ (setting),
 
372
        rec_cb_ (rec_cb),
 
373
        play_cb_ (play_cb),
 
374
        user_data_ (user_data),
 
375
        iFactory (NULL),
 
376
        iVoIPDnlink (NULL),
 
377
        iVoIPUplink (NULL),
 
378
        enc_fmt_if (NULL),
 
379
        dec_fmt_if (NULL)
365
380
{
366
381
}
367
382
 
368
383
CPjAudioEngine::~CPjAudioEngine()
369
384
{
370
385
    Stop();
371
 
    
 
386
 
372
387
    if (iVoIPUplink)
373
 
        iVoIPUplink->Close();
374
 
    
 
388
        iVoIPUplink->Close();
 
389
 
375
390
    if (iVoIPDnlink)
376
 
        iVoIPDnlink->Close();
 
391
        iVoIPDnlink->Close();
377
392
 
378
393
    delete iVoIPDnlink;
379
394
    delete iVoIPUplink;
380
395
    delete iFactory;
381
 
    
382
 
    TRACE_((THIS_FILE, "Sound device destroyed"));
 
396
 
 
397
    TRACE_ ( (THIS_FILE, "Sound device destroyed"));
383
398
}
384
399
 
385
400
TBool CPjAudioEngine::IsStarted()
386
401
{
387
 
    return ((((parentStrm_->param.dir & PJMEDIA_DIR_CAPTURE) == 0) || 
388
 
               up_state_ == STATE_STREAMING) &&
389
 
            (((parentStrm_->param.dir & PJMEDIA_DIR_PLAYBACK) == 0) || 
390
 
               dn_state_ == STATE_STREAMING));
 
402
    return ( ( ( (parentStrm_->param.dir & PJMEDIA_DIR_CAPTURE) == 0) ||
 
403
               up_state_ == STATE_STREAMING) &&
 
404
             ( ( (parentStrm_->param.dir & PJMEDIA_DIR_PLAYBACK) == 0) ||
 
405
               dn_state_ == STATE_STREAMING));
391
406
}
392
407
 
393
408
TInt CPjAudioEngine::InitPlay()
394
409
{
395
410
    TInt err;
396
411
 
397
 
    pj_assert(iVoIPDnlink);
398
 
 
399
 
    err = iVoIPDnlink->SetFormat(setting_.format, dec_fmt_if);
400
 
    if (err != KErrNone)
401
 
        return err;
402
 
    
403
 
    err = dec_fmt_if->SetObserver(*this);
404
 
    if (err != KErrNone)
405
 
        return err;
406
 
 
407
 
    return iVoIPDnlink->Open(*this);
 
412
    pj_assert (iVoIPDnlink);
 
413
 
 
414
    err = iVoIPDnlink->SetFormat (setting_.format, dec_fmt_if);
 
415
 
 
416
    if (err != KErrNone)
 
417
        return err;
 
418
 
 
419
    err = dec_fmt_if->SetObserver (*this);
 
420
 
 
421
    if (err != KErrNone)
 
422
        return err;
 
423
 
 
424
    return iVoIPDnlink->Open (*this);
408
425
}
409
426
 
410
427
TInt CPjAudioEngine::InitRec()
411
428
{
412
429
    TInt err;
413
 
    
414
 
    pj_assert(iVoIPUplink);
415
 
 
416
 
    err = iVoIPUplink->SetFormat(setting_.format, enc_fmt_if);
417
 
    if (err != KErrNone)
418
 
        return err;
419
 
    
420
 
    err = enc_fmt_if->SetObserver(*this);
421
 
    if (err != KErrNone)
422
 
        return err;
423
 
    
424
 
    return iVoIPUplink->Open(*this);
 
430
 
 
431
    pj_assert (iVoIPUplink);
 
432
 
 
433
    err = iVoIPUplink->SetFormat (setting_.format, enc_fmt_if);
 
434
 
 
435
    if (err != KErrNone)
 
436
        return err;
 
437
 
 
438
    err = enc_fmt_if->SetObserver (*this);
 
439
 
 
440
    if (err != KErrNone)
 
441
        return err;
 
442
 
 
443
    return iVoIPUplink->Open (*this);
425
444
}
426
445
 
427
446
TInt CPjAudioEngine::StartPlay()
428
447
{
429
448
    TInt err;
430
 
    
431
 
    pj_assert(iVoIPDnlink);
432
 
    pj_assert(dn_state_ == STATE_READY);
 
449
 
 
450
    pj_assert (iVoIPDnlink);
 
451
    pj_assert (dn_state_ == STATE_READY);
433
452
 
434
453
    /* Configure specific codec setting */
435
454
    switch (setting_.format) {
436
 
    case EG711:
437
 
        {
438
 
            CVoIPG711DecoderIntfc *g711dec_if = (CVoIPG711DecoderIntfc*)
439
 
                                                dec_fmt_if;
440
 
            err = g711dec_if->SetMode((CVoIPFormatIntfc::TG711CodecMode)
441
 
                                      setting_.mode);
442
 
            pj_assert(err == KErrNone);
443
 
        }
444
 
        break;
445
 
        
446
 
    case EILBC:
447
 
        {
448
 
            CVoIPILBCDecoderIntfc *ilbcdec_if = (CVoIPILBCDecoderIntfc*)
449
 
                                                dec_fmt_if;
450
 
            err = ilbcdec_if->SetMode((CVoIPFormatIntfc::TILBCCodecMode)
451
 
                                      setting_.mode);
452
 
            pj_assert(err == KErrNone);
453
 
        }
454
 
        break;
455
 
 
456
 
    default:
457
 
        break;
 
455
        case EG711: {
 
456
            CVoIPG711DecoderIntfc *g711dec_if = (CVoIPG711DecoderIntfc*)
 
457
                                                dec_fmt_if;
 
458
            err = g711dec_if->SetMode ( (CVoIPFormatIntfc::TG711CodecMode)
 
459
                                        setting_.mode);
 
460
            pj_assert (err == KErrNone);
 
461
        }
 
462
        break;
 
463
 
 
464
        case EILBC: {
 
465
            CVoIPILBCDecoderIntfc *ilbcdec_if = (CVoIPILBCDecoderIntfc*)
 
466
                                                dec_fmt_if;
 
467
            err = ilbcdec_if->SetMode ( (CVoIPFormatIntfc::TILBCCodecMode)
 
468
                                        setting_.mode);
 
469
            pj_assert (err == KErrNone);
 
470
        }
 
471
        break;
 
472
 
 
473
        default:
 
474
            break;
458
475
    }
459
 
    
 
476
 
460
477
    /* Configure audio routing */
461
 
    ActivateSpeaker(setting_.loudspk);
 
478
    ActivateSpeaker (setting_.loudspk);
462
479
 
463
480
    /* Start player */
464
481
    err = iVoIPDnlink->Start();
465
 
    
 
482
 
466
483
    if (err == KErrNone) {
467
 
        dn_state_ = STATE_STREAMING;
468
 
        TRACE_((THIS_FILE, "Downlink started"));
 
484
        dn_state_ = STATE_STREAMING;
 
485
        TRACE_ ( (THIS_FILE, "Downlink started"));
469
486
    } else {
470
 
        snd_perror("Failed starting downlink", err);
 
487
        snd_perror ("Failed starting downlink", err);
471
488
    }
472
489
 
473
490
    return err;
476
493
TInt CPjAudioEngine::StartRec()
477
494
{
478
495
    TInt err;
479
 
    
480
 
    pj_assert(iVoIPUplink);
481
 
    pj_assert(up_state_ == STATE_READY);
 
496
 
 
497
    pj_assert (iVoIPUplink);
 
498
    pj_assert (up_state_ == STATE_READY);
482
499
 
483
500
    /* Configure specific codec setting */
484
501
    switch (setting_.format) {
485
 
    case EG711:
486
 
        {
487
 
            CVoIPG711EncoderIntfc *g711enc_if = (CVoIPG711EncoderIntfc*)
488
 
                                                enc_fmt_if;
489
 
            err = g711enc_if->SetMode((CVoIPFormatIntfc::TG711CodecMode)
490
 
                                      setting_.mode);
491
 
            pj_assert(err == KErrNone);
492
 
        }
493
 
        break;
494
 
 
495
 
    case EILBC:
496
 
        {
497
 
            CVoIPILBCEncoderIntfc *ilbcenc_if = (CVoIPILBCEncoderIntfc*)
498
 
                                                enc_fmt_if;
499
 
            err = ilbcenc_if->SetMode((CVoIPFormatIntfc::TILBCCodecMode)
500
 
                                      setting_.mode);
501
 
            pj_assert(err == KErrNone);
502
 
        }
503
 
        break;
504
 
        
505
 
    default:
506
 
        break;
 
502
        case EG711: {
 
503
            CVoIPG711EncoderIntfc *g711enc_if = (CVoIPG711EncoderIntfc*)
 
504
                                                enc_fmt_if;
 
505
            err = g711enc_if->SetMode ( (CVoIPFormatIntfc::TG711CodecMode)
 
506
                                        setting_.mode);
 
507
            pj_assert (err == KErrNone);
 
508
        }
 
509
        break;
 
510
 
 
511
        case EILBC: {
 
512
            CVoIPILBCEncoderIntfc *ilbcenc_if = (CVoIPILBCEncoderIntfc*)
 
513
                                                enc_fmt_if;
 
514
            err = ilbcenc_if->SetMode ( (CVoIPFormatIntfc::TILBCCodecMode)
 
515
                                        setting_.mode);
 
516
            pj_assert (err == KErrNone);
 
517
        }
 
518
        break;
 
519
 
 
520
        default:
 
521
            break;
507
522
    }
508
 
    
 
523
 
509
524
    /* Configure general codec setting */
510
 
    enc_fmt_if->SetVAD(setting_.vad);
511
 
    
 
525
    enc_fmt_if->SetVAD (setting_.vad);
 
526
 
512
527
    /* Start recorder */
513
528
    err = iVoIPUplink->Start();
514
 
    
 
529
 
515
530
    if (err == KErrNone) {
516
 
        up_state_ = STATE_STREAMING;
517
 
        TRACE_((THIS_FILE, "Uplink started"));
 
531
        up_state_ = STATE_STREAMING;
 
532
        TRACE_ ( (THIS_FILE, "Uplink started"));
518
533
    } else {
519
 
        snd_perror("Failed starting uplink", err);
 
534
        snd_perror ("Failed starting uplink", err);
520
535
    }
521
536
 
522
537
    return err;
525
540
TInt CPjAudioEngine::Start()
526
541
{
527
542
    TInt err = KErrNone;
528
 
    
 
543
 
529
544
    if (iVoIPDnlink) {
530
 
        switch(dn_state_) {
531
 
        case STATE_READY:
532
 
            err = StartPlay();
533
 
            break;
534
 
        case STATE_NULL:
535
 
            err = InitPlay();
536
 
            if (err != KErrNone)
537
 
                return err;
538
 
            dn_state_ = STATE_STARTING;
539
 
            break;
540
 
        default:
541
 
            break;
542
 
        }
 
545
        switch (dn_state_) {
 
546
            case STATE_READY:
 
547
                err = StartPlay();
 
548
                break;
 
549
            case STATE_NULL:
 
550
                err = InitPlay();
 
551
 
 
552
                if (err != KErrNone)
 
553
                    return err;
 
554
 
 
555
                dn_state_ = STATE_STARTING;
 
556
                break;
 
557
            default:
 
558
                break;
 
559
        }
543
560
    }
544
 
    
 
561
 
545
562
    if (iVoIPUplink) {
546
 
        switch(up_state_) {
547
 
        case STATE_READY:
548
 
            err = StartRec();
549
 
            break;
550
 
        case STATE_NULL:
551
 
            err = InitRec();
552
 
            if (err != KErrNone)
553
 
                return err;
554
 
            up_state_ = STATE_STARTING;
555
 
            break;
556
 
        default:
557
 
            break;
558
 
        }
 
563
        switch (up_state_) {
 
564
            case STATE_READY:
 
565
                err = StartRec();
 
566
                break;
 
567
            case STATE_NULL:
 
568
                err = InitRec();
 
569
 
 
570
                if (err != KErrNone)
 
571
                    return err;
 
572
 
 
573
                up_state_ = STATE_STARTING;
 
574
                break;
 
575
            default:
 
576
                break;
 
577
        }
559
578
    }
560
579
 
561
580
    return err;
564
583
void CPjAudioEngine::Stop()
565
584
{
566
585
    if (iVoIPDnlink) {
567
 
        switch(dn_state_) {
568
 
        case STATE_STREAMING:
569
 
            iVoIPDnlink->Stop();
570
 
            dn_state_ = STATE_READY;
571
 
            break;
572
 
        case STATE_STARTING:
573
 
            dn_state_ = STATE_NULL;
574
 
            break;
575
 
        default:
576
 
            break;
577
 
        }
 
586
        switch (dn_state_) {
 
587
            case STATE_STREAMING:
 
588
                iVoIPDnlink->Stop();
 
589
                dn_state_ = STATE_READY;
 
590
                break;
 
591
            case STATE_STARTING:
 
592
                dn_state_ = STATE_NULL;
 
593
                break;
 
594
            default:
 
595
                break;
 
596
        }
578
597
    }
579
598
 
580
599
    if (iVoIPUplink) {
581
 
        switch(up_state_) {
582
 
        case STATE_STREAMING:
583
 
            iVoIPUplink->Stop();
584
 
            up_state_ = STATE_READY;
585
 
            break;
586
 
        case STATE_STARTING:
587
 
            up_state_ = STATE_NULL;
588
 
            break;
589
 
        default:
590
 
            break;
591
 
        }
 
600
        switch (up_state_) {
 
601
            case STATE_STREAMING:
 
602
                iVoIPUplink->Stop();
 
603
                up_state_ = STATE_READY;
 
604
                break;
 
605
            case STATE_STARTING:
 
606
                up_state_ = STATE_NULL;
 
607
                break;
 
608
            default:
 
609
                break;
 
610
        }
592
611
    }
593
612
}
594
613
 
595
614
 
596
 
TInt CPjAudioEngine::ActivateSpeaker(TBool active)
 
615
TInt CPjAudioEngine::ActivateSpeaker (TBool active)
597
616
{
598
617
    TInt err = KErrNotSupported;
599
 
    
 
618
 
600
619
    if (iVoIPDnlink) {
601
 
        err = iVoIPDnlink->SetAudioDevice(active?
602
 
                                    CVoIPAudioDownlinkStream::ELoudSpeaker :
603
 
                                    CVoIPAudioDownlinkStream::EHandset);
604
 
        TRACE_((THIS_FILE, "Loudspeaker turned %s", (active? "on":"off")));
 
620
        err = iVoIPDnlink->SetAudioDevice (active?
 
621
                                           CVoIPAudioDownlinkStream::ELoudSpeaker :
 
622
                                           CVoIPAudioDownlinkStream::EHandset);
 
623
        TRACE_ ( (THIS_FILE, "Loudspeaker turned %s", (active? "on":"off")));
605
624
    }
606
 
    
 
625
 
607
626
    return err;
608
627
}
609
628
 
610
629
// Callback from MVoIPDownlinkObserver
611
 
void CPjAudioEngine::FillBuffer(const CVoIPAudioDownlinkStream& aSrc,
612
 
                                CVoIPDataBuffer* aBuffer)
613
 
{
614
 
    play_cb_(aBuffer, user_data_);
615
 
    iVoIPDnlink->BufferFilled(aBuffer);
616
 
}
617
 
 
618
 
// Callback from MVoIPUplinkObserver
619
 
void CPjAudioEngine::EmptyBuffer(const CVoIPAudioUplinkStream& aSrc,
 
630
void CPjAudioEngine::FillBuffer (const CVoIPAudioDownlinkStream& aSrc,
620
631
                                 CVoIPDataBuffer* aBuffer)
621
632
{
622
 
    rec_cb_(aBuffer, user_data_);
623
 
    iVoIPUplink->BufferEmptied(aBuffer);
 
633
    play_cb_ (aBuffer, user_data_);
 
634
    iVoIPDnlink->BufferFilled (aBuffer);
 
635
}
 
636
 
 
637
// Callback from MVoIPUplinkObserver
 
638
void CPjAudioEngine::EmptyBuffer (const CVoIPAudioUplinkStream& aSrc,
 
639
                                  CVoIPDataBuffer* aBuffer)
 
640
{
 
641
    rec_cb_ (aBuffer, user_data_);
 
642
    iVoIPUplink->BufferEmptied (aBuffer);
624
643
}
625
644
 
626
645
// Callback from MVoIPDownlinkObserver
627
 
void CPjAudioEngine::Event(const CVoIPAudioDownlinkStream& /*aSrc*/,
628
 
                           TInt aEventType,
629
 
                           TInt aError)
 
646
void CPjAudioEngine::Event (const CVoIPAudioDownlinkStream& /*aSrc*/,
 
647
                            TInt aEventType,
 
648
                            TInt aError)
630
649
{
631
650
    switch (aEventType) {
632
 
    case MVoIPDownlinkObserver::KOpenComplete:
633
 
        if (aError == KErrNone) {
634
 
            State last_state = dn_state_;
635
 
 
636
 
            dn_state_ = STATE_READY;
637
 
            TRACE_((THIS_FILE, "Downlink opened"));
638
 
 
639
 
            if (last_state == STATE_STARTING)
640
 
                StartPlay();
641
 
        }
642
 
        break;
643
 
 
644
 
    case MVoIPDownlinkObserver::KDownlinkClosed:
645
 
        dn_state_ = STATE_NULL;
646
 
        TRACE_((THIS_FILE, "Downlink closed"));
647
 
        break;
648
 
 
649
 
    case MVoIPDownlinkObserver::KDownlinkError:
650
 
        dn_state_ = STATE_READY;
651
 
        snd_perror("Downlink problem", aError);
652
 
        break;
653
 
    default:
654
 
        break;
 
651
        case MVoIPDownlinkObserver::KOpenComplete:
 
652
 
 
653
            if (aError == KErrNone) {
 
654
                State last_state = dn_state_;
 
655
 
 
656
                dn_state_ = STATE_READY;
 
657
                TRACE_ ( (THIS_FILE, "Downlink opened"));
 
658
 
 
659
                if (last_state == STATE_STARTING)
 
660
                    StartPlay();
 
661
            }
 
662
 
 
663
            break;
 
664
 
 
665
        case MVoIPDownlinkObserver::KDownlinkClosed:
 
666
            dn_state_ = STATE_NULL;
 
667
            TRACE_ ( (THIS_FILE, "Downlink closed"));
 
668
            break;
 
669
 
 
670
        case MVoIPDownlinkObserver::KDownlinkError:
 
671
            dn_state_ = STATE_READY;
 
672
            snd_perror ("Downlink problem", aError);
 
673
            break;
 
674
        default:
 
675
            break;
655
676
    }
656
677
}
657
678
 
658
679
// Callback from MVoIPUplinkObserver
659
 
void CPjAudioEngine::Event(const CVoIPAudioUplinkStream& /*aSrc*/,
660
 
                           TInt aEventType,
661
 
                           TInt aError)
 
680
void CPjAudioEngine::Event (const CVoIPAudioUplinkStream& /*aSrc*/,
 
681
                            TInt aEventType,
 
682
                            TInt aError)
662
683
{
663
684
    switch (aEventType) {
664
 
    case MVoIPUplinkObserver::KOpenComplete:
665
 
        if (aError == KErrNone) {
666
 
            State last_state = up_state_;
667
 
 
668
 
            up_state_ = STATE_READY;
669
 
            TRACE_((THIS_FILE, "Uplink opened"));
670
 
            
671
 
            if (last_state == STATE_STARTING)
672
 
                StartRec();
673
 
        }
674
 
        break;
675
 
 
676
 
    case MVoIPUplinkObserver::KUplinkClosed:
677
 
        up_state_ = STATE_NULL;
678
 
        TRACE_((THIS_FILE, "Uplink closed"));
679
 
        break;
680
 
 
681
 
    case MVoIPUplinkObserver::KUplinkError:
682
 
        up_state_ = STATE_READY;
683
 
        snd_perror("Uplink problem", aError);
684
 
        break;
685
 
    default:
686
 
        break;
 
685
        case MVoIPUplinkObserver::KOpenComplete:
 
686
 
 
687
            if (aError == KErrNone) {
 
688
                State last_state = up_state_;
 
689
 
 
690
                up_state_ = STATE_READY;
 
691
                TRACE_ ( (THIS_FILE, "Uplink opened"));
 
692
 
 
693
                if (last_state == STATE_STARTING)
 
694
                    StartRec();
 
695
            }
 
696
 
 
697
            break;
 
698
 
 
699
        case MVoIPUplinkObserver::KUplinkClosed:
 
700
            up_state_ = STATE_NULL;
 
701
            TRACE_ ( (THIS_FILE, "Uplink closed"));
 
702
            break;
 
703
 
 
704
        case MVoIPUplinkObserver::KUplinkError:
 
705
            up_state_ = STATE_READY;
 
706
            snd_perror ("Uplink problem", aError);
 
707
            break;
 
708
        default:
 
709
            break;
687
710
    }
688
711
}
689
712
 
690
713
// Callback from MVoIPFormatObserver
691
 
void CPjAudioEngine::Event(const CVoIPFormatIntfc& /*aSrc*/, 
692
 
                           TInt aEventType)
 
714
void CPjAudioEngine::Event (const CVoIPFormatIntfc& /*aSrc*/,
 
715
                            TInt aEventType)
693
716
{
694
 
    snd_perror("Format event", aEventType);
 
717
    snd_perror ("Format event", aEventType);
695
718
}
696
719
 
697
720
/****************************************************************************
700
723
 
701
724
#ifdef USE_NATIVE_PCM
702
725
 
703
 
static void RecCbPcm2(CVoIPDataBuffer *buf, void *user_data)
 
726
static void RecCbPcm2 (CVoIPDataBuffer *buf, void *user_data)
704
727
{
705
728
    struct vas_stream *strm = (struct vas_stream*) user_data;
706
 
    TPtr8 buffer(0, 0, 0);
 
729
    TPtr8 buffer (0, 0, 0);
707
730
    pj_int16_t *p_buf;
708
731
    unsigned buf_len;
709
732
 
710
733
    /* Get the buffer */
711
 
    buf->GetPayloadPtr(buffer);
712
 
    
 
734
    buf->GetPayloadPtr (buffer);
 
735
 
713
736
    /* Call parent callback */
714
737
    p_buf = (pj_int16_t*) buffer.Ptr();
715
738
    buf_len = buffer.Length() >> 1;
 
739
 
716
740
    while (buf_len) {
717
 
        unsigned req;
718
 
        
719
 
        req = strm->param.samples_per_frame - strm->rec_buf_len;
720
 
        if (req > buf_len)
721
 
            req = buf_len;
722
 
        pjmedia_copy_samples(strm->rec_buf + strm->rec_buf_len, p_buf, req);
723
 
        p_buf += req;
724
 
        buf_len -= req;
725
 
        strm->rec_buf_len += req;
726
 
        
727
 
        if (strm->rec_buf_len >= strm->param.samples_per_frame) {
728
 
            pjmedia_frame f;
729
 
 
730
 
            f.buf = strm->rec_buf;
731
 
            f.type = PJMEDIA_FRAME_TYPE_AUDIO;
732
 
            f.size = strm->param.samples_per_frame << 1;
733
 
            strm->rec_cb(strm->user_data, &f);
734
 
            strm->rec_buf_len = 0;
735
 
        }
 
741
        unsigned req;
 
742
 
 
743
        req = strm->param.samples_per_frame - strm->rec_buf_len;
 
744
 
 
745
        if (req > buf_len)
 
746
            req = buf_len;
 
747
 
 
748
        pjmedia_copy_samples (strm->rec_buf + strm->rec_buf_len, p_buf, req);
 
749
        p_buf += req;
 
750
        buf_len -= req;
 
751
        strm->rec_buf_len += req;
 
752
 
 
753
        if (strm->rec_buf_len >= strm->param.samples_per_frame) {
 
754
            pjmedia_frame f;
 
755
 
 
756
            f.buf = strm->rec_buf;
 
757
            f.type = PJMEDIA_FRAME_TYPE_AUDIO;
 
758
            f.size = strm->param.samples_per_frame << 1;
 
759
            strm->rec_cb (strm->user_data, &f);
 
760
            strm->rec_buf_len = 0;
 
761
        }
736
762
    }
737
763
}
738
764
 
739
 
static void PlayCbPcm2(CVoIPDataBuffer *buf, void *user_data)
 
765
static void PlayCbPcm2 (CVoIPDataBuffer *buf, void *user_data)
740
766
{
741
767
    struct vas_stream *strm = (struct vas_stream*) user_data;
742
 
    TPtr8 buffer(0, 0, 0);
 
768
    TPtr8 buffer (0, 0, 0);
743
769
    pjmedia_frame f;
744
770
 
745
771
    /* Get the buffer */
746
 
    buf->GetPayloadPtr(buffer);
 
772
    buf->GetPayloadPtr (buffer);
747
773
 
748
774
    /* Call parent callback */
749
775
    f.buf = strm->play_buf;
750
776
    f.size = strm->param.samples_per_frame << 1;
751
 
    strm->play_cb(strm->user_data, &f);
 
777
    strm->play_cb (strm->user_data, &f);
 
778
 
752
779
    if (f.type != PJMEDIA_FRAME_TYPE_AUDIO) {
753
 
        pjmedia_zero_samples((pj_int16_t*)f.buf, 
754
 
                             strm->param.samples_per_frame);
 
780
        pjmedia_zero_samples ( (pj_int16_t*) f.buf,
 
781
                               strm->param.samples_per_frame);
755
782
    }
 
783
 
756
784
    f.size = strm->param.samples_per_frame << 1;
757
785
 
758
786
    /* Init buffer attributes and header. */
759
787
    buffer.Zero();
760
 
    buffer.Append((TUint8*)f.buf, f.size);
 
788
    buffer.Append ( (TUint8*) f.buf, f.size);
761
789
 
762
790
    /* Set the buffer */
763
 
    buf->SetPayloadPtr(buffer);
 
791
    buf->SetPayloadPtr (buffer);
764
792
}
765
793
 
766
794
#else // not USE_NATIVE_PCM
767
795
 
768
 
static void RecCbPcm(CVoIPDataBuffer *buf, void *user_data)
 
796
static void RecCbPcm (CVoIPDataBuffer *buf, void *user_data)
769
797
{
770
798
    struct vas_stream *strm = (struct vas_stream*) user_data;
771
 
    TPtr8 buffer(0, 0, 0);
 
799
    TPtr8 buffer (0, 0, 0);
772
800
 
773
801
    /* Get the buffer */
774
 
    buf->GetPayloadPtr(buffer);
775
 
    
 
802
    buf->GetPayloadPtr (buffer);
 
803
 
776
804
    /* Buffer has to contain normal speech. */
777
 
    pj_assert(buffer[0] == 1 && buffer[1] == 0);
 
805
    pj_assert (buffer[0] == 1 && buffer[1] == 0);
778
806
 
779
807
    /* Detect the recorder G.711 frame size, player frame size will follow
780
808
     * this recorder frame size.
781
809
     */
782
810
    if (vas_g711_frame_len == 0) {
783
 
        vas_g711_frame_len = buffer.Length() < 160? 80 : 160;
784
 
        TRACE_((THIS_FILE, "Detected VAS G.711 frame size = %u samples",
785
 
                vas_g711_frame_len));
 
811
        vas_g711_frame_len = buffer.Length() < 160? 80 : 160;
 
812
        TRACE_ ( (THIS_FILE, "Detected VAS G.711 frame size = %u samples",
 
813
                  vas_g711_frame_len));
786
814
    }
787
815
 
788
816
    /* Decode VAS buffer (coded in G.711) and put the PCM result into rec_buf.
791
819
    unsigned samples_processed = 0;
792
820
 
793
821
    while (samples_processed < vas_g711_frame_len) {
794
 
        unsigned samples_to_process;
795
 
        unsigned samples_req;
796
 
 
797
 
        samples_to_process = vas_g711_frame_len - samples_processed;
798
 
        samples_req = (strm->param.samples_per_frame /
799
 
                       strm->param.channel_count /
800
 
                       strm->resample_factor) -
801
 
                      strm->rec_buf_len;
802
 
        if (samples_to_process > samples_req)
803
 
            samples_to_process = samples_req;
804
 
 
805
 
        pjmedia_ulaw_decode(&strm->rec_buf[strm->rec_buf_len],
806
 
                            buffer.Ptr() + 2 + samples_processed,
807
 
                            samples_to_process);
808
 
 
809
 
        strm->rec_buf_len += samples_to_process;
810
 
        samples_processed += samples_to_process;
811
 
 
812
 
        /* Buffer is full, time to call parent callback */
813
 
        if (strm->rec_buf_len == strm->param.samples_per_frame / 
814
 
                                 strm->param.channel_count /
815
 
                                 strm->resample_factor) 
816
 
        {
817
 
            pjmedia_frame f;
818
 
 
819
 
            /* Need to resample clock rate? */
820
 
            if (strm->rec_resample) {
821
 
                unsigned resampled = 0;
822
 
                
823
 
                while (resampled < strm->rec_buf_len) {
824
 
                    pjmedia_resample_run(strm->rec_resample, 
825
 
                                &strm->rec_buf[resampled],
826
 
                                strm->pcm_buf + 
827
 
                                resampled * strm->resample_factor);
828
 
                    resampled += 80;
829
 
                }
830
 
                f.buf = strm->pcm_buf;
831
 
            } else {
832
 
                f.buf = strm->rec_buf;
833
 
            }
834
 
 
835
 
            /* Need to convert channel count? */
836
 
            if (strm->param.channel_count != 1) {
837
 
                pjmedia_convert_channel_1ton((pj_int16_t*)f.buf,
838
 
                                             (pj_int16_t*)f.buf,
839
 
                                             strm->param.channel_count,
840
 
                                             strm->param.samples_per_frame /
841
 
                                             strm->param.channel_count,
842
 
                                             0);
843
 
            }
844
 
 
845
 
            /* Call parent callback */
846
 
            f.type = PJMEDIA_FRAME_TYPE_AUDIO;
847
 
            f.size = strm->param.samples_per_frame << 1;
848
 
            strm->rec_cb(strm->user_data, &f);
849
 
            strm->rec_buf_len = 0;
850
 
        }
 
822
        unsigned samples_to_process;
 
823
        unsigned samples_req;
 
824
 
 
825
        samples_to_process = vas_g711_frame_len - samples_processed;
 
826
        samples_req = (strm->param.samples_per_frame /
 
827
                       strm->param.channel_count /
 
828
                       strm->resample_factor) -
 
829
                      strm->rec_buf_len;
 
830
 
 
831
        if (samples_to_process > samples_req)
 
832
            samples_to_process = samples_req;
 
833
 
 
834
        pjmedia_ulaw_decode (&strm->rec_buf[strm->rec_buf_len],
 
835
                             buffer.Ptr() + 2 + samples_processed,
 
836
                             samples_to_process);
 
837
 
 
838
        strm->rec_buf_len += samples_to_process;
 
839
        samples_processed += samples_to_process;
 
840
 
 
841
        /* Buffer is full, time to call parent callback */
 
842
        if (strm->rec_buf_len == strm->param.samples_per_frame /
 
843
                strm->param.channel_count /
 
844
                strm->resample_factor) {
 
845
            pjmedia_frame f;
 
846
 
 
847
            /* Need to resample clock rate? */
 
848
            if (strm->rec_resample) {
 
849
                unsigned resampled = 0;
 
850
 
 
851
                while (resampled < strm->rec_buf_len) {
 
852
                    pjmedia_resample_run (strm->rec_resample,
 
853
                                          &strm->rec_buf[resampled],
 
854
                                          strm->pcm_buf +
 
855
                                          resampled * strm->resample_factor);
 
856
                    resampled += 80;
 
857
                }
 
858
 
 
859
                f.buf = strm->pcm_buf;
 
860
            } else {
 
861
                f.buf = strm->rec_buf;
 
862
            }
 
863
 
 
864
            /* Need to convert channel count? */
 
865
            if (strm->param.channel_count != 1) {
 
866
                pjmedia_convert_channel_1ton ( (pj_int16_t*) f.buf,
 
867
                                               (pj_int16_t*) f.buf,
 
868
                                               strm->param.channel_count,
 
869
                                               strm->param.samples_per_frame /
 
870
                                               strm->param.channel_count,
 
871
                                               0);
 
872
            }
 
873
 
 
874
            /* Call parent callback */
 
875
            f.type = PJMEDIA_FRAME_TYPE_AUDIO;
 
876
            f.size = strm->param.samples_per_frame << 1;
 
877
            strm->rec_cb (strm->user_data, &f);
 
878
            strm->rec_buf_len = 0;
 
879
        }
851
880
    }
852
881
}
853
882
 
854
883
#endif // USE_NATIVE_PCM
855
884
 
856
 
static void PlayCbPcm(CVoIPDataBuffer *buf, void *user_data)
 
885
static void PlayCbPcm (CVoIPDataBuffer *buf, void *user_data)
857
886
{
858
887
    struct vas_stream *strm = (struct vas_stream*) user_data;
859
888
    unsigned g711_frame_len = vas_g711_frame_len;
860
 
    TPtr8 buffer(0, 0, 0);
 
889
    TPtr8 buffer (0, 0, 0);
861
890
 
862
891
    /* Get the buffer */
863
 
    buf->GetPayloadPtr(buffer);
 
892
    buf->GetPayloadPtr (buffer);
864
893
 
865
894
    /* Init buffer attributes and header. */
866
895
    buffer.Zero();
867
 
    buffer.Append(1);
868
 
    buffer.Append(0);
 
896
    buffer.Append (1);
 
897
    buffer.Append (0);
869
898
 
870
899
    /* Assume frame size is 10ms if frame size hasn't been known. */
871
900
    if (g711_frame_len == 0)
872
 
        g711_frame_len = 80;
 
901
        g711_frame_len = 80;
873
902
 
874
903
    /* Call parent stream callback to get PCM samples to play,
875
904
     * encode the PCM samples into G.711 and put it into VAS buffer.
876
905
     */
877
906
    unsigned samples_processed = 0;
878
 
    
 
907
 
879
908
    while (samples_processed < g711_frame_len) {
880
 
        /* Need more samples to play, time to call parent callback */
881
 
        if (strm->play_buf_len == 0) {
882
 
            pjmedia_frame f;
883
 
            unsigned samples_got;
884
 
            
885
 
            f.size = strm->param.samples_per_frame << 1;
886
 
            if (strm->play_resample || strm->param.channel_count != 1)
887
 
                f.buf = strm->pcm_buf;
888
 
            else
889
 
                f.buf = strm->play_buf;
890
 
 
891
 
            /* Call parent callback */
892
 
            strm->play_cb(strm->user_data, &f);
893
 
            if (f.type != PJMEDIA_FRAME_TYPE_AUDIO) {
894
 
                pjmedia_zero_samples((pj_int16_t*)f.buf, 
895
 
                                     strm->param.samples_per_frame);
896
 
            }
897
 
            
898
 
            samples_got = strm->param.samples_per_frame / 
899
 
                          strm->param.channel_count /
900
 
                          strm->resample_factor;
901
 
 
902
 
            /* Need to convert channel count? */
903
 
            if (strm->param.channel_count != 1) {
904
 
                pjmedia_convert_channel_nto1((pj_int16_t*)f.buf,
905
 
                                             (pj_int16_t*)f.buf,
906
 
                                             strm->param.channel_count,
907
 
                                             strm->param.samples_per_frame,
908
 
                                             PJ_FALSE,
909
 
                                             0);
910
 
            }
911
 
 
912
 
            /* Need to resample clock rate? */
913
 
            if (strm->play_resample) {
914
 
                unsigned resampled = 0;
915
 
                
916
 
                while (resampled < samples_got) 
917
 
                {
918
 
                    pjmedia_resample_run(strm->play_resample, 
919
 
                                strm->pcm_buf + 
920
 
                                resampled * strm->resample_factor,
921
 
                                &strm->play_buf[resampled]);
922
 
                    resampled += 80;
923
 
                }
924
 
            }
925
 
            
926
 
            strm->play_buf_len = samples_got;
927
 
            strm->play_buf_start = 0;
928
 
        }
929
 
 
930
 
        unsigned tmp;
931
 
 
932
 
        tmp = PJ_MIN(strm->play_buf_len, g711_frame_len - samples_processed);
933
 
        pjmedia_ulaw_encode((pj_uint8_t*)&strm->play_buf[strm->play_buf_start],
934
 
                            &strm->play_buf[strm->play_buf_start],
935
 
                            tmp);
936
 
        buffer.Append((TUint8*)&strm->play_buf[strm->play_buf_start], tmp);
937
 
        samples_processed += tmp;
938
 
        strm->play_buf_len -= tmp;
939
 
        strm->play_buf_start += tmp;
 
909
        /* Need more samples to play, time to call parent callback */
 
910
        if (strm->play_buf_len == 0) {
 
911
            pjmedia_frame f;
 
912
            unsigned samples_got;
 
913
 
 
914
            f.size = strm->param.samples_per_frame << 1;
 
915
 
 
916
            if (strm->play_resample || strm->param.channel_count != 1)
 
917
                f.buf = strm->pcm_buf;
 
918
            else
 
919
                f.buf = strm->play_buf;
 
920
 
 
921
            /* Call parent callback */
 
922
            strm->play_cb (strm->user_data, &f);
 
923
 
 
924
            if (f.type != PJMEDIA_FRAME_TYPE_AUDIO) {
 
925
                pjmedia_zero_samples ( (pj_int16_t*) f.buf,
 
926
                                       strm->param.samples_per_frame);
 
927
            }
 
928
 
 
929
            samples_got = strm->param.samples_per_frame /
 
930
                          strm->param.channel_count /
 
931
                          strm->resample_factor;
 
932
 
 
933
            /* Need to convert channel count? */
 
934
            if (strm->param.channel_count != 1) {
 
935
                pjmedia_convert_channel_nto1 ( (pj_int16_t*) f.buf,
 
936
                                               (pj_int16_t*) f.buf,
 
937
                                               strm->param.channel_count,
 
938
                                               strm->param.samples_per_frame,
 
939
                                               PJ_FALSE,
 
940
                                               0);
 
941
            }
 
942
 
 
943
            /* Need to resample clock rate? */
 
944
            if (strm->play_resample) {
 
945
                unsigned resampled = 0;
 
946
 
 
947
                while (resampled < samples_got) {
 
948
                    pjmedia_resample_run (strm->play_resample,
 
949
                                          strm->pcm_buf +
 
950
                                          resampled * strm->resample_factor,
 
951
                                          &strm->play_buf[resampled]);
 
952
                    resampled += 80;
 
953
                }
 
954
            }
 
955
 
 
956
            strm->play_buf_len = samples_got;
 
957
            strm->play_buf_start = 0;
 
958
        }
 
959
 
 
960
        unsigned tmp;
 
961
 
 
962
        tmp = PJ_MIN (strm->play_buf_len, g711_frame_len - samples_processed);
 
963
        pjmedia_ulaw_encode ( (pj_uint8_t*) &strm->play_buf[strm->play_buf_start],
 
964
                              &strm->play_buf[strm->play_buf_start],
 
965
                              tmp);
 
966
        buffer.Append ( (TUint8*) &strm->play_buf[strm->play_buf_start], tmp);
 
967
        samples_processed += tmp;
 
968
        strm->play_buf_len -= tmp;
 
969
        strm->play_buf_start += tmp;
940
970
    }
941
971
 
942
972
    /* Set the buffer */
943
 
    buf->SetPayloadPtr(buffer);
 
973
    buf->SetPayloadPtr (buffer);
944
974
}
945
975
 
946
976
/****************************************************************************
947
977
 * Internal VAS callbacks for non-PCM format
948
978
 */
949
979
 
950
 
static void RecCb(CVoIPDataBuffer *buf, void *user_data)
 
980
static void RecCb (CVoIPDataBuffer *buf, void *user_data)
951
981
{
952
982
    struct vas_stream *strm = (struct vas_stream*) user_data;
953
983
    pjmedia_frame_ext *frame = (pjmedia_frame_ext*) strm->rec_buf;
954
 
    TPtr8 buffer(0, 0, 0);
 
984
    TPtr8 buffer (0, 0, 0);
955
985
 
956
986
    /* Get the buffer */
957
 
    buf->GetPayloadPtr(buffer);
958
 
    
959
 
    switch(strm->param.ext_fmt.id) {
960
 
    case PJMEDIA_FORMAT_AMR:
961
 
        {
962
 
            const pj_uint8_t *p = (const pj_uint8_t*)buffer.Ptr() + 1;
963
 
            unsigned len = buffer.Length() - 1;
964
 
            
965
 
            pjmedia_frame_ext_append_subframe(frame, p, len << 3, 160);
966
 
            if (frame->samples_cnt == strm->param.samples_per_frame) {
967
 
                frame->base.type = PJMEDIA_FRAME_TYPE_EXTENDED;
968
 
                strm->rec_cb(strm->user_data, (pjmedia_frame*)frame);
969
 
                frame->samples_cnt = 0;
970
 
                frame->subframe_cnt = 0;
971
 
            }
972
 
        }
973
 
        break;
974
 
        
975
 
    case PJMEDIA_FORMAT_G729:
976
 
        {
977
 
            /* Check if we got a normal or SID frame. */
978
 
            if (buffer[0] != 0) {
979
 
                enum { NORMAL_LEN = 22, SID_LEN = 8 };
980
 
                TBitStream *bitstream = (TBitStream*)strm->strm_data;
981
 
                unsigned src_len = buffer.Length()- 2;
982
 
                
983
 
                pj_assert(src_len == NORMAL_LEN || src_len == SID_LEN);
984
 
                
985
 
                const TDesC8& p = bitstream->CompressG729Frame(
986
 
                                            buffer.Right(src_len), 
987
 
                                            src_len == SID_LEN);
988
 
                
989
 
                pjmedia_frame_ext_append_subframe(frame, p.Ptr(), 
990
 
                                                  p.Length() << 3, 80);
991
 
            } else { /* We got null frame. */
992
 
                pjmedia_frame_ext_append_subframe(frame, NULL, 0, 80);
993
 
            }
994
 
            
995
 
            if (frame->samples_cnt == strm->param.samples_per_frame) {
996
 
                frame->base.type = PJMEDIA_FRAME_TYPE_EXTENDED;
997
 
                strm->rec_cb(strm->user_data, (pjmedia_frame*)frame);
998
 
                frame->samples_cnt = 0;
999
 
                frame->subframe_cnt = 0;
1000
 
            }
1001
 
        }
1002
 
        break;
1003
 
 
1004
 
    case PJMEDIA_FORMAT_ILBC:
1005
 
        {
1006
 
            unsigned samples_got;
1007
 
            
1008
 
            samples_got = strm->param.ext_fmt.bitrate == 15200? 160 : 240;
1009
 
            
1010
 
            /* Check if we got a normal or SID frame. */
1011
 
            if (buffer[0] != 0) {
1012
 
                const pj_uint8_t *p = (const pj_uint8_t*)buffer.Ptr() + 2;
1013
 
                unsigned len = buffer.Length() - 2;
1014
 
                
1015
 
                pjmedia_frame_ext_append_subframe(frame, p, len << 3,
1016
 
                                                  samples_got);
1017
 
            } else { /* We got null frame. */
1018
 
                pjmedia_frame_ext_append_subframe(frame, NULL, 0, samples_got);
1019
 
            }
1020
 
            
1021
 
            if (frame->samples_cnt == strm->param.samples_per_frame) {
1022
 
                frame->base.type = PJMEDIA_FRAME_TYPE_EXTENDED;
1023
 
                strm->rec_cb(strm->user_data, (pjmedia_frame*)frame);
1024
 
                frame->samples_cnt = 0;
1025
 
                frame->subframe_cnt = 0;
1026
 
            }
1027
 
        }
1028
 
        break;
1029
 
        
1030
 
    case PJMEDIA_FORMAT_PCMU:
1031
 
    case PJMEDIA_FORMAT_PCMA:
1032
 
        {
1033
 
            unsigned samples_processed = 0;
1034
 
            
1035
 
            /* Make sure it is normal frame. */
1036
 
            pj_assert(buffer[0] == 1 && buffer[1] == 0);
1037
 
 
1038
 
            /* Detect the recorder G.711 frame size, player frame size will 
1039
 
             * follow this recorder frame size.
1040
 
             */
1041
 
            if (vas_g711_frame_len == 0) {
1042
 
                vas_g711_frame_len = buffer.Length() < 160? 80 : 160;
1043
 
                TRACE_((THIS_FILE, "Detected VAS G.711 frame size = %u samples",
1044
 
                        vas_g711_frame_len));
1045
 
            }
1046
 
            
1047
 
            /* Convert VAS buffer format into pjmedia_frame_ext. Whenever 
1048
 
             * samples count in the frame is equal to stream's samples per 
1049
 
             * frame, call parent stream callback.
1050
 
             */
1051
 
            while (samples_processed < vas_g711_frame_len) {
1052
 
                unsigned tmp;
1053
 
                const pj_uint8_t *pb = (const pj_uint8_t*)buffer.Ptr() +
1054
 
                                       2 + samples_processed;
1055
 
    
1056
 
                tmp = PJ_MIN(strm->param.samples_per_frame - frame->samples_cnt,
1057
 
                             vas_g711_frame_len - samples_processed);
1058
 
                
1059
 
                pjmedia_frame_ext_append_subframe(frame, pb, tmp << 3, tmp);
1060
 
                samples_processed += tmp;
1061
 
    
1062
 
                if (frame->samples_cnt == strm->param.samples_per_frame) {
1063
 
                    frame->base.type = PJMEDIA_FRAME_TYPE_EXTENDED;
1064
 
                    strm->rec_cb(strm->user_data, (pjmedia_frame*)frame);
1065
 
                    frame->samples_cnt = 0;
1066
 
                    frame->subframe_cnt = 0;
1067
 
                }
1068
 
            }
1069
 
        }
1070
 
        break;
1071
 
        
1072
 
    default:
1073
 
        break;
 
987
    buf->GetPayloadPtr (buffer);
 
988
 
 
989
    switch (strm->param.ext_fmt.id) {
 
990
        case PJMEDIA_FORMAT_AMR: {
 
991
            const pj_uint8_t *p = (const pj_uint8_t*) buffer.Ptr() + 1;
 
992
            unsigned len = buffer.Length() - 1;
 
993
 
 
994
            pjmedia_frame_ext_append_subframe (frame, p, len << 3, 160);
 
995
 
 
996
            if (frame->samples_cnt == strm->param.samples_per_frame) {
 
997
                frame->base.type = PJMEDIA_FRAME_TYPE_EXTENDED;
 
998
                strm->rec_cb (strm->user_data, (pjmedia_frame*) frame);
 
999
                frame->samples_cnt = 0;
 
1000
                frame->subframe_cnt = 0;
 
1001
            }
 
1002
        }
 
1003
        break;
 
1004
 
 
1005
        case PJMEDIA_FORMAT_G729: {
 
1006
            /* Check if we got a normal or SID frame. */
 
1007
            if (buffer[0] != 0) {
 
1008
                enum { NORMAL_LEN = 22, SID_LEN = 8 };
 
1009
                TBitStream *bitstream = (TBitStream*) strm->strm_data;
 
1010
                unsigned src_len = buffer.Length()- 2;
 
1011
 
 
1012
                pj_assert (src_len == NORMAL_LEN || src_len == SID_LEN);
 
1013
 
 
1014
                const TDesC8& p = bitstream->CompressG729Frame (
 
1015
                                      buffer.Right (src_len),
 
1016
                                      src_len == SID_LEN);
 
1017
 
 
1018
                pjmedia_frame_ext_append_subframe (frame, p.Ptr(),
 
1019
                                                   p.Length() << 3, 80);
 
1020
            } else { /* We got null frame. */
 
1021
                pjmedia_frame_ext_append_subframe (frame, NULL, 0, 80);
 
1022
            }
 
1023
 
 
1024
            if (frame->samples_cnt == strm->param.samples_per_frame) {
 
1025
                frame->base.type = PJMEDIA_FRAME_TYPE_EXTENDED;
 
1026
                strm->rec_cb (strm->user_data, (pjmedia_frame*) frame);
 
1027
                frame->samples_cnt = 0;
 
1028
                frame->subframe_cnt = 0;
 
1029
            }
 
1030
        }
 
1031
        break;
 
1032
 
 
1033
        case PJMEDIA_FORMAT_ILBC: {
 
1034
            unsigned samples_got;
 
1035
 
 
1036
            samples_got = strm->param.ext_fmt.bitrate == 15200? 160 : 240;
 
1037
 
 
1038
            /* Check if we got a normal or SID frame. */
 
1039
            if (buffer[0] != 0) {
 
1040
                const pj_uint8_t *p = (const pj_uint8_t*) buffer.Ptr() + 2;
 
1041
                unsigned len = buffer.Length() - 2;
 
1042
 
 
1043
                pjmedia_frame_ext_append_subframe (frame, p, len << 3,
 
1044
                                                   samples_got);
 
1045
            } else { /* We got null frame. */
 
1046
                pjmedia_frame_ext_append_subframe (frame, NULL, 0, samples_got);
 
1047
            }
 
1048
 
 
1049
            if (frame->samples_cnt == strm->param.samples_per_frame) {
 
1050
                frame->base.type = PJMEDIA_FRAME_TYPE_EXTENDED;
 
1051
                strm->rec_cb (strm->user_data, (pjmedia_frame*) frame);
 
1052
                frame->samples_cnt = 0;
 
1053
                frame->subframe_cnt = 0;
 
1054
            }
 
1055
        }
 
1056
        break;
 
1057
 
 
1058
        case PJMEDIA_FORMAT_PCMU:
 
1059
        case PJMEDIA_FORMAT_PCMA: {
 
1060
            unsigned samples_processed = 0;
 
1061
 
 
1062
            /* Make sure it is normal frame. */
 
1063
            pj_assert (buffer[0] == 1 && buffer[1] == 0);
 
1064
 
 
1065
            /* Detect the recorder G.711 frame size, player frame size will
 
1066
             * follow this recorder frame size.
 
1067
             */
 
1068
            if (vas_g711_frame_len == 0) {
 
1069
                vas_g711_frame_len = buffer.Length() < 160? 80 : 160;
 
1070
                TRACE_ ( (THIS_FILE, "Detected VAS G.711 frame size = %u samples",
 
1071
                          vas_g711_frame_len));
 
1072
            }
 
1073
 
 
1074
            /* Convert VAS buffer format into pjmedia_frame_ext. Whenever
 
1075
             * samples count in the frame is equal to stream's samples per
 
1076
             * frame, call parent stream callback.
 
1077
             */
 
1078
            while (samples_processed < vas_g711_frame_len) {
 
1079
                unsigned tmp;
 
1080
                const pj_uint8_t *pb = (const pj_uint8_t*) buffer.Ptr() +
 
1081
                                       2 + samples_processed;
 
1082
 
 
1083
                tmp = PJ_MIN (strm->param.samples_per_frame - frame->samples_cnt,
 
1084
                              vas_g711_frame_len - samples_processed);
 
1085
 
 
1086
                pjmedia_frame_ext_append_subframe (frame, pb, tmp << 3, tmp);
 
1087
                samples_processed += tmp;
 
1088
 
 
1089
                if (frame->samples_cnt == strm->param.samples_per_frame) {
 
1090
                    frame->base.type = PJMEDIA_FRAME_TYPE_EXTENDED;
 
1091
                    strm->rec_cb (strm->user_data, (pjmedia_frame*) frame);
 
1092
                    frame->samples_cnt = 0;
 
1093
                    frame->subframe_cnt = 0;
 
1094
                }
 
1095
            }
 
1096
        }
 
1097
        break;
 
1098
 
 
1099
        default:
 
1100
            break;
1074
1101
    }
1075
1102
}
1076
1103
 
1077
 
static void PlayCb(CVoIPDataBuffer *buf, void *user_data)
 
1104
static void PlayCb (CVoIPDataBuffer *buf, void *user_data)
1078
1105
{
1079
1106
    struct vas_stream *strm = (struct vas_stream*) user_data;
1080
1107
    pjmedia_frame_ext *frame = (pjmedia_frame_ext*) strm->play_buf;
1081
 
    TPtr8 buffer(0, 0, 0);
 
1108
    TPtr8 buffer (0, 0, 0);
1082
1109
 
1083
1110
    /* Get the buffer */
1084
 
    buf->GetPayloadPtr(buffer);
 
1111
    buf->GetPayloadPtr (buffer);
1085
1112
 
1086
1113
    /* Init buffer attributes and header. */
1087
1114
    buffer.Zero();
1088
1115
 
1089
 
    switch(strm->param.ext_fmt.id) {
1090
 
    case PJMEDIA_FORMAT_AMR:
1091
 
        {
1092
 
            if (frame->samples_cnt == 0) {
1093
 
                frame->base.type = PJMEDIA_FRAME_TYPE_EXTENDED;
1094
 
                strm->play_cb(strm->user_data, (pjmedia_frame*)frame);
1095
 
                pj_assert(frame->base.type==PJMEDIA_FRAME_TYPE_EXTENDED ||
1096
 
                          frame->base.type==PJMEDIA_FRAME_TYPE_NONE);
1097
 
            }
1098
 
 
1099
 
            if (frame->base.type == PJMEDIA_FRAME_TYPE_EXTENDED) { 
1100
 
                pjmedia_frame_ext_subframe *sf;
1101
 
                unsigned samples_cnt;
1102
 
                
1103
 
                sf = pjmedia_frame_ext_get_subframe(frame, 0);
1104
 
                samples_cnt = frame->samples_cnt / frame->subframe_cnt;
1105
 
                
1106
 
                if (sf->data && sf->bitlen) {
1107
 
                    /* AMR header for VAS is one byte, the format (may be!):
1108
 
                     * 0xxxxy00, where xxxx:frame type, y:not sure. 
1109
 
                     */
1110
 
                    unsigned len = (sf->bitlen+7)>>3;
1111
 
                    enum {SID_FT = 8 };
1112
 
                    pj_uint8_t amr_header = 4, ft = SID_FT;
1113
 
 
1114
 
                    if (len >= pjmedia_codec_amrnb_framelen[0])
1115
 
                        ft = pjmedia_codec_amr_get_mode2(PJ_TRUE, len);
1116
 
                    
1117
 
                    amr_header |= ft << 3;
1118
 
                    buffer.Append(amr_header);
1119
 
                    
1120
 
                    buffer.Append((TUint8*)sf->data, len);
1121
 
                } else {
1122
 
                    buffer.Append(0);
1123
 
                }
1124
 
 
1125
 
                pjmedia_frame_ext_pop_subframes(frame, 1);
1126
 
            
1127
 
            } else { /* PJMEDIA_FRAME_TYPE_NONE */
1128
 
                buffer.Append(0);
1129
 
                
1130
 
                frame->samples_cnt = 0;
1131
 
                frame->subframe_cnt = 0;
1132
 
            }
1133
 
        }
1134
 
        break;
1135
 
        
1136
 
    case PJMEDIA_FORMAT_G729:
1137
 
        {
1138
 
            if (frame->samples_cnt == 0) {
1139
 
                frame->base.type = PJMEDIA_FRAME_TYPE_EXTENDED;
1140
 
                strm->play_cb(strm->user_data, (pjmedia_frame*)frame);
1141
 
                pj_assert(frame->base.type==PJMEDIA_FRAME_TYPE_EXTENDED ||
1142
 
                          frame->base.type==PJMEDIA_FRAME_TYPE_NONE);
1143
 
            }
1144
 
 
1145
 
            if (frame->base.type == PJMEDIA_FRAME_TYPE_EXTENDED) { 
1146
 
                pjmedia_frame_ext_subframe *sf;
1147
 
                unsigned samples_cnt;
1148
 
                
1149
 
                sf = pjmedia_frame_ext_get_subframe(frame, 0);
1150
 
                samples_cnt = frame->samples_cnt / frame->subframe_cnt;
1151
 
                
1152
 
                if (sf->data && sf->bitlen) {
1153
 
                    enum { NORMAL_LEN = 10, SID_LEN = 2 };
1154
 
                    pj_bool_t sid_frame = ((sf->bitlen >> 3) == SID_LEN);
1155
 
                    TBitStream *bitstream = (TBitStream*)strm->strm_data;
1156
 
                    const TPtrC8 src(sf->data, sf->bitlen>>3);
1157
 
                    const TDesC8 &dst = bitstream->ExpandG729Frame(src,
1158
 
                                                                   sid_frame); 
1159
 
                    if (sid_frame) {
1160
 
                        buffer.Append(2);
1161
 
                        buffer.Append(0);
1162
 
                    } else {
1163
 
                        buffer.Append(1);
1164
 
                        buffer.Append(0);
1165
 
                    }
1166
 
                    buffer.Append(dst);
1167
 
                } else {
1168
 
                    buffer.Append(2);
1169
 
                    buffer.Append(0);
1170
 
 
1171
 
                    buffer.AppendFill(0, 22);
1172
 
                }
1173
 
 
1174
 
                pjmedia_frame_ext_pop_subframes(frame, 1);
1175
 
            
1176
 
            } else { /* PJMEDIA_FRAME_TYPE_NONE */
1177
 
                buffer.Append(2);
1178
 
                buffer.Append(0);
1179
 
                
1180
 
                buffer.AppendFill(0, 22);
1181
 
            }
1182
 
        }
1183
 
        break;
1184
 
        
1185
 
    case PJMEDIA_FORMAT_ILBC:
1186
 
        {
1187
 
            if (frame->samples_cnt == 0) {
1188
 
                frame->base.type = PJMEDIA_FRAME_TYPE_EXTENDED;
1189
 
                strm->play_cb(strm->user_data, (pjmedia_frame*)frame);
1190
 
                pj_assert(frame->base.type==PJMEDIA_FRAME_TYPE_EXTENDED ||
1191
 
                          frame->base.type==PJMEDIA_FRAME_TYPE_NONE);
1192
 
            }
1193
 
 
1194
 
            if (frame->base.type == PJMEDIA_FRAME_TYPE_EXTENDED) { 
1195
 
                pjmedia_frame_ext_subframe *sf;
1196
 
                unsigned samples_cnt;
1197
 
                
1198
 
                sf = pjmedia_frame_ext_get_subframe(frame, 0);
1199
 
                samples_cnt = frame->samples_cnt / frame->subframe_cnt;
1200
 
                
1201
 
                pj_assert((strm->param.ext_fmt.bitrate == 15200 && 
1202
 
                           samples_cnt == 160) ||
1203
 
                          (strm->param.ext_fmt.bitrate != 15200 &&
1204
 
                           samples_cnt == 240));
1205
 
                
1206
 
                if (sf->data && sf->bitlen) {
1207
 
                    buffer.Append(1);
1208
 
                    buffer.Append(0);
1209
 
                    buffer.Append((TUint8*)sf->data, sf->bitlen>>3);
1210
 
                } else {
1211
 
                    unsigned frame_len;
1212
 
                    
1213
 
                    buffer.Append(1);
1214
 
                    buffer.Append(0);
1215
 
                    
1216
 
                    /* VAS iLBC frame is 20ms or 30ms */
1217
 
                    frame_len = strm->param.ext_fmt.bitrate == 15200? 38 : 50;
1218
 
                    buffer.AppendFill(0, frame_len);
1219
 
                }
1220
 
 
1221
 
                pjmedia_frame_ext_pop_subframes(frame, 1);
1222
 
            
1223
 
            } else { /* PJMEDIA_FRAME_TYPE_NONE */
1224
 
                
1225
 
                unsigned frame_len;
1226
 
                
1227
 
                buffer.Append(1);
1228
 
                buffer.Append(0);
1229
 
                
1230
 
                /* VAS iLBC frame is 20ms or 30ms */
1231
 
                frame_len = strm->param.ext_fmt.bitrate == 15200? 38 : 50;
1232
 
                buffer.AppendFill(0, frame_len);
1233
 
 
1234
 
            }
1235
 
        }
1236
 
        break;
1237
 
        
1238
 
    case PJMEDIA_FORMAT_PCMU:
1239
 
    case PJMEDIA_FORMAT_PCMA:
1240
 
        {
1241
 
            unsigned samples_ready = 0;
1242
 
            unsigned samples_req = vas_g711_frame_len;
1243
 
            
1244
 
            /* Assume frame size is 10ms if frame size hasn't been known. */
1245
 
            if (samples_req == 0)
1246
 
                samples_req = 80;
1247
 
            
1248
 
            buffer.Append(1);
1249
 
            buffer.Append(0);
1250
 
            
1251
 
            /* Call parent stream callback to get samples to play. */
1252
 
            while (samples_ready < samples_req) {
1253
 
                if (frame->samples_cnt == 0) {
1254
 
                    frame->base.type = PJMEDIA_FRAME_TYPE_EXTENDED;
1255
 
                    strm->play_cb(strm->user_data, (pjmedia_frame*)frame);
1256
 
                    pj_assert(frame->base.type==PJMEDIA_FRAME_TYPE_EXTENDED ||
1257
 
                              frame->base.type==PJMEDIA_FRAME_TYPE_NONE);
1258
 
                }
1259
 
    
1260
 
                if (frame->base.type == PJMEDIA_FRAME_TYPE_EXTENDED) { 
1261
 
                    pjmedia_frame_ext_subframe *sf;
1262
 
                    unsigned samples_cnt;
1263
 
                    
1264
 
                    sf = pjmedia_frame_ext_get_subframe(frame, 0);
1265
 
                    samples_cnt = frame->samples_cnt / frame->subframe_cnt;
1266
 
                    if (sf->data && sf->bitlen) {
1267
 
                        buffer.Append((TUint8*)sf->data, sf->bitlen>>3);
1268
 
                    } else {
1269
 
                        pj_uint8_t silc;
1270
 
                        silc = (strm->param.ext_fmt.id==PJMEDIA_FORMAT_PCMU)?
1271
 
                                pjmedia_linear2ulaw(0) : pjmedia_linear2alaw(0);
1272
 
                        buffer.AppendFill(silc, samples_cnt);
1273
 
                    }
1274
 
                    samples_ready += samples_cnt;
1275
 
                    
1276
 
                    pjmedia_frame_ext_pop_subframes(frame, 1);
1277
 
                
1278
 
                } else { /* PJMEDIA_FRAME_TYPE_NONE */
1279
 
                    pj_uint8_t silc;
1280
 
                    
1281
 
                    silc = (strm->param.ext_fmt.id==PJMEDIA_FORMAT_PCMU)?
1282
 
                            pjmedia_linear2ulaw(0) : pjmedia_linear2alaw(0);
1283
 
                    buffer.AppendFill(silc, samples_req - samples_ready);
1284
 
 
1285
 
                    samples_ready = samples_req;
1286
 
                    frame->samples_cnt = 0;
1287
 
                    frame->subframe_cnt = 0;
1288
 
                }
1289
 
            }
1290
 
        }
1291
 
        break;
1292
 
        
1293
 
    default:
1294
 
        break;
 
1116
    switch (strm->param.ext_fmt.id) {
 
1117
        case PJMEDIA_FORMAT_AMR: {
 
1118
            if (frame->samples_cnt == 0) {
 
1119
                frame->base.type = PJMEDIA_FRAME_TYPE_EXTENDED;
 
1120
                strm->play_cb (strm->user_data, (pjmedia_frame*) frame);
 
1121
                pj_assert (frame->base.type==PJMEDIA_FRAME_TYPE_EXTENDED ||
 
1122
                           frame->base.type==PJMEDIA_FRAME_TYPE_NONE);
 
1123
            }
 
1124
 
 
1125
            if (frame->base.type == PJMEDIA_FRAME_TYPE_EXTENDED) {
 
1126
                pjmedia_frame_ext_subframe *sf;
 
1127
                unsigned samples_cnt;
 
1128
 
 
1129
                sf = pjmedia_frame_ext_get_subframe (frame, 0);
 
1130
                samples_cnt = frame->samples_cnt / frame->subframe_cnt;
 
1131
 
 
1132
                if (sf->data && sf->bitlen) {
 
1133
                    /* AMR header for VAS is one byte, the format (may be!):
 
1134
                     * 0xxxxy00, where xxxx:frame type, y:not sure.
 
1135
                     */
 
1136
                    unsigned len = (sf->bitlen+7) >>3;
 
1137
                    enum {SID_FT = 8 };
 
1138
                    pj_uint8_t amr_header = 4, ft = SID_FT;
 
1139
 
 
1140
                    if (len >= pjmedia_codec_amrnb_framelen[0])
 
1141
                        ft = pjmedia_codec_amr_get_mode2 (PJ_TRUE, len);
 
1142
 
 
1143
                    amr_header |= ft << 3;
 
1144
                    buffer.Append (amr_header);
 
1145
 
 
1146
                    buffer.Append ( (TUint8*) sf->data, len);
 
1147
                } else {
 
1148
                    buffer.Append (0);
 
1149
                }
 
1150
 
 
1151
                pjmedia_frame_ext_pop_subframes (frame, 1);
 
1152
 
 
1153
            } else { /* PJMEDIA_FRAME_TYPE_NONE */
 
1154
                buffer.Append (0);
 
1155
 
 
1156
                frame->samples_cnt = 0;
 
1157
                frame->subframe_cnt = 0;
 
1158
            }
 
1159
        }
 
1160
        break;
 
1161
 
 
1162
        case PJMEDIA_FORMAT_G729: {
 
1163
            if (frame->samples_cnt == 0) {
 
1164
                frame->base.type = PJMEDIA_FRAME_TYPE_EXTENDED;
 
1165
                strm->play_cb (strm->user_data, (pjmedia_frame*) frame);
 
1166
                pj_assert (frame->base.type==PJMEDIA_FRAME_TYPE_EXTENDED ||
 
1167
                           frame->base.type==PJMEDIA_FRAME_TYPE_NONE);
 
1168
            }
 
1169
 
 
1170
            if (frame->base.type == PJMEDIA_FRAME_TYPE_EXTENDED) {
 
1171
                pjmedia_frame_ext_subframe *sf;
 
1172
                unsigned samples_cnt;
 
1173
 
 
1174
                sf = pjmedia_frame_ext_get_subframe (frame, 0);
 
1175
                samples_cnt = frame->samples_cnt / frame->subframe_cnt;
 
1176
 
 
1177
                if (sf->data && sf->bitlen) {
 
1178
                    enum { NORMAL_LEN = 10, SID_LEN = 2 };
 
1179
                    pj_bool_t sid_frame = ( (sf->bitlen >> 3) == SID_LEN);
 
1180
                    TBitStream *bitstream = (TBitStream*) strm->strm_data;
 
1181
                    const TPtrC8 src (sf->data, sf->bitlen>>3);
 
1182
                    const TDesC8 &dst = bitstream->ExpandG729Frame (src,
 
1183
                                        sid_frame);
 
1184
 
 
1185
                    if (sid_frame) {
 
1186
                        buffer.Append (2);
 
1187
                        buffer.Append (0);
 
1188
                    } else {
 
1189
                        buffer.Append (1);
 
1190
                        buffer.Append (0);
 
1191
                    }
 
1192
 
 
1193
                    buffer.Append (dst);
 
1194
                } else {
 
1195
                    buffer.Append (2);
 
1196
                    buffer.Append (0);
 
1197
 
 
1198
                    buffer.AppendFill (0, 22);
 
1199
                }
 
1200
 
 
1201
                pjmedia_frame_ext_pop_subframes (frame, 1);
 
1202
 
 
1203
            } else { /* PJMEDIA_FRAME_TYPE_NONE */
 
1204
                buffer.Append (2);
 
1205
                buffer.Append (0);
 
1206
 
 
1207
                buffer.AppendFill (0, 22);
 
1208
            }
 
1209
        }
 
1210
        break;
 
1211
 
 
1212
        case PJMEDIA_FORMAT_ILBC: {
 
1213
            if (frame->samples_cnt == 0) {
 
1214
                frame->base.type = PJMEDIA_FRAME_TYPE_EXTENDED;
 
1215
                strm->play_cb (strm->user_data, (pjmedia_frame*) frame);
 
1216
                pj_assert (frame->base.type==PJMEDIA_FRAME_TYPE_EXTENDED ||
 
1217
                           frame->base.type==PJMEDIA_FRAME_TYPE_NONE);
 
1218
            }
 
1219
 
 
1220
            if (frame->base.type == PJMEDIA_FRAME_TYPE_EXTENDED) {
 
1221
                pjmedia_frame_ext_subframe *sf;
 
1222
                unsigned samples_cnt;
 
1223
 
 
1224
                sf = pjmedia_frame_ext_get_subframe (frame, 0);
 
1225
                samples_cnt = frame->samples_cnt / frame->subframe_cnt;
 
1226
 
 
1227
                pj_assert ( (strm->param.ext_fmt.bitrate == 15200 &&
 
1228
                             samples_cnt == 160) ||
 
1229
                            (strm->param.ext_fmt.bitrate != 15200 &&
 
1230
                             samples_cnt == 240));
 
1231
 
 
1232
                if (sf->data && sf->bitlen) {
 
1233
                    buffer.Append (1);
 
1234
                    buffer.Append (0);
 
1235
                    buffer.Append ( (TUint8*) sf->data, sf->bitlen>>3);
 
1236
                } else {
 
1237
                    unsigned frame_len;
 
1238
 
 
1239
                    buffer.Append (1);
 
1240
                    buffer.Append (0);
 
1241
 
 
1242
                    /* VAS iLBC frame is 20ms or 30ms */
 
1243
                    frame_len = strm->param.ext_fmt.bitrate == 15200? 38 : 50;
 
1244
                    buffer.AppendFill (0, frame_len);
 
1245
                }
 
1246
 
 
1247
                pjmedia_frame_ext_pop_subframes (frame, 1);
 
1248
 
 
1249
            } else { /* PJMEDIA_FRAME_TYPE_NONE */
 
1250
 
 
1251
                unsigned frame_len;
 
1252
 
 
1253
                buffer.Append (1);
 
1254
                buffer.Append (0);
 
1255
 
 
1256
                /* VAS iLBC frame is 20ms or 30ms */
 
1257
                frame_len = strm->param.ext_fmt.bitrate == 15200? 38 : 50;
 
1258
                buffer.AppendFill (0, frame_len);
 
1259
 
 
1260
            }
 
1261
        }
 
1262
        break;
 
1263
 
 
1264
        case PJMEDIA_FORMAT_PCMU:
 
1265
        case PJMEDIA_FORMAT_PCMA: {
 
1266
            unsigned samples_ready = 0;
 
1267
            unsigned samples_req = vas_g711_frame_len;
 
1268
 
 
1269
            /* Assume frame size is 10ms if frame size hasn't been known. */
 
1270
            if (samples_req == 0)
 
1271
                samples_req = 80;
 
1272
 
 
1273
            buffer.Append (1);
 
1274
            buffer.Append (0);
 
1275
 
 
1276
            /* Call parent stream callback to get samples to play. */
 
1277
            while (samples_ready < samples_req) {
 
1278
                if (frame->samples_cnt == 0) {
 
1279
                    frame->base.type = PJMEDIA_FRAME_TYPE_EXTENDED;
 
1280
                    strm->play_cb (strm->user_data, (pjmedia_frame*) frame);
 
1281
                    pj_assert (frame->base.type==PJMEDIA_FRAME_TYPE_EXTENDED ||
 
1282
                               frame->base.type==PJMEDIA_FRAME_TYPE_NONE);
 
1283
                }
 
1284
 
 
1285
                if (frame->base.type == PJMEDIA_FRAME_TYPE_EXTENDED) {
 
1286
                    pjmedia_frame_ext_subframe *sf;
 
1287
                    unsigned samples_cnt;
 
1288
 
 
1289
                    sf = pjmedia_frame_ext_get_subframe (frame, 0);
 
1290
                    samples_cnt = frame->samples_cnt / frame->subframe_cnt;
 
1291
 
 
1292
                    if (sf->data && sf->bitlen) {
 
1293
                        buffer.Append ( (TUint8*) sf->data, sf->bitlen>>3);
 
1294
                    } else {
 
1295
                        pj_uint8_t silc;
 
1296
                        silc = (strm->param.ext_fmt.id==PJMEDIA_FORMAT_PCMU) ?
 
1297
                               pjmedia_linear2ulaw (0) : pjmedia_linear2alaw (0);
 
1298
                        buffer.AppendFill (silc, samples_cnt);
 
1299
                    }
 
1300
 
 
1301
                    samples_ready += samples_cnt;
 
1302
 
 
1303
                    pjmedia_frame_ext_pop_subframes (frame, 1);
 
1304
 
 
1305
                } else { /* PJMEDIA_FRAME_TYPE_NONE */
 
1306
                    pj_uint8_t silc;
 
1307
 
 
1308
                    silc = (strm->param.ext_fmt.id==PJMEDIA_FORMAT_PCMU) ?
 
1309
                           pjmedia_linear2ulaw (0) : pjmedia_linear2alaw (0);
 
1310
                    buffer.AppendFill (silc, samples_req - samples_ready);
 
1311
 
 
1312
                    samples_ready = samples_req;
 
1313
                    frame->samples_cnt = 0;
 
1314
                    frame->subframe_cnt = 0;
 
1315
                }
 
1316
            }
 
1317
        }
 
1318
        break;
 
1319
 
 
1320
        default:
 
1321
            break;
1295
1322
    }
1296
1323
 
1297
1324
    /* Set the buffer */
1298
 
    buf->SetPayloadPtr(buffer);
 
1325
    buf->SetPayloadPtr (buffer);
1299
1326
}
1300
1327
 
1301
1328
 
1307
1334
 * C compatible declaration of VAS factory.
1308
1335
 */
1309
1336
PJ_BEGIN_DECL
1310
 
PJ_DECL(pjmedia_aud_dev_factory*)pjmedia_symb_vas_factory(pj_pool_factory *pf);
 
1337
PJ_DECL (pjmedia_aud_dev_factory*) pjmedia_symb_vas_factory (pj_pool_factory *pf);
1311
1338
PJ_END_DECL
1312
1339
 
1313
1340
/*
1314
1341
 * Init VAS audio driver.
1315
1342
 */
1316
 
PJ_DEF(pjmedia_aud_dev_factory*) pjmedia_symb_vas_factory(pj_pool_factory *pf)
 
1343
PJ_DEF (pjmedia_aud_dev_factory*) pjmedia_symb_vas_factory (pj_pool_factory *pf)
1317
1344
{
1318
1345
    struct vas_factory *f;
1319
1346
    pj_pool_t *pool;
1320
1347
 
1321
 
    pool = pj_pool_create(pf, "VAS", 1000, 1000, NULL);
1322
 
    f = PJ_POOL_ZALLOC_T(pool, struct vas_factory);
 
1348
    pool = pj_pool_create (pf, "VAS", 1000, 1000, NULL);
 
1349
    f = PJ_POOL_ZALLOC_T (pool, struct vas_factory);
1323
1350
    f->pf = pf;
1324
1351
    f->pool = pool;
1325
1352
    f->base.op = &factory_op;
1328
1355
}
1329
1356
 
1330
1357
/* API: init factory */
1331
 
static pj_status_t factory_init(pjmedia_aud_dev_factory *f)
 
1358
static pj_status_t factory_init (pjmedia_aud_dev_factory *f)
1332
1359
{
1333
 
    struct vas_factory *af = (struct vas_factory*)f;
 
1360
    struct vas_factory *af = (struct vas_factory*) f;
1334
1361
    CVoIPUtilityFactory *vas_factory_;
1335
1362
    CVoIPAudioUplinkStream *vas_uplink;
1336
1363
    CVoIPAudioDownlinkStream *vas_dnlink;
1337
1364
    RArray<TVoIPCodecFormat> uplink_formats, dnlink_formats;
1338
1365
    unsigned ext_fmt_cnt = 0;
1339
 
    TVersion vas_version(1, 0, 0); /* Not really used at this time */
 
1366
    TVersion vas_version (1, 0, 0); /* Not really used at this time */
1340
1367
    TInt err;
1341
1368
 
1342
 
    pj_ansi_strcpy(af->dev_info.name, "S60 VAS");
 
1369
    pj_ansi_strcpy (af->dev_info.name, "S60 VAS");
1343
1370
    af->dev_info.default_samples_per_sec = 8000;
1344
1371
    af->dev_info.caps = PJMEDIA_AUD_DEV_CAP_EXT_FORMAT |
1345
 
                        //PJMEDIA_AUD_DEV_CAP_INPUT_VOLUME_SETTING |
1346
 
                        PJMEDIA_AUD_DEV_CAP_OUTPUT_VOLUME_SETTING |
1347
 
                        PJMEDIA_AUD_DEV_CAP_OUTPUT_ROUTE |
1348
 
                        PJMEDIA_AUD_DEV_CAP_VAD |
1349
 
                        PJMEDIA_AUD_DEV_CAP_CNG;
1350
 
    af->dev_info.routes = PJMEDIA_AUD_DEV_ROUTE_EARPIECE | 
1351
 
                          PJMEDIA_AUD_DEV_ROUTE_LOUDSPEAKER;
 
1372
                        //PJMEDIA_AUD_DEV_CAP_INPUT_VOLUME_SETTING |
 
1373
                        PJMEDIA_AUD_DEV_CAP_OUTPUT_VOLUME_SETTING |
 
1374
                        PJMEDIA_AUD_DEV_CAP_OUTPUT_ROUTE |
 
1375
                        PJMEDIA_AUD_DEV_CAP_VAD |
 
1376
                        PJMEDIA_AUD_DEV_CAP_CNG;
 
1377
    af->dev_info.routes = PJMEDIA_AUD_DEV_ROUTE_EARPIECE |
 
1378
                          PJMEDIA_AUD_DEV_ROUTE_LOUDSPEAKER;
1352
1379
    af->dev_info.input_count = 1;
1353
1380
    af->dev_info.output_count = 1;
1354
1381
    af->dev_info.ext_fmt_cnt = 0;
1355
1382
 
1356
1383
    /* Enumerate supported formats */
1357
 
    err = CVoIPUtilityFactory::CreateFactory(vas_factory_);
 
1384
    err = CVoIPUtilityFactory::CreateFactory (vas_factory_);
 
1385
 
1358
1386
    if (err != KErrNone)
1359
 
        goto on_error;
 
1387
        goto on_error;
1360
1388
 
1361
 
    /* On VAS 2.0, uplink & downlink stream should be instantiated before 
 
1389
    /* On VAS 2.0, uplink & downlink stream should be instantiated before
1362
1390
     * querying formats.
1363
1391
     */
1364
 
    err = vas_factory_->CreateUplinkStream(vas_version, 
1365
 
                                          CVoIPUtilityFactory::EVoIPCall,
1366
 
                                          vas_uplink);
1367
 
    if (err != KErrNone)
1368
 
        goto on_error;
1369
 
    
1370
 
    err = vas_factory_->CreateDownlinkStream(vas_version, 
1371
 
                                            CVoIPUtilityFactory::EVoIPCall,
1372
 
                                            vas_dnlink);
1373
 
    if (err != KErrNone)
1374
 
        goto on_error;
1375
 
    
 
1392
    err = vas_factory_->CreateUplinkStream (vas_version,
 
1393
                                            CVoIPUtilityFactory::EVoIPCall,
 
1394
                                            vas_uplink);
 
1395
 
 
1396
    if (err != KErrNone)
 
1397
        goto on_error;
 
1398
 
 
1399
    err = vas_factory_->CreateDownlinkStream (vas_version,
 
1400
            CVoIPUtilityFactory::EVoIPCall,
 
1401
            vas_dnlink);
 
1402
 
 
1403
    if (err != KErrNone)
 
1404
        goto on_error;
 
1405
 
1376
1406
    uplink_formats.Reset();
1377
 
    err = vas_factory_->GetSupportedUplinkFormats(uplink_formats);
 
1407
    err = vas_factory_->GetSupportedUplinkFormats (uplink_formats);
 
1408
 
1378
1409
    if (err != KErrNone)
1379
 
        goto on_error;
 
1410
        goto on_error;
1380
1411
 
1381
1412
    dnlink_formats.Reset();
1382
 
    err = vas_factory_->GetSupportedDownlinkFormats(dnlink_formats);
 
1413
    err = vas_factory_->GetSupportedDownlinkFormats (dnlink_formats);
 
1414
 
1383
1415
    if (err != KErrNone)
1384
 
        goto on_error;
 
1416
        goto on_error;
1385
1417
 
1386
1418
    /* Free the streams, they are just used for querying formats */
1387
1419
    delete vas_uplink;
1390
1422
    vas_dnlink = NULL;
1391
1423
    delete vas_factory_;
1392
1424
    vas_factory_ = NULL;
1393
 
    
 
1425
 
1394
1426
    for (TInt i = 0; i < dnlink_formats.Count(); i++) {
1395
 
        /* Format must be supported by both downlink & uplink. */
1396
 
        if (uplink_formats.Find(dnlink_formats[i]) == KErrNotFound)
1397
 
            continue;
1398
 
        
1399
 
        switch (dnlink_formats[i]) {
1400
 
        case EAMR_NB:
1401
 
            af->dev_info.ext_fmt[ext_fmt_cnt].id = PJMEDIA_FORMAT_AMR;
1402
 
            af->dev_info.ext_fmt[ext_fmt_cnt].bitrate = 7400;
1403
 
            af->dev_info.ext_fmt[ext_fmt_cnt].vad = PJ_TRUE;
1404
 
            break;
1405
 
 
1406
 
        case EG729:
1407
 
            af->dev_info.ext_fmt[ext_fmt_cnt].id = PJMEDIA_FORMAT_G729;
1408
 
            af->dev_info.ext_fmt[ext_fmt_cnt].bitrate = 8000;
1409
 
            af->dev_info.ext_fmt[ext_fmt_cnt].vad = PJ_FALSE;
1410
 
            break;
1411
 
 
1412
 
        case EILBC:
1413
 
            af->dev_info.ext_fmt[ext_fmt_cnt].id = PJMEDIA_FORMAT_ILBC;
1414
 
            af->dev_info.ext_fmt[ext_fmt_cnt].bitrate = 13333;
1415
 
            af->dev_info.ext_fmt[ext_fmt_cnt].vad = PJ_TRUE;
1416
 
            break;
1417
 
 
1418
 
        case EG711:
 
1427
        /* Format must be supported by both downlink & uplink. */
 
1428
        if (uplink_formats.Find (dnlink_formats[i]) == KErrNotFound)
 
1429
            continue;
 
1430
 
 
1431
        switch (dnlink_formats[i]) {
 
1432
            case EAMR_NB:
 
1433
                af->dev_info.ext_fmt[ext_fmt_cnt].id = PJMEDIA_FORMAT_AMR;
 
1434
                af->dev_info.ext_fmt[ext_fmt_cnt].bitrate = 7400;
 
1435
                af->dev_info.ext_fmt[ext_fmt_cnt].vad = PJ_TRUE;
 
1436
                break;
 
1437
 
 
1438
            case EG729:
 
1439
                af->dev_info.ext_fmt[ext_fmt_cnt].id = PJMEDIA_FORMAT_G729;
 
1440
                af->dev_info.ext_fmt[ext_fmt_cnt].bitrate = 8000;
 
1441
                af->dev_info.ext_fmt[ext_fmt_cnt].vad = PJ_FALSE;
 
1442
                break;
 
1443
 
 
1444
            case EILBC:
 
1445
                af->dev_info.ext_fmt[ext_fmt_cnt].id = PJMEDIA_FORMAT_ILBC;
 
1446
                af->dev_info.ext_fmt[ext_fmt_cnt].bitrate = 13333;
 
1447
                af->dev_info.ext_fmt[ext_fmt_cnt].vad = PJ_TRUE;
 
1448
                break;
 
1449
 
 
1450
            case EG711:
1419
1451
#if PJMEDIA_AUDIO_DEV_SYMB_VAS_VERSION==2
1420
 
        case EG711_10MS:
 
1452
            case EG711_10MS:
1421
1453
#endif
1422
 
            af->dev_info.ext_fmt[ext_fmt_cnt].id = PJMEDIA_FORMAT_PCMU;
1423
 
            af->dev_info.ext_fmt[ext_fmt_cnt].bitrate = 64000;
1424
 
            af->dev_info.ext_fmt[ext_fmt_cnt].vad = PJ_FALSE;
1425
 
            ++ext_fmt_cnt;
1426
 
            af->dev_info.ext_fmt[ext_fmt_cnt].id = PJMEDIA_FORMAT_PCMA;
1427
 
            af->dev_info.ext_fmt[ext_fmt_cnt].bitrate = 64000;
1428
 
            af->dev_info.ext_fmt[ext_fmt_cnt].vad = PJ_FALSE;
1429
 
            break;
1430
 
        
1431
 
        default:
1432
 
            continue;
1433
 
        }
1434
 
        
1435
 
        ++ext_fmt_cnt;
 
1454
                af->dev_info.ext_fmt[ext_fmt_cnt].id = PJMEDIA_FORMAT_PCMU;
 
1455
                af->dev_info.ext_fmt[ext_fmt_cnt].bitrate = 64000;
 
1456
                af->dev_info.ext_fmt[ext_fmt_cnt].vad = PJ_FALSE;
 
1457
                ++ext_fmt_cnt;
 
1458
                af->dev_info.ext_fmt[ext_fmt_cnt].id = PJMEDIA_FORMAT_PCMA;
 
1459
                af->dev_info.ext_fmt[ext_fmt_cnt].bitrate = 64000;
 
1460
                af->dev_info.ext_fmt[ext_fmt_cnt].vad = PJ_FALSE;
 
1461
                break;
 
1462
 
 
1463
            default:
 
1464
                continue;
 
1465
        }
 
1466
 
 
1467
        ++ext_fmt_cnt;
1436
1468
    }
1437
 
    
 
1469
 
1438
1470
    af->dev_info.ext_fmt_cnt = ext_fmt_cnt;
1439
1471
 
1440
1472
    uplink_formats.Close();
1441
1473
    dnlink_formats.Close();
1442
 
    
1443
 
    PJ_LOG(3, (THIS_FILE, "VAS initialized"));
 
1474
 
 
1475
    PJ_LOG (3, (THIS_FILE, "VAS initialized"));
1444
1476
 
1445
1477
    return PJ_SUCCESS;
1446
 
    
 
1478
 
1447
1479
on_error:
1448
 
    return PJ_RETURN_OS_ERROR(err);
 
1480
    return PJ_RETURN_OS_ERROR (err);
1449
1481
}
1450
1482
 
1451
1483
/* API: destroy factory */
1452
 
static pj_status_t factory_destroy(pjmedia_aud_dev_factory *f)
 
1484
static pj_status_t factory_destroy (pjmedia_aud_dev_factory *f)
1453
1485
{
1454
 
    struct vas_factory *af = (struct vas_factory*)f;
 
1486
    struct vas_factory *af = (struct vas_factory*) f;
1455
1487
    pj_pool_t *pool = af->pool;
1456
1488
 
1457
1489
    af->pool = NULL;
1458
 
    pj_pool_release(pool);
1459
 
 
1460
 
    PJ_LOG(3, (THIS_FILE, "VAS destroyed"));
1461
 
    
 
1490
    pj_pool_release (pool);
 
1491
 
 
1492
    PJ_LOG (3, (THIS_FILE, "VAS destroyed"));
 
1493
 
1462
1494
    return PJ_SUCCESS;
1463
1495
}
1464
1496
 
1465
1497
/* API: get number of devices */
1466
 
static unsigned factory_get_dev_count(pjmedia_aud_dev_factory *f)
 
1498
static unsigned factory_get_dev_count (pjmedia_aud_dev_factory *f)
1467
1499
{
1468
 
    PJ_UNUSED_ARG(f);
 
1500
    PJ_UNUSED_ARG (f);
1469
1501
    return 1;
1470
1502
}
1471
1503
 
1472
1504
/* API: get device info */
1473
 
static pj_status_t factory_get_dev_info(pjmedia_aud_dev_factory *f, 
1474
 
                                        unsigned index,
1475
 
                                        pjmedia_aud_dev_info *info)
 
1505
static pj_status_t factory_get_dev_info (pjmedia_aud_dev_factory *f,
 
1506
        unsigned index,
 
1507
        pjmedia_aud_dev_info *info)
1476
1508
{
1477
 
    struct vas_factory *af = (struct vas_factory*)f;
1478
 
 
1479
 
    PJ_ASSERT_RETURN(index == 0, PJMEDIA_EAUD_INVDEV);
1480
 
 
1481
 
    pj_memcpy(info, &af->dev_info, sizeof(*info));
 
1509
    struct vas_factory *af = (struct vas_factory*) f;
 
1510
 
 
1511
    PJ_ASSERT_RETURN (index == 0, PJMEDIA_EAUD_INVDEV);
 
1512
 
 
1513
    pj_memcpy (info, &af->dev_info, sizeof (*info));
1482
1514
 
1483
1515
    return PJ_SUCCESS;
1484
1516
}
1485
1517
 
1486
1518
/* API: create default device parameter */
1487
 
static pj_status_t factory_default_param(pjmedia_aud_dev_factory *f,
1488
 
                                         unsigned index,
1489
 
                                         pjmedia_aud_param *param)
 
1519
static pj_status_t factory_default_param (pjmedia_aud_dev_factory *f,
 
1520
        unsigned index,
 
1521
        pjmedia_aud_param *param)
1490
1522
{
1491
 
    struct vas_factory *af = (struct vas_factory*)f;
1492
 
 
1493
 
    PJ_ASSERT_RETURN(index == 0, PJMEDIA_EAUD_INVDEV);
1494
 
 
1495
 
    pj_bzero(param, sizeof(*param));
 
1523
    struct vas_factory *af = (struct vas_factory*) f;
 
1524
 
 
1525
    PJ_ASSERT_RETURN (index == 0, PJMEDIA_EAUD_INVDEV);
 
1526
 
 
1527
    pj_bzero (param, sizeof (*param));
1496
1528
    param->dir = PJMEDIA_DIR_CAPTURE_PLAYBACK;
1497
1529
    param->rec_id = index;
1498
1530
    param->play_id = index;
1508
1540
 
1509
1541
 
1510
1542
/* API: create stream */
1511
 
static pj_status_t factory_create_stream(pjmedia_aud_dev_factory *f,
1512
 
                                         const pjmedia_aud_param *param,
1513
 
                                         pjmedia_aud_rec_cb rec_cb,
1514
 
                                         pjmedia_aud_play_cb play_cb,
1515
 
                                         void *user_data,
1516
 
                                         pjmedia_aud_stream **p_aud_strm)
 
1543
static pj_status_t factory_create_stream (pjmedia_aud_dev_factory *f,
 
1544
        const pjmedia_aud_param *param,
 
1545
        pjmedia_aud_rec_cb rec_cb,
 
1546
        pjmedia_aud_play_cb play_cb,
 
1547
        void *user_data,
 
1548
        pjmedia_aud_stream **p_aud_strm)
1517
1549
{
1518
 
    struct vas_factory *af = (struct vas_factory*)f;
 
1550
    struct vas_factory *af = (struct vas_factory*) f;
1519
1551
    pj_pool_t *pool;
1520
1552
    struct vas_stream *strm;
1521
1553
 
1524
1556
    PjAudioCallback vas_play_cb;
1525
1557
 
1526
1558
    /* Can only support 16bits per sample */
1527
 
    PJ_ASSERT_RETURN(param->bits_per_sample == BITS_PER_SAMPLE, PJ_EINVAL);
 
1559
    PJ_ASSERT_RETURN (param->bits_per_sample == BITS_PER_SAMPLE, PJ_EINVAL);
1528
1560
 
1529
1561
    /* Supported clock rates:
1530
 
     * - for non-PCM format: 8kHz  
1531
 
     * - for PCM format: 8kHz and 16kHz  
 
1562
     * - for non-PCM format: 8kHz
 
1563
     * - for PCM format: 8kHz and 16kHz
1532
1564
     */
1533
 
    PJ_ASSERT_RETURN(param->clock_rate == 8000 ||
1534
 
                     (param->clock_rate == 16000 && 
1535
 
                      param->ext_fmt.id == PJMEDIA_FORMAT_L16),
1536
 
                     PJ_EINVAL);
 
1565
    PJ_ASSERT_RETURN (param->clock_rate == 8000 ||
 
1566
                      (param->clock_rate == 16000 &&
 
1567
                       param->ext_fmt.id == PJMEDIA_FORMAT_L16),
 
1568
                      PJ_EINVAL);
1537
1569
 
1538
1570
    /* Supported channels number:
1539
1571
     * - for non-PCM format: mono
1540
 
     * - for PCM format: mono and stereo  
 
1572
     * - for PCM format: mono and stereo
1541
1573
     */
1542
 
    PJ_ASSERT_RETURN(param->channel_count == 1 || 
1543
 
                     (param->channel_count == 2 &&
1544
 
                      param->ext_fmt.id == PJMEDIA_FORMAT_L16),
1545
 
                     PJ_EINVAL);
 
1574
    PJ_ASSERT_RETURN (param->channel_count == 1 ||
 
1575
                      (param->channel_count == 2 &&
 
1576
                       param->ext_fmt.id == PJMEDIA_FORMAT_L16),
 
1577
                      PJ_EINVAL);
1546
1578
 
1547
1579
    /* Create and Initialize stream descriptor */
1548
 
    pool = pj_pool_create(af->pf, "vas-dev", 1000, 1000, NULL);
1549
 
    PJ_ASSERT_RETURN(pool, PJ_ENOMEM);
 
1580
    pool = pj_pool_create (af->pf, "vas-dev", 1000, 1000, NULL);
 
1581
    PJ_ASSERT_RETURN (pool, PJ_ENOMEM);
1550
1582
 
1551
 
    strm = PJ_POOL_ZALLOC_T(pool, struct vas_stream);
 
1583
    strm = PJ_POOL_ZALLOC_T (pool, struct vas_stream);
1552
1584
    strm->pool = pool;
1553
1585
    strm->param = *param;
1554
1586
 
1555
1587
    if (strm->param.flags & PJMEDIA_AUD_DEV_CAP_EXT_FORMAT == 0)
1556
 
        strm->param.ext_fmt.id = PJMEDIA_FORMAT_L16;
1557
 
        
 
1588
        strm->param.ext_fmt.id = PJMEDIA_FORMAT_L16;
 
1589
 
1558
1590
    /* Set audio engine fourcc. */
1559
 
    switch(strm->param.ext_fmt.id) {
1560
 
    case PJMEDIA_FORMAT_L16:
1561
 
#ifdef USE_NATIVE_PCM   
1562
 
        vas_setting.format = EPCM16;
 
1591
    switch (strm->param.ext_fmt.id) {
 
1592
        case PJMEDIA_FORMAT_L16:
 
1593
#ifdef USE_NATIVE_PCM
 
1594
            vas_setting.format = EPCM16;
1563
1595
#else
1564
 
        vas_setting.format = EG711;
 
1596
            vas_setting.format = EG711;
1565
1597
#endif
1566
 
        break;
1567
 
    case PJMEDIA_FORMAT_PCMU:
1568
 
    case PJMEDIA_FORMAT_PCMA:
1569
 
        vas_setting.format = EG711;
1570
 
        break;
1571
 
    case PJMEDIA_FORMAT_AMR:
1572
 
        vas_setting.format = EAMR_NB;
1573
 
        break;
1574
 
    case PJMEDIA_FORMAT_G729:
1575
 
        vas_setting.format = EG729;
1576
 
        break;
1577
 
    case PJMEDIA_FORMAT_ILBC:
1578
 
        vas_setting.format = EILBC;
1579
 
        break;
1580
 
    default:
1581
 
        vas_setting.format = ENULL;
1582
 
        break;
 
1598
            break;
 
1599
        case PJMEDIA_FORMAT_PCMU:
 
1600
        case PJMEDIA_FORMAT_PCMA:
 
1601
            vas_setting.format = EG711;
 
1602
            break;
 
1603
        case PJMEDIA_FORMAT_AMR:
 
1604
            vas_setting.format = EAMR_NB;
 
1605
            break;
 
1606
        case PJMEDIA_FORMAT_G729:
 
1607
            vas_setting.format = EG729;
 
1608
            break;
 
1609
        case PJMEDIA_FORMAT_ILBC:
 
1610
            vas_setting.format = EILBC;
 
1611
            break;
 
1612
        default:
 
1613
            vas_setting.format = ENULL;
 
1614
            break;
1583
1615
    }
1584
1616
 
1585
1617
    /* Set audio engine mode. */
1586
 
    if (strm->param.ext_fmt.id == PJMEDIA_FORMAT_L16)
1587
 
    {
1588
 
#ifdef USE_NATIVE_PCM   
1589
 
        vas_setting.mode = 0;
 
1618
    if (strm->param.ext_fmt.id == PJMEDIA_FORMAT_L16) {
 
1619
#ifdef USE_NATIVE_PCM
 
1620
        vas_setting.mode = 0;
1590
1621
#else
1591
 
        vas_setting.mode = CVoIPFormatIntfc::EG711uLaw;
 
1622
        vas_setting.mode = CVoIPFormatIntfc::EG711uLaw;
1592
1623
#endif
1593
 
    } 
1594
 
    else if (strm->param.ext_fmt.id == PJMEDIA_FORMAT_AMR)
1595
 
    {
1596
 
        vas_setting.mode = strm->param.ext_fmt.bitrate;
1597
 
    } 
1598
 
    else if (strm->param.ext_fmt.id == PJMEDIA_FORMAT_PCMU)
1599
 
    {
1600
 
        vas_setting.mode = CVoIPFormatIntfc::EG711uLaw;
1601
 
    }
1602
 
    else if (strm->param.ext_fmt.id == PJMEDIA_FORMAT_PCMA)
1603
 
    {
1604
 
        vas_setting.mode = CVoIPFormatIntfc::EG711ALaw;
1605
 
    }
1606
 
    else if (strm->param.ext_fmt.id == PJMEDIA_FORMAT_ILBC)
1607
 
    {
1608
 
        if (strm->param.ext_fmt.bitrate == 15200)
1609
 
            vas_setting.mode = CVoIPFormatIntfc::EiLBC20mSecFrame;
1610
 
        else
1611
 
            vas_setting.mode = CVoIPFormatIntfc::EiLBC30mSecFrame;
 
1624
    } else if (strm->param.ext_fmt.id == PJMEDIA_FORMAT_AMR) {
 
1625
        vas_setting.mode = strm->param.ext_fmt.bitrate;
 
1626
    } else if (strm->param.ext_fmt.id == PJMEDIA_FORMAT_PCMU) {
 
1627
        vas_setting.mode = CVoIPFormatIntfc::EG711uLaw;
 
1628
    } else if (strm->param.ext_fmt.id == PJMEDIA_FORMAT_PCMA) {
 
1629
        vas_setting.mode = CVoIPFormatIntfc::EG711ALaw;
 
1630
    } else if (strm->param.ext_fmt.id == PJMEDIA_FORMAT_ILBC) {
 
1631
        if (strm->param.ext_fmt.bitrate == 15200)
 
1632
            vas_setting.mode = CVoIPFormatIntfc::EiLBC20mSecFrame;
 
1633
        else
 
1634
            vas_setting.mode = CVoIPFormatIntfc::EiLBC30mSecFrame;
1612
1635
    } else {
1613
 
        vas_setting.mode = 0;
 
1636
        vas_setting.mode = 0;
1614
1637
    }
1615
1638
 
1616
 
    /* Disable VAD on L16, G711, iLBC, and also G729 (G729's SID 
 
1639
    /* Disable VAD on L16, G711, iLBC, and also G729 (G729's SID
1617
1640
     * potentially cause noise?).
1618
1641
     */
1619
1642
    if (strm->param.ext_fmt.id == PJMEDIA_FORMAT_PCMU ||
1620
 
        strm->param.ext_fmt.id == PJMEDIA_FORMAT_PCMA ||
1621
 
        strm->param.ext_fmt.id == PJMEDIA_FORMAT_L16 ||
1622
 
        strm->param.ext_fmt.id == PJMEDIA_FORMAT_ILBC ||
1623
 
        strm->param.ext_fmt.id == PJMEDIA_FORMAT_G729)
1624
 
    {
1625
 
        vas_setting.vad = EFalse;
 
1643
            strm->param.ext_fmt.id == PJMEDIA_FORMAT_PCMA ||
 
1644
            strm->param.ext_fmt.id == PJMEDIA_FORMAT_L16 ||
 
1645
            strm->param.ext_fmt.id == PJMEDIA_FORMAT_ILBC ||
 
1646
            strm->param.ext_fmt.id == PJMEDIA_FORMAT_G729) {
 
1647
        vas_setting.vad = EFalse;
1626
1648
    } else {
1627
 
        vas_setting.vad = strm->param.ext_fmt.vad;
 
1649
        vas_setting.vad = strm->param.ext_fmt.vad;
1628
1650
    }
1629
 
    
 
1651
 
1630
1652
    /* Set other audio engine attributes. */
1631
1653
    vas_setting.plc = strm->param.plc_enabled;
1632
1654
    vas_setting.cng = vas_setting.vad;
1633
 
    vas_setting.loudspk = 
1634
 
                strm->param.output_route==PJMEDIA_AUD_DEV_ROUTE_LOUDSPEAKER;
 
1655
    vas_setting.loudspk =
 
1656
        strm->param.output_route==PJMEDIA_AUD_DEV_ROUTE_LOUDSPEAKER;
1635
1657
 
1636
1658
    /* Set audio engine callbacks. */
1637
1659
    if (strm->param.ext_fmt.id == PJMEDIA_FORMAT_L16) {
1638
1660
#ifdef USE_NATIVE_PCM
1639
 
        vas_play_cb = &PlayCbPcm2;
1640
 
        vas_rec_cb  = &RecCbPcm2;
 
1661
        vas_play_cb = &PlayCbPcm2;
 
1662
        vas_rec_cb  = &RecCbPcm2;
1641
1663
#else
1642
 
        vas_play_cb = &PlayCbPcm;
1643
 
        vas_rec_cb  = &RecCbPcm;
 
1664
        vas_play_cb = &PlayCbPcm;
 
1665
        vas_rec_cb  = &RecCbPcm;
1644
1666
#endif
1645
1667
    } else {
1646
 
        vas_play_cb = &PlayCb;
1647
 
        vas_rec_cb  = &RecCb;
 
1668
        vas_play_cb = &PlayCb;
 
1669
        vas_rec_cb  = &RecCb;
1648
1670
    }
1649
1671
 
1650
1672
    strm->rec_cb = rec_cb;
1653
1675
    strm->resample_factor = strm->param.clock_rate / 8000;
1654
1676
 
1655
1677
    /* play_buf size is samples per frame scaled in to 8kHz mono. */
1656
 
    strm->play_buf = (pj_int16_t*)pj_pool_zalloc(
1657
 
                                        pool, 
1658
 
                                        (strm->param.samples_per_frame / 
1659
 
                                        strm->resample_factor /
1660
 
                                        strm->param.channel_count) << 1);
 
1678
    strm->play_buf = (pj_int16_t*) pj_pool_zalloc (
 
1679
                         pool,
 
1680
                         (strm->param.samples_per_frame /
 
1681
                          strm->resample_factor /
 
1682
                          strm->param.channel_count) << 1);
1661
1683
    strm->play_buf_len = 0;
1662
1684
    strm->play_buf_start = 0;
1663
1685
 
1664
1686
    /* rec_buf size is samples per frame scaled in to 8kHz mono. */
1665
 
    strm->rec_buf  = (pj_int16_t*)pj_pool_zalloc(
1666
 
                                        pool, 
1667
 
                                        (strm->param.samples_per_frame / 
1668
 
                                        strm->resample_factor /
1669
 
                                        strm->param.channel_count) << 1);
 
1687
    strm->rec_buf  = (pj_int16_t*) pj_pool_zalloc (
 
1688
                         pool,
 
1689
                         (strm->param.samples_per_frame /
 
1690
                          strm->resample_factor /
 
1691
                          strm->param.channel_count) << 1);
1670
1692
    strm->rec_buf_len = 0;
1671
1693
 
1672
1694
    if (strm->param.ext_fmt.id == PJMEDIA_FORMAT_G729) {
1673
 
        TBitStream *g729_bitstream = new TBitStream;
1674
 
        
1675
 
        PJ_ASSERT_RETURN(g729_bitstream, PJ_ENOMEM);
1676
 
        strm->strm_data = (void*)g729_bitstream;
 
1695
        TBitStream *g729_bitstream = new TBitStream;
 
1696
 
 
1697
        PJ_ASSERT_RETURN (g729_bitstream, PJ_ENOMEM);
 
1698
        strm->strm_data = (void*) g729_bitstream;
1677
1699
    }
1678
 
        
 
1700
 
1679
1701
    /* Init resampler when format is PCM and clock rate is not 8kHz */
1680
 
    if (strm->param.clock_rate != 8000 && 
1681
 
        strm->param.ext_fmt.id == PJMEDIA_FORMAT_L16)
1682
 
    {
1683
 
        pj_status_t status;
1684
 
        
1685
 
        if (strm->param.dir & PJMEDIA_DIR_CAPTURE) {
1686
 
            /* Create resample for recorder */
1687
 
            status = pjmedia_resample_create( pool, PJ_TRUE, PJ_FALSE, 1, 
1688
 
                                              8000,
1689
 
                                              strm->param.clock_rate,
1690
 
                                              80,
1691
 
                                              &strm->rec_resample);
1692
 
            if (status != PJ_SUCCESS)
1693
 
                return status;
1694
 
        }
1695
 
    
1696
 
        if (strm->param.dir & PJMEDIA_DIR_PLAYBACK) {
1697
 
            /* Create resample for player */
1698
 
            status = pjmedia_resample_create( pool, PJ_TRUE, PJ_FALSE, 1, 
1699
 
                                              strm->param.clock_rate,
1700
 
                                              8000,
1701
 
                                              80 * strm->resample_factor,
1702
 
                                              &strm->play_resample);
1703
 
            if (status != PJ_SUCCESS)
1704
 
                return status;
1705
 
        }
 
1702
    if (strm->param.clock_rate != 8000 &&
 
1703
            strm->param.ext_fmt.id == PJMEDIA_FORMAT_L16) {
 
1704
        pj_status_t status;
 
1705
 
 
1706
        if (strm->param.dir & PJMEDIA_DIR_CAPTURE) {
 
1707
            /* Create resample for recorder */
 
1708
            status = pjmedia_resample_create (pool, PJ_TRUE, PJ_FALSE, 1,
 
1709
                                              8000,
 
1710
                                              strm->param.clock_rate,
 
1711
                                              80,
 
1712
                                              &strm->rec_resample);
 
1713
 
 
1714
            if (status != PJ_SUCCESS)
 
1715
                return status;
 
1716
        }
 
1717
 
 
1718
        if (strm->param.dir & PJMEDIA_DIR_PLAYBACK) {
 
1719
            /* Create resample for player */
 
1720
            status = pjmedia_resample_create (pool, PJ_TRUE, PJ_FALSE, 1,
 
1721
                                              strm->param.clock_rate,
 
1722
                                              8000,
 
1723
                                              80 * strm->resample_factor,
 
1724
                                              &strm->play_resample);
 
1725
 
 
1726
            if (status != PJ_SUCCESS)
 
1727
                return status;
 
1728
        }
1706
1729
    }
1707
1730
 
1708
1731
    /* Create PCM buffer, when the clock rate is not 8kHz or not mono */
1709
1732
    if (strm->param.ext_fmt.id == PJMEDIA_FORMAT_L16 &&
1710
 
        (strm->resample_factor > 1 || strm->param.channel_count != 1)) 
1711
 
    {
1712
 
        strm->pcm_buf = (pj_int16_t*)pj_pool_zalloc(pool, 
1713
 
                                        strm->param.samples_per_frame << 1);
 
1733
            (strm->resample_factor > 1 || strm->param.channel_count != 1)) {
 
1734
        strm->pcm_buf = (pj_int16_t*) pj_pool_zalloc (pool,
 
1735
                        strm->param.samples_per_frame << 1);
1714
1736
    }
1715
1737
 
1716
 
    
 
1738
 
1717
1739
    /* Create the audio engine. */
1718
 
    TRAPD(err, strm->engine = CPjAudioEngine::NewL(strm,
1719
 
                                                   vas_rec_cb, vas_play_cb,
1720
 
                                                   strm, vas_setting));
 
1740
    TRAPD (err, strm->engine = CPjAudioEngine::NewL (strm,
 
1741
                               vas_rec_cb, vas_play_cb,
 
1742
                               strm, vas_setting));
 
1743
 
1721
1744
    if (err != KErrNone) {
1722
 
        pj_pool_release(pool);
1723
 
        return PJ_RETURN_OS_ERROR(err);
 
1745
        pj_pool_release (pool);
 
1746
        return PJ_RETURN_OS_ERROR (err);
1724
1747
    }
1725
1748
 
1726
1749
    /* Apply output volume setting if specified */
1727
1750
    if (param->flags & PJMEDIA_AUD_DEV_CAP_OUTPUT_VOLUME_SETTING) {
1728
 
        stream_set_cap(&strm->base, PJMEDIA_AUD_DEV_CAP_OUTPUT_VOLUME_SETTING, 
1729
 
                       &param->output_vol);
 
1751
        stream_set_cap (&strm->base, PJMEDIA_AUD_DEV_CAP_OUTPUT_VOLUME_SETTING,
 
1752
                        &param->output_vol);
1730
1753
    }
1731
1754
 
1732
1755
    /* Done */
1737
1760
}
1738
1761
 
1739
1762
/* API: Get stream info. */
1740
 
static pj_status_t stream_get_param(pjmedia_aud_stream *s,
1741
 
                                    pjmedia_aud_param *pi)
 
1763
static pj_status_t stream_get_param (pjmedia_aud_stream *s,
 
1764
                                     pjmedia_aud_param *pi)
1742
1765
{
1743
 
    struct vas_stream *strm = (struct vas_stream*)s;
1744
 
 
1745
 
    PJ_ASSERT_RETURN(strm && pi, PJ_EINVAL);
1746
 
 
1747
 
    pj_memcpy(pi, &strm->param, sizeof(*pi));
 
1766
    struct vas_stream *strm = (struct vas_stream*) s;
 
1767
 
 
1768
    PJ_ASSERT_RETURN (strm && pi, PJ_EINVAL);
 
1769
 
 
1770
    pj_memcpy (pi, &strm->param, sizeof (*pi));
1748
1771
 
1749
1772
    /* Update the output volume setting */
1750
 
    if (stream_get_cap(s, PJMEDIA_AUD_DEV_CAP_OUTPUT_VOLUME_SETTING,
1751
 
                       &pi->output_vol) == PJ_SUCCESS)
1752
 
    {
1753
 
        pi->flags |= PJMEDIA_AUD_DEV_CAP_OUTPUT_VOLUME_SETTING;
 
1773
    if (stream_get_cap (s, PJMEDIA_AUD_DEV_CAP_OUTPUT_VOLUME_SETTING,
 
1774
                        &pi->output_vol) == PJ_SUCCESS) {
 
1775
        pi->flags |= PJMEDIA_AUD_DEV_CAP_OUTPUT_VOLUME_SETTING;
1754
1776
    }
1755
 
    
 
1777
 
1756
1778
    return PJ_SUCCESS;
1757
1779
}
1758
1780
 
1759
1781
/* API: get capability */
1760
 
static pj_status_t stream_get_cap(pjmedia_aud_stream *s,
1761
 
                                  pjmedia_aud_dev_cap cap,
1762
 
                                  void *pval)
 
1782
static pj_status_t stream_get_cap (pjmedia_aud_stream *s,
 
1783
                                   pjmedia_aud_dev_cap cap,
 
1784
                                   void *pval)
1763
1785
{
1764
 
    struct vas_stream *strm = (struct vas_stream*)s;
 
1786
    struct vas_stream *strm = (struct vas_stream*) s;
1765
1787
    pj_status_t status = PJ_ENOTSUP;
1766
1788
 
1767
 
    PJ_ASSERT_RETURN(s && pval, PJ_EINVAL);
 
1789
    PJ_ASSERT_RETURN (s && pval, PJ_EINVAL);
1768
1790
 
1769
1791
    switch (cap) {
1770
 
    case PJMEDIA_AUD_DEV_CAP_OUTPUT_ROUTE: 
1771
 
        if (strm->param.dir & PJMEDIA_DIR_PLAYBACK) {
1772
 
            *(pjmedia_aud_dev_route*)pval = strm->param.output_route;
1773
 
            status = PJ_SUCCESS;
1774
 
        }
1775
 
        break;
1776
 
    
1777
 
    /* There is a case that GetMaxGain() stucks, e.g: in N95. */ 
1778
 
    /*
1779
 
    case PJMEDIA_AUD_DEV_CAP_INPUT_VOLUME_SETTING:
1780
 
        if (strm->param.dir & PJMEDIA_DIR_CAPTURE) {
1781
 
            PJ_ASSERT_RETURN(strm->engine, PJ_EINVAL);
1782
 
            
1783
 
            TInt max_gain = strm->engine->GetMaxGain();
1784
 
            TInt gain = strm->engine->GetGain();
1785
 
            
1786
 
            if (max_gain > 0 && gain >= 0) {
1787
 
                *(unsigned*)pval = gain * 100 / max_gain; 
1788
 
                status = PJ_SUCCESS;
1789
 
            } else {
1790
 
                status = PJMEDIA_EAUD_NOTREADY;
1791
 
            }
1792
 
        }
1793
 
        break;
1794
 
    */
1795
 
 
1796
 
    case PJMEDIA_AUD_DEV_CAP_OUTPUT_VOLUME_SETTING:
1797
 
        if (strm->param.dir & PJMEDIA_DIR_PLAYBACK) {
1798
 
            PJ_ASSERT_RETURN(strm->engine, PJ_EINVAL);
1799
 
            
1800
 
            TInt max_vol = strm->engine->GetMaxVolume();
1801
 
            TInt vol = strm->engine->GetVolume();
1802
 
            
1803
 
            if (max_vol > 0 && vol >= 0) {
1804
 
                *(unsigned*)pval = vol * 100 / max_vol; 
1805
 
                status = PJ_SUCCESS;
1806
 
            } else {
1807
 
                status = PJMEDIA_EAUD_NOTREADY;
1808
 
            }
1809
 
        }
1810
 
        break;
1811
 
    default:
1812
 
        break;
 
1792
        case PJMEDIA_AUD_DEV_CAP_OUTPUT_ROUTE:
 
1793
 
 
1794
            if (strm->param.dir & PJMEDIA_DIR_PLAYBACK) {
 
1795
                * (pjmedia_aud_dev_route*) pval = strm->param.output_route;
 
1796
                status = PJ_SUCCESS;
 
1797
            }
 
1798
 
 
1799
            break;
 
1800
 
 
1801
            /* There is a case that GetMaxGain() stucks, e.g: in N95. */
 
1802
            /*
 
1803
            case PJMEDIA_AUD_DEV_CAP_INPUT_VOLUME_SETTING:
 
1804
            if (strm->param.dir & PJMEDIA_DIR_CAPTURE) {
 
1805
                PJ_ASSERT_RETURN(strm->engine, PJ_EINVAL);
 
1806
 
 
1807
                TInt max_gain = strm->engine->GetMaxGain();
 
1808
                TInt gain = strm->engine->GetGain();
 
1809
 
 
1810
                if (max_gain > 0 && gain >= 0) {
 
1811
                *(unsigned*)pval = gain * 100 / max_gain;
 
1812
                status = PJ_SUCCESS;
 
1813
                } else {
 
1814
                status = PJMEDIA_EAUD_NOTREADY;
 
1815
                }
 
1816
            }
 
1817
            break;
 
1818
            */
 
1819
 
 
1820
        case PJMEDIA_AUD_DEV_CAP_OUTPUT_VOLUME_SETTING:
 
1821
 
 
1822
            if (strm->param.dir & PJMEDIA_DIR_PLAYBACK) {
 
1823
                PJ_ASSERT_RETURN (strm->engine, PJ_EINVAL);
 
1824
 
 
1825
                TInt max_vol = strm->engine->GetMaxVolume();
 
1826
                TInt vol = strm->engine->GetVolume();
 
1827
 
 
1828
                if (max_vol > 0 && vol >= 0) {
 
1829
                    * (unsigned*) pval = vol * 100 / max_vol;
 
1830
                    status = PJ_SUCCESS;
 
1831
                } else {
 
1832
                    status = PJMEDIA_EAUD_NOTREADY;
 
1833
                }
 
1834
            }
 
1835
 
 
1836
            break;
 
1837
        default:
 
1838
            break;
1813
1839
    }
1814
 
    
 
1840
 
1815
1841
    return status;
1816
1842
}
1817
1843
 
1818
1844
/* API: set capability */
1819
 
static pj_status_t stream_set_cap(pjmedia_aud_stream *s,
1820
 
                                  pjmedia_aud_dev_cap cap,
1821
 
                                  const void *pval)
 
1845
static pj_status_t stream_set_cap (pjmedia_aud_stream *s,
 
1846
                                   pjmedia_aud_dev_cap cap,
 
1847
                                   const void *pval)
1822
1848
{
1823
 
    struct vas_stream *strm = (struct vas_stream*)s;
 
1849
    struct vas_stream *strm = (struct vas_stream*) s;
1824
1850
    pj_status_t status = PJ_ENOTSUP;
1825
1851
 
1826
 
    PJ_ASSERT_RETURN(s && pval, PJ_EINVAL);
 
1852
    PJ_ASSERT_RETURN (s && pval, PJ_EINVAL);
1827
1853
 
1828
1854
    switch (cap) {
1829
 
    case PJMEDIA_AUD_DEV_CAP_OUTPUT_ROUTE: 
1830
 
        if (strm->param.dir & PJMEDIA_DIR_PLAYBACK) {
1831
 
            pjmedia_aud_dev_route r = *(const pjmedia_aud_dev_route*)pval;
1832
 
            TInt err;
1833
 
 
1834
 
            PJ_ASSERT_RETURN(strm->engine, PJ_EINVAL);
1835
 
            
1836
 
            switch (r) {
1837
 
            case PJMEDIA_AUD_DEV_ROUTE_DEFAULT:
1838
 
            case PJMEDIA_AUD_DEV_ROUTE_EARPIECE:
1839
 
                err = strm->engine->ActivateSpeaker(EFalse);
1840
 
                status = (err==KErrNone)? PJ_SUCCESS:PJ_RETURN_OS_ERROR(err);
1841
 
                break;
1842
 
            case PJMEDIA_AUD_DEV_ROUTE_LOUDSPEAKER:
1843
 
                err = strm->engine->ActivateSpeaker(ETrue);
1844
 
                status = (err==KErrNone)? PJ_SUCCESS:PJ_RETURN_OS_ERROR(err);
1845
 
                break;
1846
 
            default:
1847
 
                status = PJ_EINVAL;
1848
 
                break;
1849
 
            }
1850
 
            if (status == PJ_SUCCESS)
1851
 
                strm->param.output_route = r; 
1852
 
        }
1853
 
        break;
1854
 
 
1855
 
    /* There is a case that GetMaxGain() stucks, e.g: in N95. */ 
1856
 
    /*
1857
 
    case PJMEDIA_AUD_DEV_CAP_INPUT_VOLUME_SETTING:
1858
 
        if (strm->param.dir & PJMEDIA_DIR_CAPTURE) {
1859
 
            PJ_ASSERT_RETURN(strm->engine, PJ_EINVAL);
1860
 
            
1861
 
            TInt max_gain = strm->engine->GetMaxGain();
1862
 
            if (max_gain > 0) {
1863
 
                TInt gain, err;
1864
 
                
1865
 
                gain = *(unsigned*)pval * max_gain / 100;
1866
 
                err = strm->engine->SetGain(gain);
1867
 
                status = (err==KErrNone)? PJ_SUCCESS:PJ_RETURN_OS_ERROR(err);
1868
 
            } else {
1869
 
                status = PJMEDIA_EAUD_NOTREADY;
1870
 
            }
1871
 
            if (status == PJ_SUCCESS)
1872
 
                strm->param.input_vol = *(unsigned*)pval;
1873
 
        }
1874
 
        break;
1875
 
    */
1876
 
 
1877
 
    case PJMEDIA_AUD_DEV_CAP_OUTPUT_VOLUME_SETTING:
1878
 
        if (strm->param.dir & PJMEDIA_DIR_PLAYBACK) {
1879
 
            PJ_ASSERT_RETURN(strm->engine, PJ_EINVAL);
1880
 
            
1881
 
            TInt max_vol = strm->engine->GetMaxVolume();
1882
 
            if (max_vol > 0) {
1883
 
                TInt vol, err;
1884
 
                
1885
 
                vol = *(unsigned*)pval * max_vol / 100;
1886
 
                err = strm->engine->SetVolume(vol);
1887
 
                status = (err==KErrNone)? PJ_SUCCESS:PJ_RETURN_OS_ERROR(err);
1888
 
            } else {
1889
 
                status = PJMEDIA_EAUD_NOTREADY;
1890
 
            }
1891
 
            if (status == PJ_SUCCESS)
1892
 
                strm->param.output_vol = *(unsigned*)pval;
1893
 
        }
1894
 
        break;
1895
 
    default:
1896
 
        break;
 
1855
        case PJMEDIA_AUD_DEV_CAP_OUTPUT_ROUTE:
 
1856
 
 
1857
            if (strm->param.dir & PJMEDIA_DIR_PLAYBACK) {
 
1858
                pjmedia_aud_dev_route r = * (const pjmedia_aud_dev_route*) pval;
 
1859
                TInt err;
 
1860
 
 
1861
                PJ_ASSERT_RETURN (strm->engine, PJ_EINVAL);
 
1862
 
 
1863
                switch (r) {
 
1864
                    case PJMEDIA_AUD_DEV_ROUTE_DEFAULT:
 
1865
                    case PJMEDIA_AUD_DEV_ROUTE_EARPIECE:
 
1866
                        err = strm->engine->ActivateSpeaker (EFalse);
 
1867
                        status = (err==KErrNone) ? PJ_SUCCESS:PJ_RETURN_OS_ERROR (err);
 
1868
                        break;
 
1869
                    case PJMEDIA_AUD_DEV_ROUTE_LOUDSPEAKER:
 
1870
                        err = strm->engine->ActivateSpeaker (ETrue);
 
1871
                        status = (err==KErrNone) ? PJ_SUCCESS:PJ_RETURN_OS_ERROR (err);
 
1872
                        break;
 
1873
                    default:
 
1874
                        status = PJ_EINVAL;
 
1875
                        break;
 
1876
                }
 
1877
 
 
1878
                if (status == PJ_SUCCESS)
 
1879
                    strm->param.output_route = r;
 
1880
            }
 
1881
 
 
1882
            break;
 
1883
 
 
1884
            /* There is a case that GetMaxGain() stucks, e.g: in N95. */
 
1885
            /*
 
1886
            case PJMEDIA_AUD_DEV_CAP_INPUT_VOLUME_SETTING:
 
1887
            if (strm->param.dir & PJMEDIA_DIR_CAPTURE) {
 
1888
                PJ_ASSERT_RETURN(strm->engine, PJ_EINVAL);
 
1889
 
 
1890
                TInt max_gain = strm->engine->GetMaxGain();
 
1891
                if (max_gain > 0) {
 
1892
                TInt gain, err;
 
1893
 
 
1894
                gain = *(unsigned*)pval * max_gain / 100;
 
1895
                err = strm->engine->SetGain(gain);
 
1896
                status = (err==KErrNone)? PJ_SUCCESS:PJ_RETURN_OS_ERROR(err);
 
1897
                } else {
 
1898
                status = PJMEDIA_EAUD_NOTREADY;
 
1899
                }
 
1900
                if (status == PJ_SUCCESS)
 
1901
                strm->param.input_vol = *(unsigned*)pval;
 
1902
            }
 
1903
            break;
 
1904
            */
 
1905
 
 
1906
        case PJMEDIA_AUD_DEV_CAP_OUTPUT_VOLUME_SETTING:
 
1907
 
 
1908
            if (strm->param.dir & PJMEDIA_DIR_PLAYBACK) {
 
1909
                PJ_ASSERT_RETURN (strm->engine, PJ_EINVAL);
 
1910
 
 
1911
                TInt max_vol = strm->engine->GetMaxVolume();
 
1912
 
 
1913
                if (max_vol > 0) {
 
1914
                    TInt vol, err;
 
1915
 
 
1916
                    vol = * (unsigned*) pval * max_vol / 100;
 
1917
                    err = strm->engine->SetVolume (vol);
 
1918
                    status = (err==KErrNone) ? PJ_SUCCESS:PJ_RETURN_OS_ERROR (err);
 
1919
                } else {
 
1920
                    status = PJMEDIA_EAUD_NOTREADY;
 
1921
                }
 
1922
 
 
1923
                if (status == PJ_SUCCESS)
 
1924
                    strm->param.output_vol = * (unsigned*) pval;
 
1925
            }
 
1926
 
 
1927
            break;
 
1928
        default:
 
1929
            break;
1897
1930
    }
1898
 
    
 
1931
 
1899
1932
    return status;
1900
1933
}
1901
1934
 
1902
1935
/* API: Start stream. */
1903
 
static pj_status_t stream_start(pjmedia_aud_stream *strm)
 
1936
static pj_status_t stream_start (pjmedia_aud_stream *strm)
1904
1937
{
1905
 
    struct vas_stream *stream = (struct vas_stream*)strm;
 
1938
    struct vas_stream *stream = (struct vas_stream*) strm;
1906
1939
 
1907
 
    PJ_ASSERT_RETURN(stream, PJ_EINVAL);
 
1940
    PJ_ASSERT_RETURN (stream, PJ_EINVAL);
1908
1941
 
1909
1942
    if (stream->engine) {
1910
 
        enum { VAS_WAIT_START = 2000 }; /* in msecs */
1911
 
        TTime start, now;
1912
 
        TInt err = stream->engine->Start();
1913
 
        
1914
 
        if (err != KErrNone)
1915
 
            return PJ_RETURN_OS_ERROR(err);
1916
 
 
1917
 
        /* Perform synchronous start, timeout after VAS_WAIT_START ms */
1918
 
        start.UniversalTime();
1919
 
        do {
1920
 
            pj_symbianos_poll(-1, 100);
1921
 
            now.UniversalTime();
1922
 
        } while (!stream->engine->IsStarted() &&
1923
 
                 (now.MicroSecondsFrom(start) < VAS_WAIT_START * 1000));
1924
 
        
1925
 
        if (stream->engine->IsStarted())
1926
 
            return PJ_SUCCESS;
1927
 
        else
1928
 
            return PJ_ETIMEDOUT;
1929
 
    }    
 
1943
        enum { VAS_WAIT_START = 2000 }; /* in msecs */
 
1944
        TTime start, now;
 
1945
        TInt err = stream->engine->Start();
 
1946
 
 
1947
        if (err != KErrNone)
 
1948
            return PJ_RETURN_OS_ERROR (err);
 
1949
 
 
1950
        /* Perform synchronous start, timeout after VAS_WAIT_START ms */
 
1951
        start.UniversalTime();
 
1952
 
 
1953
        do {
 
1954
            pj_symbianos_poll (-1, 100);
 
1955
            now.UniversalTime();
 
1956
        } while (!stream->engine->IsStarted() &&
 
1957
                 (now.MicroSecondsFrom (start) < VAS_WAIT_START * 1000));
 
1958
 
 
1959
        if (stream->engine->IsStarted())
 
1960
            return PJ_SUCCESS;
 
1961
        else
 
1962
            return PJ_ETIMEDOUT;
 
1963
    }
1930
1964
 
1931
1965
    return PJ_EINVALIDOP;
1932
1966
}
1933
1967
 
1934
1968
/* API: Stop stream. */
1935
 
static pj_status_t stream_stop(pjmedia_aud_stream *strm)
 
1969
static pj_status_t stream_stop (pjmedia_aud_stream *strm)
1936
1970
{
1937
 
    struct vas_stream *stream = (struct vas_stream*)strm;
 
1971
    struct vas_stream *stream = (struct vas_stream*) strm;
1938
1972
 
1939
 
    PJ_ASSERT_RETURN(stream, PJ_EINVAL);
 
1973
    PJ_ASSERT_RETURN (stream, PJ_EINVAL);
1940
1974
 
1941
1975
    if (stream->engine) {
1942
 
        stream->engine->Stop();
 
1976
        stream->engine->Stop();
1943
1977
    }
1944
1978
 
1945
1979
    return PJ_SUCCESS;
1947
1981
 
1948
1982
 
1949
1983
/* API: Destroy stream. */
1950
 
static pj_status_t stream_destroy(pjmedia_aud_stream *strm)
 
1984
static pj_status_t stream_destroy (pjmedia_aud_stream *strm)
1951
1985
{
1952
 
    struct vas_stream *stream = (struct vas_stream*)strm;
1953
 
 
1954
 
    PJ_ASSERT_RETURN(stream, PJ_EINVAL);
1955
 
 
1956
 
    stream_stop(strm);
 
1986
    struct vas_stream *stream = (struct vas_stream*) strm;
 
1987
 
 
1988
    PJ_ASSERT_RETURN (stream, PJ_EINVAL);
 
1989
 
 
1990
    stream_stop (strm);
1957
1991
 
1958
1992
    delete stream->engine;
1959
1993
    stream->engine = NULL;
1960
1994
 
1961
1995
    if (stream->param.ext_fmt.id == PJMEDIA_FORMAT_G729) {
1962
 
        TBitStream *g729_bitstream = (TBitStream*)stream->strm_data;
1963
 
        stream->strm_data = NULL;
1964
 
        delete g729_bitstream;
 
1996
        TBitStream *g729_bitstream = (TBitStream*) stream->strm_data;
 
1997
        stream->strm_data = NULL;
 
1998
        delete g729_bitstream;
1965
1999
    }
1966
2000
 
1967
2001
    pj_pool_t *pool;
1968
2002
    pool = stream->pool;
 
2003
 
1969
2004
    if (pool) {
1970
 
        stream->pool = NULL;
1971
 
        pj_pool_release(pool);
 
2005
        stream->pool = NULL;
 
2006
        pj_pool_release (pool);
1972
2007
    }
1973
2008
 
1974
2009
    return PJ_SUCCESS;