~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_mda_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_mda_dev.cpp 2777 2009-06-19 09:15:59Z bennylp $ */
2
 
/* 
 
2
/*
3
3
 * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
4
4
 * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
5
5
 *
15
15
 *
16
16
 * You should have received a copy of the GNU General Public License
17
17
 * along with this program; if not, write to the Free Software
18
 
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
 
18
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19
19
 *
20
20
 *  Additional permission under GNU GPL version 3 section 7:
21
21
 *
43
43
 * This file provides sound implementation for Symbian Audio Streaming
44
44
 * device. Application using this sound abstraction must link with:
45
45
 *  - mediaclientaudiostream.lib, and
46
 
 *  - mediaclientaudioinputstream.lib 
 
46
 *  - mediaclientaudioinputstream.lib
47
47
 */
48
48
#include <mda/common/audio.h>
49
49
#include <mdaaudiooutputstream.h>
63
63
 
64
64
 
65
65
/* MDA factory */
66
 
struct mda_factory
67
 
{
 
66
struct mda_factory {
68
67
    pjmedia_aud_dev_factory      base;
69
68
    pj_pool_t                   *pool;
70
69
    pj_pool_factory             *pf;
76
75
class CPjAudioOutputEngine;
77
76
 
78
77
/* MDA stream. */
79
 
struct mda_stream
80
 
{
 
78
struct mda_stream {
81
79
    // Base
82
80
    pjmedia_aud_stream   base;                  /**< Base class.        */
83
 
    
 
81
 
84
82
    // Pool
85
83
    pj_pool_t           *pool;                  /**< Memory pool.       */
86
84
 
94
92
 
95
93
 
96
94
/* Prototypes */
97
 
static pj_status_t factory_init(pjmedia_aud_dev_factory *f);
98
 
static pj_status_t factory_destroy(pjmedia_aud_dev_factory *f);
99
 
static unsigned    factory_get_dev_count(pjmedia_aud_dev_factory *f);
100
 
static pj_status_t factory_get_dev_info(pjmedia_aud_dev_factory *f, 
101
 
                                        unsigned index,
102
 
                                        pjmedia_aud_dev_info *info);
103
 
static pj_status_t factory_default_param(pjmedia_aud_dev_factory *f,
104
 
                                         unsigned index,
105
 
                                         pjmedia_aud_param *param);
106
 
static pj_status_t factory_create_stream(pjmedia_aud_dev_factory *f,
107
 
                                         const pjmedia_aud_param *param,
108
 
                                         pjmedia_aud_rec_cb rec_cb,
109
 
                                         pjmedia_aud_play_cb play_cb,
110
 
                                         void *user_data,
111
 
                                         pjmedia_aud_stream **p_aud_strm);
 
95
static pj_status_t factory_init (pjmedia_aud_dev_factory *f);
 
96
static pj_status_t factory_destroy (pjmedia_aud_dev_factory *f);
 
97
static unsigned    factory_get_dev_count (pjmedia_aud_dev_factory *f);
 
98
static pj_status_t factory_get_dev_info (pjmedia_aud_dev_factory *f,
 
99
        unsigned index,
 
100
        pjmedia_aud_dev_info *info);
 
101
static pj_status_t factory_default_param (pjmedia_aud_dev_factory *f,
 
102
        unsigned index,
 
103
        pjmedia_aud_param *param);
 
104
static pj_status_t factory_create_stream (pjmedia_aud_dev_factory *f,
 
105
        const pjmedia_aud_param *param,
 
106
        pjmedia_aud_rec_cb rec_cb,
 
107
        pjmedia_aud_play_cb play_cb,
 
108
        void *user_data,
 
109
        pjmedia_aud_stream **p_aud_strm);
112
110
 
113
 
static pj_status_t stream_get_param(pjmedia_aud_stream *strm,
114
 
                                    pjmedia_aud_param *param);
115
 
static pj_status_t stream_get_cap(pjmedia_aud_stream *strm,
116
 
                                  pjmedia_aud_dev_cap cap,
117
 
                                  void *value);
118
 
static pj_status_t stream_set_cap(pjmedia_aud_stream *strm,
119
 
                                  pjmedia_aud_dev_cap cap,
120
 
                                  const void *value);
121
 
static pj_status_t stream_start(pjmedia_aud_stream *strm);
122
 
static pj_status_t stream_stop(pjmedia_aud_stream *strm);
123
 
static pj_status_t stream_destroy(pjmedia_aud_stream *strm);
 
111
static pj_status_t stream_get_param (pjmedia_aud_stream *strm,
 
112
                                     pjmedia_aud_param *param);
 
113
static pj_status_t stream_get_cap (pjmedia_aud_stream *strm,
 
114
                                   pjmedia_aud_dev_cap cap,
 
115
                                   void *value);
 
116
static pj_status_t stream_set_cap (pjmedia_aud_stream *strm,
 
117
                                   pjmedia_aud_dev_cap cap,
 
118
                                   const void *value);
 
119
static pj_status_t stream_start (pjmedia_aud_stream *strm);
 
120
static pj_status_t stream_stop (pjmedia_aud_stream *strm);
 
121
static pj_status_t stream_destroy (pjmedia_aud_stream *strm);
124
122
 
125
123
 
126
124
/* Operations */
127
 
static pjmedia_aud_dev_factory_op factory_op =
128
 
{
 
125
static pjmedia_aud_dev_factory_op factory_op = {
129
126
    &factory_init,
130
127
    &factory_destroy,
131
128
    &factory_get_dev_count,
134
131
    &factory_create_stream
135
132
};
136
133
 
137
 
static pjmedia_aud_stream_op stream_op = 
138
 
{
 
134
static pjmedia_aud_stream_op stream_op = {
139
135
    &stream_get_param,
140
136
    &stream_get_cap,
141
137
    &stream_set_cap,
148
144
/*
149
145
 * Convert clock rate to Symbian's TMdaAudioDataSettings capability.
150
146
 */
151
 
static TInt get_clock_rate_cap(unsigned clock_rate)
 
147
static TInt get_clock_rate_cap (unsigned clock_rate)
152
148
{
153
149
    switch (clock_rate) {
154
 
    case 8000:  return TMdaAudioDataSettings::ESampleRate8000Hz;
155
 
    case 11025: return TMdaAudioDataSettings::ESampleRate11025Hz;
156
 
    case 12000: return TMdaAudioDataSettings::ESampleRate12000Hz;
157
 
    case 16000: return TMdaAudioDataSettings::ESampleRate16000Hz;
158
 
    case 22050: return TMdaAudioDataSettings::ESampleRate22050Hz;
159
 
    case 24000: return TMdaAudioDataSettings::ESampleRate24000Hz;
160
 
    case 32000: return TMdaAudioDataSettings::ESampleRate32000Hz;
161
 
    case 44100: return TMdaAudioDataSettings::ESampleRate44100Hz;
162
 
    case 48000: return TMdaAudioDataSettings::ESampleRate48000Hz;
163
 
    case 64000: return TMdaAudioDataSettings::ESampleRate64000Hz;
164
 
    case 96000: return TMdaAudioDataSettings::ESampleRate96000Hz;
165
 
    default:
166
 
        return 0;
 
150
        case 8000:
 
151
            return TMdaAudioDataSettings::ESampleRate8000Hz;
 
152
        case 11025:
 
153
            return TMdaAudioDataSettings::ESampleRate11025Hz;
 
154
        case 12000:
 
155
            return TMdaAudioDataSettings::ESampleRate12000Hz;
 
156
        case 16000:
 
157
            return TMdaAudioDataSettings::ESampleRate16000Hz;
 
158
        case 22050:
 
159
            return TMdaAudioDataSettings::ESampleRate22050Hz;
 
160
        case 24000:
 
161
            return TMdaAudioDataSettings::ESampleRate24000Hz;
 
162
        case 32000:
 
163
            return TMdaAudioDataSettings::ESampleRate32000Hz;
 
164
        case 44100:
 
165
            return TMdaAudioDataSettings::ESampleRate44100Hz;
 
166
        case 48000:
 
167
            return TMdaAudioDataSettings::ESampleRate48000Hz;
 
168
        case 64000:
 
169
            return TMdaAudioDataSettings::ESampleRate64000Hz;
 
170
        case 96000:
 
171
            return TMdaAudioDataSettings::ESampleRate96000Hz;
 
172
        default:
 
173
            return 0;
167
174
    }
168
175
}
169
176
 
170
177
/*
171
178
 * Convert number of channels into Symbian's TMdaAudioDataSettings capability.
172
179
 */
173
 
static TInt get_channel_cap(unsigned channel_count)
 
180
static TInt get_channel_cap (unsigned channel_count)
174
181
{
175
182
    switch (channel_count) {
176
 
    case 1: return TMdaAudioDataSettings::EChannelsMono;
177
 
    case 2: return TMdaAudioDataSettings::EChannelsStereo;
178
 
    default:
179
 
        return 0;
 
183
        case 1:
 
184
            return TMdaAudioDataSettings::EChannelsMono;
 
185
        case 2:
 
186
            return TMdaAudioDataSettings::EChannelsStereo;
 
187
        default:
 
188
            return 0;
180
189
    }
181
190
}
182
191
 
183
192
/*
184
193
 * Utility: print sound device error
185
194
 */
186
 
static void snd_perror(const char *title, TInt rc) 
 
195
static void snd_perror (const char *title, TInt rc)
187
196
{
188
 
    PJ_LOG(1,(THIS_FILE, "%s: error code %d", title, rc));
 
197
    PJ_LOG (1, (THIS_FILE, "%s: error code %d", title, rc));
189
198
}
190
 
 
 
199
 
191
200
//////////////////////////////////////////////////////////////////////////////
192
201
//
193
202
 
196
205
 */
197
206
class CPjAudioInputEngine : public CBase, MMdaAudioInputStreamCallback
198
207
{
199
 
public:
200
 
    enum State
201
 
    {
202
 
        STATE_INACTIVE,
203
 
        STATE_ACTIVE,
204
 
    };
205
 
 
206
 
    ~CPjAudioInputEngine();
207
 
 
208
 
    static CPjAudioInputEngine *NewL(struct mda_stream *parent_strm,
209
 
                                     pjmedia_aud_rec_cb rec_cb,
210
 
                                     void *user_data);
211
 
 
212
 
    static CPjAudioInputEngine *NewLC(struct mda_stream *parent_strm,
213
 
                                      pjmedia_aud_rec_cb rec_cb,
214
 
                                      void *user_data);
215
 
 
216
 
    pj_status_t StartRecord();
217
 
    void Stop();
218
 
 
219
 
    pj_status_t SetGain(TInt gain) { 
220
 
        if (iInputStream_) { 
221
 
            iInputStream_->SetGain(gain);
222
 
            return PJ_SUCCESS;
223
 
        } else
224
 
            return PJ_EINVALIDOP;
225
 
    }
226
 
    
227
 
    TInt GetGain() { 
228
 
        if (iInputStream_) { 
229
 
            return iInputStream_->Gain();
230
 
        } else
231
 
            return PJ_EINVALIDOP;
232
 
    }
233
 
 
234
 
    TInt GetMaxGain() { 
235
 
        if (iInputStream_) { 
236
 
            return iInputStream_->MaxGain();
237
 
        } else
238
 
            return PJ_EINVALIDOP;
239
 
    }
240
 
    
241
 
private:
242
 
    State                    state_;
243
 
    struct mda_stream       *parentStrm_;
244
 
    pjmedia_aud_rec_cb       recCb_;
245
 
    void                    *userData_;
246
 
    CMdaAudioInputStream    *iInputStream_;
247
 
    HBufC8                  *iStreamBuffer_;
248
 
    TPtr8                    iFramePtr_;
249
 
    TInt                     lastError_;
250
 
    pj_uint32_t              timeStamp_;
251
 
 
252
 
    // cache variable
253
 
    // to avoid calculating frame length repeatedly
254
 
    TInt                     frameLen_;
255
 
    
256
 
    // sometimes recorded size != requested framesize, so let's
257
 
    // provide a buffer to make sure the rec callback returning
258
 
    // framesize as requested.
259
 
    TUint8                  *frameRecBuf_;
260
 
    TInt                     frameRecBufLen_;
261
 
 
262
 
    CPjAudioInputEngine(struct mda_stream *parent_strm,
263
 
            pjmedia_aud_rec_cb rec_cb,
264
 
                        void *user_data);
265
 
    void ConstructL();
266
 
    TPtr8 & GetFrame();
267
 
    
268
 
public:
269
 
    virtual void MaiscOpenComplete(TInt aError);
270
 
    virtual void MaiscBufferCopied(TInt aError, const TDesC8 &aBuffer);
271
 
    virtual void MaiscRecordComplete(TInt aError);
 
208
    public:
 
209
        enum State {
 
210
            STATE_INACTIVE,
 
211
            STATE_ACTIVE,
 
212
        };
 
213
 
 
214
        ~CPjAudioInputEngine();
 
215
 
 
216
        static CPjAudioInputEngine *NewL (struct mda_stream *parent_strm,
 
217
                                          pjmedia_aud_rec_cb rec_cb,
 
218
                                          void *user_data);
 
219
 
 
220
        static CPjAudioInputEngine *NewLC (struct mda_stream *parent_strm,
 
221
                                           pjmedia_aud_rec_cb rec_cb,
 
222
                                           void *user_data);
 
223
 
 
224
        pj_status_t StartRecord();
 
225
        void Stop();
 
226
 
 
227
        pj_status_t SetGain (TInt gain) {
 
228
            if (iInputStream_) {
 
229
                iInputStream_->SetGain (gain);
 
230
                return PJ_SUCCESS;
 
231
            } else
 
232
                return PJ_EINVALIDOP;
 
233
        }
 
234
 
 
235
        TInt GetGain() {
 
236
            if (iInputStream_) {
 
237
                return iInputStream_->Gain();
 
238
            } else
 
239
                return PJ_EINVALIDOP;
 
240
        }
 
241
 
 
242
        TInt GetMaxGain() {
 
243
            if (iInputStream_) {
 
244
                return iInputStream_->MaxGain();
 
245
            } else
 
246
                return PJ_EINVALIDOP;
 
247
        }
 
248
 
 
249
    private:
 
250
        State                state_;
 
251
        struct mda_stream           *parentStrm_;
 
252
        pjmedia_aud_rec_cb           recCb_;
 
253
        void                *userData_;
 
254
        CMdaAudioInputStream    *iInputStream_;
 
255
        HBufC8              *iStreamBuffer_;
 
256
        TPtr8                iFramePtr_;
 
257
        TInt                 lastError_;
 
258
        pj_uint32_t                  timeStamp_;
 
259
 
 
260
        // cache variable
 
261
        // to avoid calculating frame length repeatedly
 
262
        TInt                 frameLen_;
 
263
 
 
264
        // sometimes recorded size != requested framesize, so let's
 
265
        // provide a buffer to make sure the rec callback returning
 
266
        // framesize as requested.
 
267
        TUint8              *frameRecBuf_;
 
268
        TInt                 frameRecBufLen_;
 
269
 
 
270
        CPjAudioInputEngine (struct mda_stream *parent_strm,
 
271
                             pjmedia_aud_rec_cb rec_cb,
 
272
                             void *user_data);
 
273
        void ConstructL();
 
274
        TPtr8 & GetFrame();
 
275
 
 
276
    public:
 
277
        virtual void MaiscOpenComplete (TInt aError);
 
278
        virtual void MaiscBufferCopied (TInt aError, const TDesC8 &aBuffer);
 
279
        virtual void MaiscRecordComplete (TInt aError);
272
280
 
273
281
};
274
282
 
275
283
 
276
 
CPjAudioInputEngine::CPjAudioInputEngine(struct mda_stream *parent_strm,
277
 
                                         pjmedia_aud_rec_cb rec_cb,
278
 
                                         void *user_data)
279
 
    : state_(STATE_INACTIVE), parentStrm_(parent_strm), 
280
 
      recCb_(rec_cb), userData_(user_data), 
281
 
      iInputStream_(NULL), iStreamBuffer_(NULL), iFramePtr_(0, 0),
282
 
      lastError_(KErrNone), timeStamp_(0),
283
 
      frameLen_(parent_strm->param.samples_per_frame * 
284
 
                BYTES_PER_SAMPLE),
285
 
      frameRecBuf_(NULL), frameRecBufLen_(0)
 
284
CPjAudioInputEngine::CPjAudioInputEngine (struct mda_stream *parent_strm,
 
285
        pjmedia_aud_rec_cb rec_cb,
 
286
        void *user_data)
 
287
        : state_ (STATE_INACTIVE), parentStrm_ (parent_strm),
 
288
        recCb_ (rec_cb), userData_ (user_data),
 
289
        iInputStream_ (NULL), iStreamBuffer_ (NULL), iFramePtr_ (0, 0),
 
290
        lastError_ (KErrNone), timeStamp_ (0),
 
291
        frameLen_ (parent_strm->param.samples_per_frame *
 
292
                   BYTES_PER_SAMPLE),
 
293
        frameRecBuf_ (NULL), frameRecBufLen_ (0)
286
294
{
287
295
}
288
296
 
292
300
 
293
301
    delete iStreamBuffer_;
294
302
    iStreamBuffer_ = NULL;
295
 
    
 
303
 
296
304
    delete [] frameRecBuf_;
297
305
    frameRecBuf_ = NULL;
298
306
    frameRecBufLen_ = 0;
300
308
 
301
309
void CPjAudioInputEngine::ConstructL()
302
310
{
303
 
    iStreamBuffer_ = HBufC8::NewL(frameLen_);
304
 
    CleanupStack::PushL(iStreamBuffer_);
 
311
    iStreamBuffer_ = HBufC8::NewL (frameLen_);
 
312
    CleanupStack::PushL (iStreamBuffer_);
305
313
 
306
314
    frameRecBuf_ = new TUint8[frameLen_*2];
307
 
    CleanupStack::PushL(frameRecBuf_);
 
315
    CleanupStack::PushL (frameRecBuf_);
308
316
}
309
317
 
310
 
CPjAudioInputEngine *CPjAudioInputEngine::NewLC(struct mda_stream *parent,
311
 
                                                pjmedia_aud_rec_cb rec_cb,
312
 
                                                void *user_data)
 
318
CPjAudioInputEngine *CPjAudioInputEngine::NewLC (struct mda_stream *parent,
 
319
        pjmedia_aud_rec_cb rec_cb,
 
320
        void *user_data)
313
321
{
314
 
    CPjAudioInputEngine* self = new (ELeave) CPjAudioInputEngine(parent,
315
 
                                                                 rec_cb, 
316
 
                                                                 user_data);
317
 
    CleanupStack::PushL(self);
 
322
    CPjAudioInputEngine* self = new (ELeave) CPjAudioInputEngine (parent,
 
323
            rec_cb,
 
324
            user_data);
 
325
    CleanupStack::PushL (self);
318
326
    self->ConstructL();
319
327
    return self;
320
328
}
321
329
 
322
 
CPjAudioInputEngine *CPjAudioInputEngine::NewL(struct mda_stream *parent,
323
 
                                               pjmedia_aud_rec_cb rec_cb,
324
 
                                               void *user_data)
 
330
CPjAudioInputEngine *CPjAudioInputEngine::NewL (struct mda_stream *parent,
 
331
        pjmedia_aud_rec_cb rec_cb,
 
332
        void *user_data)
325
333
{
326
 
    CPjAudioInputEngine *self = NewLC(parent, rec_cb, user_data);
327
 
    CleanupStack::Pop(self->frameRecBuf_);
328
 
    CleanupStack::Pop(self->iStreamBuffer_);
329
 
    CleanupStack::Pop(self);
 
334
    CPjAudioInputEngine *self = NewLC (parent, rec_cb, user_data);
 
335
    CleanupStack::Pop (self->frameRecBuf_);
 
336
    CleanupStack::Pop (self->iStreamBuffer_);
 
337
    CleanupStack::Pop (self);
330
338
    return self;
331
339
}
332
340
 
336
344
 
337
345
    // Ignore command if recording is in progress.
338
346
    if (state_ == STATE_ACTIVE)
339
 
        return PJ_SUCCESS;
 
347
        return PJ_SUCCESS;
340
348
 
341
349
    // According to Nokia's AudioStream example, some 2nd Edition, FP2 devices
342
 
    // (such as Nokia 6630) require the stream to be reconstructed each time 
 
350
    // (such as Nokia 6630) require the stream to be reconstructed each time
343
351
    // before calling Open() - otherwise the callback never gets called.
344
352
    // For uniform behavior, lets just delete/re-create the stream for all
345
353
    // devices.
346
354
 
347
355
    // Destroy existing stream.
348
356
    if (iInputStream_) delete iInputStream_;
 
357
 
349
358
    iInputStream_ = NULL;
350
359
 
351
360
    // Create the stream.
352
 
    TRAPD(err, iInputStream_ = CMdaAudioInputStream::NewL(*this));
 
361
    TRAPD (err, iInputStream_ = CMdaAudioInputStream::NewL (*this));
 
362
 
353
363
    if (err != KErrNone)
354
 
        return PJ_RETURN_OS_ERROR(err);
 
364
        return PJ_RETURN_OS_ERROR (err);
355
365
 
356
366
    // Initialize settings.
357
367
    TMdaAudioDataSettings iStreamSettings;
358
 
    iStreamSettings.iChannels = 
359
 
                            get_channel_cap(parentStrm_->param.channel_count);
360
 
    iStreamSettings.iSampleRate = 
361
 
                            get_clock_rate_cap(parentStrm_->param.clock_rate);
362
 
 
363
 
    pj_assert(iStreamSettings.iChannels != 0 && 
364
 
              iStreamSettings.iSampleRate != 0);
365
 
 
366
 
    PJ_LOG(4,(THIS_FILE, "Opening sound device for capture, "
367
 
                         "clock rate=%d, channel count=%d..",
368
 
                         parentStrm_->param.clock_rate, 
369
 
                         parentStrm_->param.channel_count));
370
 
    
 
368
    iStreamSettings.iChannels =
 
369
        get_channel_cap (parentStrm_->param.channel_count);
 
370
    iStreamSettings.iSampleRate =
 
371
        get_clock_rate_cap (parentStrm_->param.clock_rate);
 
372
 
 
373
    pj_assert (iStreamSettings.iChannels != 0 &&
 
374
               iStreamSettings.iSampleRate != 0);
 
375
 
 
376
    PJ_LOG (4, (THIS_FILE, "Opening sound device for capture, "
 
377
                "clock rate=%d, channel count=%d..",
 
378
                parentStrm_->param.clock_rate,
 
379
                parentStrm_->param.channel_count));
 
380
 
371
381
    // Open stream.
372
382
    lastError_ = KRequestPending;
373
 
    iInputStream_->Open(&iStreamSettings);
374
 
    
 
383
    iInputStream_->Open (&iStreamSettings);
 
384
 
375
385
    // Success
376
 
    PJ_LOG(4,(THIS_FILE, "Sound capture started."));
 
386
    PJ_LOG (4, (THIS_FILE, "Sound capture started."));
377
387
    return PJ_SUCCESS;
378
388
}
379
389
 
382
392
{
383
393
    // If capture is in progress, stop it.
384
394
    if (iInputStream_ && state_ == STATE_ACTIVE) {
385
 
        lastError_ = KRequestPending;
386
 
        iInputStream_->Stop();
 
395
        lastError_ = KRequestPending;
 
396
        iInputStream_->Stop();
387
397
 
388
 
        // Wait until it's actually stopped
389
 
        while (lastError_ == KRequestPending)
390
 
            pj_symbianos_poll(-1, 100);
 
398
        // Wait until it's actually stopped
 
399
        while (lastError_ == KRequestPending)
 
400
            pj_symbianos_poll (-1, 100);
391
401
    }
392
402
 
393
403
    if (iInputStream_) {
394
 
        delete iInputStream_;
395
 
        iInputStream_ = NULL;
 
404
        delete iInputStream_;
 
405
        iInputStream_ = NULL;
396
406
    }
397
 
    
 
407
 
398
408
    state_ = STATE_INACTIVE;
399
409
}
400
410
 
401
411
 
402
 
TPtr8 & CPjAudioInputEngine::GetFrame() 
 
412
TPtr8 & CPjAudioInputEngine::GetFrame()
403
413
{
404
414
    //iStreamBuffer_->Des().FillZ(frameLen_);
405
 
    iFramePtr_.Set((TUint8*)(iStreamBuffer_->Ptr()), frameLen_, frameLen_);
 
415
    iFramePtr_.Set ( (TUint8*) (iStreamBuffer_->Ptr()), frameLen_, frameLen_);
406
416
    return iFramePtr_;
407
417
}
408
418
 
409
 
void CPjAudioInputEngine::MaiscOpenComplete(TInt aError)
 
419
void CPjAudioInputEngine::MaiscOpenComplete (TInt aError)
410
420
{
411
421
    lastError_ = aError;
 
422
 
412
423
    if (aError != KErrNone) {
413
 
        snd_perror("Error in MaiscOpenComplete()", aError);
414
 
        return;
 
424
        snd_perror ("Error in MaiscOpenComplete()", aError);
 
425
        return;
415
426
    }
416
427
 
417
428
    // set stream priority to normal and time sensitive
418
 
    iInputStream_->SetPriority(EPriorityNormal, 
419
 
                               EMdaPriorityPreferenceTime);                             
 
429
    iInputStream_->SetPriority (EPriorityNormal,
 
430
                                EMdaPriorityPreferenceTime);
420
431
 
421
432
    // Read the first frame.
422
433
    TPtr8 & frm = GetFrame();
423
 
    TRAPD(err2, iInputStream_->ReadL(frm));
 
434
    TRAPD (err2, iInputStream_->ReadL (frm));
 
435
 
424
436
    if (err2) {
425
 
        PJ_LOG(4,(THIS_FILE, "Exception in iInputStream_->ReadL()"));
 
437
        PJ_LOG (4, (THIS_FILE, "Exception in iInputStream_->ReadL()"));
426
438
    }
427
439
}
428
440
 
429
 
void CPjAudioInputEngine::MaiscBufferCopied(TInt aError, 
430
 
                                            const TDesC8 &aBuffer)
 
441
void CPjAudioInputEngine::MaiscBufferCopied (TInt aError,
 
442
        const TDesC8 &aBuffer)
431
443
{
432
444
    lastError_ = aError;
 
445
 
433
446
    if (aError != KErrNone) {
434
 
        snd_perror("Error in MaiscBufferCopied()", aError);
435
 
        return;
 
447
        snd_perror ("Error in MaiscBufferCopied()", aError);
 
448
        return;
436
449
    }
437
450
 
438
451
    if (frameRecBufLen_ || aBuffer.Length() < frameLen_) {
439
 
        pj_memcpy(frameRecBuf_ + frameRecBufLen_, (void*) aBuffer.Ptr(), aBuffer.Length());
440
 
        frameRecBufLen_ += aBuffer.Length();
 
452
        pj_memcpy (frameRecBuf_ + frameRecBufLen_, (void*) aBuffer.Ptr(), aBuffer.Length());
 
453
        frameRecBufLen_ += aBuffer.Length();
441
454
    }
442
455
 
443
456
    if (frameRecBufLen_) {
444
 
        while (frameRecBufLen_ >= frameLen_) {
445
 
            pjmedia_frame f;
446
 
            
447
 
            f.type = PJMEDIA_FRAME_TYPE_AUDIO;
448
 
            f.buf = frameRecBuf_;
449
 
            f.size = frameLen_;
450
 
            f.timestamp.u32.lo = timeStamp_;
451
 
            f.bit_info = 0;
452
 
            
453
 
            // Call the callback.
454
 
            recCb_(userData_, &f);
455
 
            // Increment timestamp.
456
 
            timeStamp_ += parentStrm_->param.samples_per_frame;
457
 
 
458
 
            frameRecBufLen_ -= frameLen_;
459
 
            pj_memmove(frameRecBuf_, frameRecBuf_+frameLen_, frameRecBufLen_);
460
 
        }
 
457
        while (frameRecBufLen_ >= frameLen_) {
 
458
            pjmedia_frame f;
 
459
 
 
460
            f.type = PJMEDIA_FRAME_TYPE_AUDIO;
 
461
            f.buf = frameRecBuf_;
 
462
            f.size = frameLen_;
 
463
            f.timestamp.u32.lo = timeStamp_;
 
464
            f.bit_info = 0;
 
465
 
 
466
            // Call the callback.
 
467
            recCb_ (userData_, &f);
 
468
            // Increment timestamp.
 
469
            timeStamp_ += parentStrm_->param.samples_per_frame;
 
470
 
 
471
            frameRecBufLen_ -= frameLen_;
 
472
            pj_memmove (frameRecBuf_, frameRecBuf_+frameLen_, frameRecBufLen_);
 
473
        }
461
474
    } else {
462
 
        pjmedia_frame f;
463
 
        
464
 
        f.type = PJMEDIA_FRAME_TYPE_AUDIO;
465
 
        f.buf = (void*)aBuffer.Ptr();
466
 
        f.size = aBuffer.Length();
467
 
        f.timestamp.u32.lo = timeStamp_;
468
 
        f.bit_info = 0;
469
 
        
470
 
        // Call the callback.
471
 
        recCb_(userData_, &f);
472
 
        
473
 
        // Increment timestamp.
474
 
        timeStamp_ += parentStrm_->param.samples_per_frame;
 
475
        pjmedia_frame f;
 
476
 
 
477
        f.type = PJMEDIA_FRAME_TYPE_AUDIO;
 
478
        f.buf = (void*) aBuffer.Ptr();
 
479
        f.size = aBuffer.Length();
 
480
        f.timestamp.u32.lo = timeStamp_;
 
481
        f.bit_info = 0;
 
482
 
 
483
        // Call the callback.
 
484
        recCb_ (userData_, &f);
 
485
 
 
486
        // Increment timestamp.
 
487
        timeStamp_ += parentStrm_->param.samples_per_frame;
475
488
    }
476
489
 
477
490
    // Record next frame
478
491
    TPtr8 & frm = GetFrame();
479
 
    TRAPD(err2, iInputStream_->ReadL(frm));
 
492
    TRAPD (err2, iInputStream_->ReadL (frm));
 
493
 
480
494
    if (err2) {
481
 
        PJ_LOG(4,(THIS_FILE, "Exception in iInputStream_->ReadL()"));
 
495
        PJ_LOG (4, (THIS_FILE, "Exception in iInputStream_->ReadL()"));
482
496
    }
483
497
}
484
498
 
485
499
 
486
 
void CPjAudioInputEngine::MaiscRecordComplete(TInt aError)
 
500
void CPjAudioInputEngine::MaiscRecordComplete (TInt aError)
487
501
{
488
502
    lastError_ = aError;
489
503
    state_ = STATE_INACTIVE;
 
504
 
490
505
    if (aError != KErrNone && aError != KErrCancel) {
491
 
        snd_perror("Error in MaiscRecordComplete()", aError);
 
506
        snd_perror ("Error in MaiscRecordComplete()", aError);
492
507
    }
493
508
}
494
509
 
503
518
 
504
519
class CPjAudioOutputEngine : public CBase, MMdaAudioOutputStreamCallback
505
520
{
506
 
public:
507
 
    enum State
508
 
    {
509
 
        STATE_INACTIVE,
510
 
        STATE_ACTIVE,
511
 
    };
512
 
 
513
 
    ~CPjAudioOutputEngine();
514
 
 
515
 
    static CPjAudioOutputEngine *NewL(struct mda_stream *parent_strm,
516
 
                                      pjmedia_aud_play_cb play_cb,
517
 
                                      void *user_data);
518
 
 
519
 
    static CPjAudioOutputEngine *NewLC(struct mda_stream *parent_strm,
520
 
                                       pjmedia_aud_play_cb rec_cb,
521
 
                                       void *user_data);
522
 
 
523
 
    pj_status_t StartPlay();
524
 
    void Stop();
525
 
 
526
 
    pj_status_t SetVolume(TInt vol) { 
527
 
        if (iOutputStream_) { 
528
 
            iOutputStream_->SetVolume(vol);
529
 
            return PJ_SUCCESS;
530
 
        } else
531
 
            return PJ_EINVALIDOP;
532
 
    }
533
 
    
534
 
    TInt GetVolume() { 
535
 
        if (iOutputStream_) { 
536
 
            return iOutputStream_->Volume();
537
 
        } else
538
 
            return PJ_EINVALIDOP;
539
 
    }
540
 
 
541
 
    TInt GetMaxVolume() { 
542
 
        if (iOutputStream_) { 
543
 
            return iOutputStream_->MaxVolume();
544
 
        } else
545
 
            return PJ_EINVALIDOP;
546
 
    }
547
 
 
548
 
private:
549
 
    State                    state_;
550
 
    struct mda_stream       *parentStrm_;
551
 
    pjmedia_aud_play_cb      playCb_;
552
 
    void                    *userData_;
553
 
    CMdaAudioOutputStream   *iOutputStream_;
554
 
    TUint8                  *frameBuf_;
555
 
    unsigned                 frameBufSize_;
556
 
    TPtrC8                   frame_;
557
 
    TInt                     lastError_;
558
 
    unsigned                 timestamp_;
559
 
 
560
 
    CPjAudioOutputEngine(struct mda_stream *parent_strm,
561
 
                         pjmedia_aud_play_cb play_cb,
562
 
                         void *user_data);
563
 
    void ConstructL();
564
 
 
565
 
    virtual void MaoscOpenComplete(TInt aError);
566
 
    virtual void MaoscBufferCopied(TInt aError, const TDesC8& aBuffer);
567
 
    virtual void MaoscPlayComplete(TInt aError);
 
521
    public:
 
522
        enum State {
 
523
            STATE_INACTIVE,
 
524
            STATE_ACTIVE,
 
525
        };
 
526
 
 
527
        ~CPjAudioOutputEngine();
 
528
 
 
529
        static CPjAudioOutputEngine *NewL (struct mda_stream *parent_strm,
 
530
                                           pjmedia_aud_play_cb play_cb,
 
531
                                           void *user_data);
 
532
 
 
533
        static CPjAudioOutputEngine *NewLC (struct mda_stream *parent_strm,
 
534
                                            pjmedia_aud_play_cb rec_cb,
 
535
                                            void *user_data);
 
536
 
 
537
        pj_status_t StartPlay();
 
538
        void Stop();
 
539
 
 
540
        pj_status_t SetVolume (TInt vol) {
 
541
            if (iOutputStream_) {
 
542
                iOutputStream_->SetVolume (vol);
 
543
                return PJ_SUCCESS;
 
544
            } else
 
545
                return PJ_EINVALIDOP;
 
546
        }
 
547
 
 
548
        TInt GetVolume() {
 
549
            if (iOutputStream_) {
 
550
                return iOutputStream_->Volume();
 
551
            } else
 
552
                return PJ_EINVALIDOP;
 
553
        }
 
554
 
 
555
        TInt GetMaxVolume() {
 
556
            if (iOutputStream_) {
 
557
                return iOutputStream_->MaxVolume();
 
558
            } else
 
559
                return PJ_EINVALIDOP;
 
560
        }
 
561
 
 
562
    private:
 
563
        State                state_;
 
564
        struct mda_stream           *parentStrm_;
 
565
        pjmedia_aud_play_cb          playCb_;
 
566
        void                *userData_;
 
567
        CMdaAudioOutputStream   *iOutputStream_;
 
568
        TUint8              *frameBuf_;
 
569
        unsigned                     frameBufSize_;
 
570
        TPtrC8               frame_;
 
571
        TInt                 lastError_;
 
572
        unsigned                     timestamp_;
 
573
 
 
574
        CPjAudioOutputEngine (struct mda_stream *parent_strm,
 
575
                              pjmedia_aud_play_cb play_cb,
 
576
                              void *user_data);
 
577
        void ConstructL();
 
578
 
 
579
        virtual void MaoscOpenComplete (TInt aError);
 
580
        virtual void MaoscBufferCopied (TInt aError, const TDesC8& aBuffer);
 
581
        virtual void MaoscPlayComplete (TInt aError);
568
582
};
569
583
 
570
584
 
571
 
CPjAudioOutputEngine::CPjAudioOutputEngine(struct mda_stream *parent_strm,
572
 
                                           pjmedia_aud_play_cb play_cb,
573
 
                                           void *user_data) 
574
 
: state_(STATE_INACTIVE), parentStrm_(parent_strm), playCb_(play_cb), 
575
 
  userData_(user_data), iOutputStream_(NULL), frameBuf_(NULL),
576
 
  lastError_(KErrNone), timestamp_(0)
 
585
CPjAudioOutputEngine::CPjAudioOutputEngine (struct mda_stream *parent_strm,
 
586
        pjmedia_aud_play_cb play_cb,
 
587
        void *user_data)
 
588
        : state_ (STATE_INACTIVE), parentStrm_ (parent_strm), playCb_ (play_cb),
 
589
        userData_ (user_data), iOutputStream_ (NULL), frameBuf_ (NULL),
 
590
        lastError_ (KErrNone), timestamp_ (0)
577
591
{
578
592
}
579
593
 
581
595
void CPjAudioOutputEngine::ConstructL()
582
596
{
583
597
    frameBufSize_ = parentStrm_->param.samples_per_frame *
584
 
                    BYTES_PER_SAMPLE;
 
598
                    BYTES_PER_SAMPLE;
585
599
    frameBuf_ = new TUint8[frameBufSize_];
586
600
}
587
601
 
588
602
CPjAudioOutputEngine::~CPjAudioOutputEngine()
589
603
{
590
604
    Stop();
591
 
    delete [] frameBuf_;        
 
605
    delete [] frameBuf_;
592
606
}
593
607
 
594
608
CPjAudioOutputEngine *
595
 
CPjAudioOutputEngine::NewLC(struct mda_stream *parent_strm,
596
 
                            pjmedia_aud_play_cb play_cb,
597
 
                            void *user_data)
 
609
CPjAudioOutputEngine::NewLC (struct mda_stream *parent_strm,
 
610
                             pjmedia_aud_play_cb play_cb,
 
611
                             void *user_data)
598
612
{
599
 
    CPjAudioOutputEngine* self = new (ELeave) CPjAudioOutputEngine(parent_strm,
600
 
                                                                   play_cb, 
601
 
                                                                   user_data);
602
 
    CleanupStack::PushL(self);
 
613
    CPjAudioOutputEngine* self = new (ELeave) CPjAudioOutputEngine (parent_strm,
 
614
            play_cb,
 
615
            user_data);
 
616
    CleanupStack::PushL (self);
603
617
    self->ConstructL();
604
618
    return self;
605
619
}
606
620
 
607
621
CPjAudioOutputEngine *
608
 
CPjAudioOutputEngine::NewL(struct mda_stream *parent_strm,
609
 
                           pjmedia_aud_play_cb play_cb,
610
 
                           void *user_data)
 
622
CPjAudioOutputEngine::NewL (struct mda_stream *parent_strm,
 
623
                            pjmedia_aud_play_cb play_cb,
 
624
                            void *user_data)
611
625
{
612
 
    CPjAudioOutputEngine *self = NewLC(parent_strm, play_cb, user_data);
613
 
    CleanupStack::Pop(self);
 
626
    CPjAudioOutputEngine *self = NewLC (parent_strm, play_cb, user_data);
 
627
    CleanupStack::Pop (self);
614
628
    return self;
615
629
}
616
630
 
618
632
{
619
633
    // Ignore command if playing is in progress.
620
634
    if (state_ == STATE_ACTIVE)
621
 
        return PJ_SUCCESS;
622
 
    
 
635
        return PJ_SUCCESS;
 
636
 
623
637
    // Destroy existing stream.
624
638
    if (iOutputStream_) delete iOutputStream_;
 
639
 
625
640
    iOutputStream_ = NULL;
626
 
    
 
641
 
627
642
    // Create the stream
628
 
    TRAPD(err, iOutputStream_ = CMdaAudioOutputStream::NewL(*this));
 
643
    TRAPD (err, iOutputStream_ = CMdaAudioOutputStream::NewL (*this));
 
644
 
629
645
    if (err != KErrNone)
630
 
        return PJ_RETURN_OS_ERROR(err);
631
 
    
 
646
        return PJ_RETURN_OS_ERROR (err);
 
647
 
632
648
    // Initialize settings.
633
649
    TMdaAudioDataSettings iStreamSettings;
634
 
    iStreamSettings.iChannels = 
635
 
                            get_channel_cap(parentStrm_->param.channel_count);
636
 
    iStreamSettings.iSampleRate = 
637
 
                            get_clock_rate_cap(parentStrm_->param.clock_rate);
638
 
 
639
 
    pj_assert(iStreamSettings.iChannels != 0 && 
640
 
              iStreamSettings.iSampleRate != 0);
641
 
    
642
 
    PJ_LOG(4,(THIS_FILE, "Opening sound device for playback, "
643
 
                         "clock rate=%d, channel count=%d..",
644
 
                         parentStrm_->param.clock_rate, 
645
 
                         parentStrm_->param.channel_count));
 
650
    iStreamSettings.iChannels =
 
651
        get_channel_cap (parentStrm_->param.channel_count);
 
652
    iStreamSettings.iSampleRate =
 
653
        get_clock_rate_cap (parentStrm_->param.clock_rate);
 
654
 
 
655
    pj_assert (iStreamSettings.iChannels != 0 &&
 
656
               iStreamSettings.iSampleRate != 0);
 
657
 
 
658
    PJ_LOG (4, (THIS_FILE, "Opening sound device for playback, "
 
659
                "clock rate=%d, channel count=%d..",
 
660
                parentStrm_->param.clock_rate,
 
661
                parentStrm_->param.channel_count));
646
662
 
647
663
    // Open stream.
648
664
    lastError_ = KRequestPending;
649
 
    iOutputStream_->Open(&iStreamSettings);
 
665
    iOutputStream_->Open (&iStreamSettings);
650
666
 
651
667
    // Success
652
 
    PJ_LOG(4,(THIS_FILE, "Sound playback started"));
 
668
    PJ_LOG (4, (THIS_FILE, "Sound playback started"));
653
669
    return PJ_SUCCESS;
654
670
 
655
671
}
658
674
{
659
675
    // Stop stream if it's playing
660
676
    if (iOutputStream_ && state_ != STATE_INACTIVE) {
661
 
        lastError_ = KRequestPending;
662
 
        iOutputStream_->Stop();
663
 
 
664
 
        // Wait until it's actually stopped
665
 
        while (lastError_ == KRequestPending)
666
 
            pj_symbianos_poll(-1, 100);
667
 
    }
668
 
    
669
 
    if (iOutputStream_) {       
670
 
        delete iOutputStream_;
671
 
        iOutputStream_ = NULL;
672
 
    }
673
 
    
 
677
        lastError_ = KRequestPending;
 
678
        iOutputStream_->Stop();
 
679
 
 
680
        // Wait until it's actually stopped
 
681
        while (lastError_ == KRequestPending)
 
682
            pj_symbianos_poll (-1, 100);
 
683
    }
 
684
 
 
685
    if (iOutputStream_) {
 
686
        delete iOutputStream_;
 
687
        iOutputStream_ = NULL;
 
688
    }
 
689
 
674
690
    state_ = STATE_INACTIVE;
675
691
}
676
692
 
677
 
void CPjAudioOutputEngine::MaoscOpenComplete(TInt aError)
 
693
void CPjAudioOutputEngine::MaoscOpenComplete (TInt aError)
678
694
{
679
695
    lastError_ = aError;
680
 
    
 
696
 
681
697
    if (aError==KErrNone) {
682
 
        // output stream opened succesfully, set status to Active
683
 
        state_ = STATE_ACTIVE;
684
 
 
685
 
        // set stream properties, 16bit 8KHz mono
686
 
        TMdaAudioDataSettings iSettings;
687
 
        iSettings.iChannels = 
688
 
                        get_channel_cap(parentStrm_->param.channel_count);
689
 
        iSettings.iSampleRate = 
690
 
                        get_clock_rate_cap(parentStrm_->param.clock_rate);
691
 
 
692
 
        iOutputStream_->SetAudioPropertiesL(iSettings.iSampleRate, 
693
 
                                            iSettings.iChannels);
694
 
 
695
 
        // set volume to 1/2th of stream max volume
696
 
        iOutputStream_->SetVolume(iOutputStream_->MaxVolume()/2);
697
 
        
698
 
        // set stream priority to normal and time sensitive
699
 
        iOutputStream_->SetPriority(EPriorityNormal, 
700
 
                                    EMdaPriorityPreferenceTime);                                
701
 
 
702
 
        // Call callback to retrieve frame from upstream.
703
 
        pjmedia_frame f;
704
 
        pj_status_t status;
705
 
        
706
 
        f.type = PJMEDIA_FRAME_TYPE_AUDIO;
707
 
        f.buf = frameBuf_;
708
 
        f.size = frameBufSize_;
709
 
        f.timestamp.u32.lo = timestamp_;
710
 
        f.bit_info = 0;
711
 
 
712
 
        status = playCb_(this->userData_, &f);
713
 
        if (status != PJ_SUCCESS) {
714
 
            this->Stop();
715
 
            return;
716
 
        }
717
 
 
718
 
        if (f.type != PJMEDIA_FRAME_TYPE_AUDIO)
719
 
            pj_bzero(frameBuf_, frameBufSize_);
720
 
        
721
 
        // Increment timestamp.
722
 
        timestamp_ += (frameBufSize_ / BYTES_PER_SAMPLE);
723
 
 
724
 
        // issue WriteL() to write the first audio data block, 
725
 
        // subsequent calls to WriteL() will be issued in 
726
 
        // MMdaAudioOutputStreamCallback::MaoscBufferCopied() 
727
 
        // until whole data buffer is written.
728
 
        frame_.Set(frameBuf_, frameBufSize_);
729
 
        iOutputStream_->WriteL(frame_);
 
698
        // output stream opened succesfully, set status to Active
 
699
        state_ = STATE_ACTIVE;
 
700
 
 
701
        // set stream properties, 16bit 8KHz mono
 
702
        TMdaAudioDataSettings iSettings;
 
703
        iSettings.iChannels =
 
704
            get_channel_cap (parentStrm_->param.channel_count);
 
705
        iSettings.iSampleRate =
 
706
            get_clock_rate_cap (parentStrm_->param.clock_rate);
 
707
 
 
708
        iOutputStream_->SetAudioPropertiesL (iSettings.iSampleRate,
 
709
                                             iSettings.iChannels);
 
710
 
 
711
        // set volume to 1/2th of stream max volume
 
712
        iOutputStream_->SetVolume (iOutputStream_->MaxVolume() /2);
 
713
 
 
714
        // set stream priority to normal and time sensitive
 
715
        iOutputStream_->SetPriority (EPriorityNormal,
 
716
                                     EMdaPriorityPreferenceTime);
 
717
 
 
718
        // Call callback to retrieve frame from upstream.
 
719
        pjmedia_frame f;
 
720
        pj_status_t status;
 
721
 
 
722
        f.type = PJMEDIA_FRAME_TYPE_AUDIO;
 
723
        f.buf = frameBuf_;
 
724
        f.size = frameBufSize_;
 
725
        f.timestamp.u32.lo = timestamp_;
 
726
        f.bit_info = 0;
 
727
 
 
728
        status = playCb_ (this->userData_, &f);
 
729
 
 
730
        if (status != PJ_SUCCESS) {
 
731
            this->Stop();
 
732
            return;
 
733
        }
 
734
 
 
735
        if (f.type != PJMEDIA_FRAME_TYPE_AUDIO)
 
736
            pj_bzero (frameBuf_, frameBufSize_);
 
737
 
 
738
        // Increment timestamp.
 
739
        timestamp_ += (frameBufSize_ / BYTES_PER_SAMPLE);
 
740
 
 
741
        // issue WriteL() to write the first audio data block,
 
742
        // subsequent calls to WriteL() will be issued in
 
743
        // MMdaAudioOutputStreamCallback::MaoscBufferCopied()
 
744
        // until whole data buffer is written.
 
745
        frame_.Set (frameBuf_, frameBufSize_);
 
746
        iOutputStream_->WriteL (frame_);
730
747
    } else {
731
 
        snd_perror("Error in MaoscOpenComplete()", aError);
 
748
        snd_perror ("Error in MaoscOpenComplete()", aError);
732
749
    }
733
750
}
734
751
 
735
 
void CPjAudioOutputEngine::MaoscBufferCopied(TInt aError, 
736
 
                                             const TDesC8& aBuffer)
 
752
void CPjAudioOutputEngine::MaoscBufferCopied (TInt aError,
 
753
        const TDesC8& aBuffer)
737
754
{
738
 
    PJ_UNUSED_ARG(aBuffer);
 
755
    PJ_UNUSED_ARG (aBuffer);
739
756
 
740
757
    if (aError==KErrNone) {
741
 
        // Buffer successfully written, feed another one.
742
 
 
743
 
        // Call callback to retrieve frame from upstream.
744
 
        pjmedia_frame f;
745
 
        pj_status_t status;
746
 
        
747
 
        f.type = PJMEDIA_FRAME_TYPE_AUDIO;
748
 
        f.buf = frameBuf_;
749
 
        f.size = frameBufSize_;
750
 
        f.timestamp.u32.lo = timestamp_;
751
 
        f.bit_info = 0;
752
 
 
753
 
        status = playCb_(this->userData_, &f);
754
 
        if (status != PJ_SUCCESS) {
755
 
            this->Stop();
756
 
            return;
757
 
        }
758
 
 
759
 
        if (f.type != PJMEDIA_FRAME_TYPE_AUDIO)
760
 
            pj_bzero(frameBuf_, frameBufSize_);
761
 
        
762
 
        // Increment timestamp.
763
 
        timestamp_ += (frameBufSize_ / BYTES_PER_SAMPLE);
764
 
 
765
 
        // Write to playback stream.
766
 
        frame_.Set(frameBuf_, frameBufSize_);
767
 
        iOutputStream_->WriteL(frame_);
 
758
        // Buffer successfully written, feed another one.
 
759
 
 
760
        // Call callback to retrieve frame from upstream.
 
761
        pjmedia_frame f;
 
762
        pj_status_t status;
 
763
 
 
764
        f.type = PJMEDIA_FRAME_TYPE_AUDIO;
 
765
        f.buf = frameBuf_;
 
766
        f.size = frameBufSize_;
 
767
        f.timestamp.u32.lo = timestamp_;
 
768
        f.bit_info = 0;
 
769
 
 
770
        status = playCb_ (this->userData_, &f);
 
771
 
 
772
        if (status != PJ_SUCCESS) {
 
773
            this->Stop();
 
774
            return;
 
775
        }
 
776
 
 
777
        if (f.type != PJMEDIA_FRAME_TYPE_AUDIO)
 
778
            pj_bzero (frameBuf_, frameBufSize_);
 
779
 
 
780
        // Increment timestamp.
 
781
        timestamp_ += (frameBufSize_ / BYTES_PER_SAMPLE);
 
782
 
 
783
        // Write to playback stream.
 
784
        frame_.Set (frameBuf_, frameBufSize_);
 
785
        iOutputStream_->WriteL (frame_);
768
786
 
769
787
    } else if (aError==KErrAbort) {
770
 
        // playing was aborted, due to call to CMdaAudioOutputStream::Stop()
771
 
        state_ = STATE_INACTIVE;
 
788
        // playing was aborted, due to call to CMdaAudioOutputStream::Stop()
 
789
        state_ = STATE_INACTIVE;
772
790
    } else  {
773
 
        // error writing data to output
774
 
        lastError_ = aError;
775
 
        state_ = STATE_INACTIVE;
776
 
        snd_perror("Error in MaoscBufferCopied()", aError);
 
791
        // error writing data to output
 
792
        lastError_ = aError;
 
793
        state_ = STATE_INACTIVE;
 
794
        snd_perror ("Error in MaoscBufferCopied()", aError);
777
795
    }
778
796
}
779
797
 
780
 
void CPjAudioOutputEngine::MaoscPlayComplete(TInt aError)
 
798
void CPjAudioOutputEngine::MaoscPlayComplete (TInt aError)
781
799
{
782
800
    lastError_ = aError;
783
801
    state_ = STATE_INACTIVE;
 
802
 
784
803
    if (aError != KErrNone && aError != KErrCancel) {
785
 
        snd_perror("Error in MaoscPlayComplete()", aError);
 
804
        snd_perror ("Error in MaoscPlayComplete()", aError);
786
805
    }
787
806
}
788
807
 
794
813
 * C compatible declaration of MDA factory.
795
814
 */
796
815
PJ_BEGIN_DECL
797
 
PJ_DECL(pjmedia_aud_dev_factory*) pjmedia_symb_mda_factory(pj_pool_factory *pf);
 
816
PJ_DECL (pjmedia_aud_dev_factory*) pjmedia_symb_mda_factory (pj_pool_factory *pf);
798
817
PJ_END_DECL
799
818
 
800
819
/*
801
820
 * Init Symbian audio driver.
802
821
 */
803
 
pjmedia_aud_dev_factory* pjmedia_symb_mda_factory(pj_pool_factory *pf)
 
822
pjmedia_aud_dev_factory* pjmedia_symb_mda_factory (pj_pool_factory *pf)
804
823
{
805
824
    struct mda_factory *f;
806
825
    pj_pool_t *pool;
807
826
 
808
 
    pool = pj_pool_create(pf, "symb_aud", 1000, 1000, NULL);
809
 
    f = PJ_POOL_ZALLOC_T(pool, struct mda_factory);
 
827
    pool = pj_pool_create (pf, "symb_aud", 1000, 1000, NULL);
 
828
    f = PJ_POOL_ZALLOC_T (pool, struct mda_factory);
810
829
    f->pf = pf;
811
830
    f->pool = pool;
812
831
    f->base.op = &factory_op;
815
834
}
816
835
 
817
836
/* API: init factory */
818
 
static pj_status_t factory_init(pjmedia_aud_dev_factory *f)
 
837
static pj_status_t factory_init (pjmedia_aud_dev_factory *f)
819
838
{
820
 
    struct mda_factory *af = (struct mda_factory*)f;
 
839
    struct mda_factory *af = (struct mda_factory*) f;
821
840
 
822
 
    pj_ansi_strcpy(af->dev_info.name, "Symbian Audio");
 
841
    pj_ansi_strcpy (af->dev_info.name, "Symbian Audio");
823
842
    af->dev_info.default_samples_per_sec = 8000;
824
843
    af->dev_info.caps = PJMEDIA_AUD_DEV_CAP_INPUT_VOLUME_SETTING |
825
 
                        PJMEDIA_AUD_DEV_CAP_OUTPUT_VOLUME_SETTING;
 
844
                        PJMEDIA_AUD_DEV_CAP_OUTPUT_VOLUME_SETTING;
826
845
    af->dev_info.input_count = 1;
827
846
    af->dev_info.output_count = 1;
828
847
 
829
 
    PJ_LOG(4, (THIS_FILE, "Symb Mda initialized"));
 
848
    PJ_LOG (4, (THIS_FILE, "Symb Mda initialized"));
830
849
 
831
850
    return PJ_SUCCESS;
832
851
}
833
852
 
834
853
/* API: destroy factory */
835
 
static pj_status_t factory_destroy(pjmedia_aud_dev_factory *f)
 
854
static pj_status_t factory_destroy (pjmedia_aud_dev_factory *f)
836
855
{
837
 
    struct mda_factory *af = (struct mda_factory*)f;
 
856
    struct mda_factory *af = (struct mda_factory*) f;
838
857
    pj_pool_t *pool = af->pool;
839
858
 
840
859
    af->pool = NULL;
841
 
    pj_pool_release(pool);
842
 
 
843
 
    PJ_LOG(4, (THIS_FILE, "Symbian Mda destroyed"));
844
 
    
 
860
    pj_pool_release (pool);
 
861
 
 
862
    PJ_LOG (4, (THIS_FILE, "Symbian Mda destroyed"));
 
863
 
845
864
    return PJ_SUCCESS;
846
865
}
847
866
 
848
867
/* API: get number of devices */
849
 
static unsigned factory_get_dev_count(pjmedia_aud_dev_factory *f)
 
868
static unsigned factory_get_dev_count (pjmedia_aud_dev_factory *f)
850
869
{
851
 
    PJ_UNUSED_ARG(f);
 
870
    PJ_UNUSED_ARG (f);
852
871
    return 1;
853
872
}
854
873
 
855
874
/* API: get device info */
856
 
static pj_status_t factory_get_dev_info(pjmedia_aud_dev_factory *f, 
857
 
                                        unsigned index,
858
 
                                        pjmedia_aud_dev_info *info)
 
875
static pj_status_t factory_get_dev_info (pjmedia_aud_dev_factory *f,
 
876
        unsigned index,
 
877
        pjmedia_aud_dev_info *info)
859
878
{
860
 
    struct mda_factory *af = (struct mda_factory*)f;
861
 
 
862
 
    PJ_ASSERT_RETURN(index == 0, PJMEDIA_EAUD_INVDEV);
863
 
 
864
 
    pj_memcpy(info, &af->dev_info, sizeof(*info));
 
879
    struct mda_factory *af = (struct mda_factory*) f;
 
880
 
 
881
    PJ_ASSERT_RETURN (index == 0, PJMEDIA_EAUD_INVDEV);
 
882
 
 
883
    pj_memcpy (info, &af->dev_info, sizeof (*info));
865
884
 
866
885
    return PJ_SUCCESS;
867
886
}
868
887
 
869
888
/* API: create default device parameter */
870
 
static pj_status_t factory_default_param(pjmedia_aud_dev_factory *f,
871
 
                                         unsigned index,
872
 
                                         pjmedia_aud_param *param)
 
889
static pj_status_t factory_default_param (pjmedia_aud_dev_factory *f,
 
890
        unsigned index,
 
891
        pjmedia_aud_param *param)
873
892
{
874
 
    struct mda_factory *af = (struct mda_factory*)f;
875
 
 
876
 
    PJ_ASSERT_RETURN(index == 0, PJMEDIA_EAUD_INVDEV);
877
 
 
878
 
    pj_bzero(param, sizeof(*param));
 
893
    struct mda_factory *af = (struct mda_factory*) f;
 
894
 
 
895
    PJ_ASSERT_RETURN (index == 0, PJMEDIA_EAUD_INVDEV);
 
896
 
 
897
    pj_bzero (param, sizeof (*param));
879
898
    param->dir = PJMEDIA_DIR_CAPTURE_PLAYBACK;
880
899
    param->rec_id = index;
881
900
    param->play_id = index;
890
909
 
891
910
 
892
911
/* API: create stream */
893
 
static pj_status_t factory_create_stream(pjmedia_aud_dev_factory *f,
894
 
                                         const pjmedia_aud_param *param,
895
 
                                         pjmedia_aud_rec_cb rec_cb,
896
 
                                         pjmedia_aud_play_cb play_cb,
897
 
                                         void *user_data,
898
 
                                         pjmedia_aud_stream **p_aud_strm)
 
912
static pj_status_t factory_create_stream (pjmedia_aud_dev_factory *f,
 
913
        const pjmedia_aud_param *param,
 
914
        pjmedia_aud_rec_cb rec_cb,
 
915
        pjmedia_aud_play_cb play_cb,
 
916
        void *user_data,
 
917
        pjmedia_aud_stream **p_aud_strm)
899
918
{
900
 
    struct mda_factory *mf = (struct mda_factory*)f;
 
919
    struct mda_factory *mf = (struct mda_factory*) f;
901
920
    pj_pool_t *pool;
902
921
    struct mda_stream *strm;
903
922
 
904
923
    /* Can only support 16bits per sample raw PCM format. */
905
 
    PJ_ASSERT_RETURN(param->bits_per_sample == BITS_PER_SAMPLE, PJ_EINVAL);
906
 
    PJ_ASSERT_RETURN((param->flags & PJMEDIA_AUD_DEV_CAP_EXT_FORMAT)==0 ||
907
 
                     param->ext_fmt.id == PJMEDIA_FORMAT_L16,
908
 
                     PJ_ENOTSUP);
909
 
    
 
924
    PJ_ASSERT_RETURN (param->bits_per_sample == BITS_PER_SAMPLE, PJ_EINVAL);
 
925
    PJ_ASSERT_RETURN ( (param->flags & PJMEDIA_AUD_DEV_CAP_EXT_FORMAT) ==0 ||
 
926
                       param->ext_fmt.id == PJMEDIA_FORMAT_L16,
 
927
                       PJ_ENOTSUP);
 
928
 
910
929
    /* It seems that MDA recorder only supports for mono channel. */
911
 
    PJ_ASSERT_RETURN(param->channel_count == 1, PJ_EINVAL);
 
930
    PJ_ASSERT_RETURN (param->channel_count == 1, PJ_EINVAL);
912
931
 
913
932
    /* Create and Initialize stream descriptor */
914
 
    pool = pj_pool_create(mf->pf, "symb_aud_dev", 1000, 1000, NULL);
915
 
    PJ_ASSERT_RETURN(pool, PJ_ENOMEM);
 
933
    pool = pj_pool_create (mf->pf, "symb_aud_dev", 1000, 1000, NULL);
 
934
    PJ_ASSERT_RETURN (pool, PJ_ENOMEM);
916
935
 
917
 
    strm = PJ_POOL_ZALLOC_T(pool, struct mda_stream);
 
936
    strm = PJ_POOL_ZALLOC_T (pool, struct mda_stream);
918
937
    strm->pool = pool;
919
938
    strm->param = *param;
920
939
 
921
940
    // Create the output stream.
922
941
    if (strm->param.dir & PJMEDIA_DIR_PLAYBACK) {
923
 
        TRAPD(err, strm->out_engine = CPjAudioOutputEngine::NewL(strm, play_cb,
924
 
                                                                 user_data));
925
 
        if (err != KErrNone) {
926
 
            pj_pool_release(pool);      
927
 
            return PJ_RETURN_OS_ERROR(err);
928
 
        }
 
942
        TRAPD (err, strm->out_engine = CPjAudioOutputEngine::NewL (strm, play_cb,
 
943
                                       user_data));
 
944
 
 
945
        if (err != KErrNone) {
 
946
            pj_pool_release (pool);
 
947
            return PJ_RETURN_OS_ERROR (err);
 
948
        }
929
949
    }
930
950
 
931
951
    // Create the input stream.
932
952
    if (strm->param.dir & PJMEDIA_DIR_CAPTURE) {
933
 
        TRAPD(err, strm->in_engine = CPjAudioInputEngine::NewL(strm, rec_cb, 
934
 
                                                               user_data));
935
 
        if (err != KErrNone) {
936
 
            strm->in_engine = NULL;
937
 
            delete strm->out_engine;
938
 
            strm->out_engine = NULL;
939
 
            pj_pool_release(pool);      
940
 
            return PJ_RETURN_OS_ERROR(err);
941
 
        }
 
953
        TRAPD (err, strm->in_engine = CPjAudioInputEngine::NewL (strm, rec_cb,
 
954
                                      user_data));
 
955
 
 
956
        if (err != KErrNone) {
 
957
            strm->in_engine = NULL;
 
958
            delete strm->out_engine;
 
959
            strm->out_engine = NULL;
 
960
            pj_pool_release (pool);
 
961
            return PJ_RETURN_OS_ERROR (err);
 
962
        }
942
963
    }
943
 
        
 
964
 
944
965
    /* Done */
945
966
    strm->base.op = &stream_op;
946
967
    *p_aud_strm = &strm->base;
949
970
}
950
971
 
951
972
/* API: Get stream info. */
952
 
static pj_status_t stream_get_param(pjmedia_aud_stream *s,
953
 
                                    pjmedia_aud_param *pi)
 
973
static pj_status_t stream_get_param (pjmedia_aud_stream *s,
 
974
                                     pjmedia_aud_param *pi)
954
975
{
955
 
    struct mda_stream *strm = (struct mda_stream*)s;
956
 
 
957
 
    PJ_ASSERT_RETURN(strm && pi, PJ_EINVAL);
958
 
 
959
 
    pj_memcpy(pi, &strm->param, sizeof(*pi));
960
 
    
 
976
    struct mda_stream *strm = (struct mda_stream*) s;
 
977
 
 
978
    PJ_ASSERT_RETURN (strm && pi, PJ_EINVAL);
 
979
 
 
980
    pj_memcpy (pi, &strm->param, sizeof (*pi));
 
981
 
961
982
    return PJ_SUCCESS;
962
983
}
963
984
 
964
985
/* API: get capability */
965
 
static pj_status_t stream_get_cap(pjmedia_aud_stream *s,
966
 
                                  pjmedia_aud_dev_cap cap,
967
 
                                  void *pval)
 
986
static pj_status_t stream_get_cap (pjmedia_aud_stream *s,
 
987
                                   pjmedia_aud_dev_cap cap,
 
988
                                   void *pval)
968
989
{
969
 
    struct mda_stream *strm = (struct mda_stream*)s;
 
990
    struct mda_stream *strm = (struct mda_stream*) s;
970
991
    pj_status_t status = PJ_ENOTSUP;
971
992
 
972
 
    PJ_ASSERT_RETURN(s && pval, PJ_EINVAL);
 
993
    PJ_ASSERT_RETURN (s && pval, PJ_EINVAL);
973
994
 
974
995
    switch (cap) {
975
 
    case PJMEDIA_AUD_DEV_CAP_INPUT_VOLUME_SETTING:
976
 
        if (strm->param.dir & PJMEDIA_DIR_CAPTURE) {
977
 
            PJ_ASSERT_RETURN(strm->in_engine, PJ_EINVAL);
978
 
            
979
 
            TInt max_gain = strm->in_engine->GetMaxGain();
980
 
            TInt gain = strm->in_engine->GetGain();
981
 
            
982
 
            if (max_gain > 0 && gain >= 0) {
983
 
                *(unsigned*)pval = gain * 100 / max_gain; 
984
 
                status = PJ_SUCCESS;
985
 
            } else {
986
 
                status = PJMEDIA_EAUD_NOTREADY;
987
 
            }
988
 
        }
989
 
        break;
990
 
    case PJMEDIA_AUD_DEV_CAP_OUTPUT_VOLUME_SETTING:
991
 
        if (strm->param.dir & PJMEDIA_DIR_PLAYBACK) {
992
 
            PJ_ASSERT_RETURN(strm->out_engine, PJ_EINVAL);
993
 
            
994
 
            TInt max_vol = strm->out_engine->GetMaxVolume();
995
 
            TInt vol = strm->out_engine->GetVolume();
996
 
            
997
 
            if (max_vol > 0 && vol >= 0) {
998
 
                *(unsigned*)pval = vol * 100 / max_vol; 
999
 
                status = PJ_SUCCESS;
1000
 
            } else {
1001
 
                status = PJMEDIA_EAUD_NOTREADY;
1002
 
            }
1003
 
        }
1004
 
        break;
1005
 
    default:
1006
 
        break;
 
996
        case PJMEDIA_AUD_DEV_CAP_INPUT_VOLUME_SETTING:
 
997
 
 
998
            if (strm->param.dir & PJMEDIA_DIR_CAPTURE) {
 
999
                PJ_ASSERT_RETURN (strm->in_engine, PJ_EINVAL);
 
1000
 
 
1001
                TInt max_gain = strm->in_engine->GetMaxGain();
 
1002
                TInt gain = strm->in_engine->GetGain();
 
1003
 
 
1004
                if (max_gain > 0 && gain >= 0) {
 
1005
                    * (unsigned*) pval = gain * 100 / max_gain;
 
1006
                    status = PJ_SUCCESS;
 
1007
                } else {
 
1008
                    status = PJMEDIA_EAUD_NOTREADY;
 
1009
                }
 
1010
            }
 
1011
 
 
1012
            break;
 
1013
        case PJMEDIA_AUD_DEV_CAP_OUTPUT_VOLUME_SETTING:
 
1014
 
 
1015
            if (strm->param.dir & PJMEDIA_DIR_PLAYBACK) {
 
1016
                PJ_ASSERT_RETURN (strm->out_engine, PJ_EINVAL);
 
1017
 
 
1018
                TInt max_vol = strm->out_engine->GetMaxVolume();
 
1019
                TInt vol = strm->out_engine->GetVolume();
 
1020
 
 
1021
                if (max_vol > 0 && vol >= 0) {
 
1022
                    * (unsigned*) pval = vol * 100 / max_vol;
 
1023
                    status = PJ_SUCCESS;
 
1024
                } else {
 
1025
                    status = PJMEDIA_EAUD_NOTREADY;
 
1026
                }
 
1027
            }
 
1028
 
 
1029
            break;
 
1030
        default:
 
1031
            break;
1007
1032
    }
1008
 
    
 
1033
 
1009
1034
    return status;
1010
1035
}
1011
1036
 
1012
1037
/* API: set capability */
1013
 
static pj_status_t stream_set_cap(pjmedia_aud_stream *s,
1014
 
                                  pjmedia_aud_dev_cap cap,
1015
 
                                  const void *pval)
 
1038
static pj_status_t stream_set_cap (pjmedia_aud_stream *s,
 
1039
                                   pjmedia_aud_dev_cap cap,
 
1040
                                   const void *pval)
1016
1041
{
1017
 
    struct mda_stream *strm = (struct mda_stream*)s;
 
1042
    struct mda_stream *strm = (struct mda_stream*) s;
1018
1043
    pj_status_t status = PJ_ENOTSUP;
1019
1044
 
1020
 
    PJ_ASSERT_RETURN(s && pval, PJ_EINVAL);
 
1045
    PJ_ASSERT_RETURN (s && pval, PJ_EINVAL);
1021
1046
 
1022
1047
    switch (cap) {
1023
 
    case PJMEDIA_AUD_DEV_CAP_INPUT_VOLUME_SETTING:
1024
 
        if (strm->param.dir & PJMEDIA_DIR_CAPTURE) {
1025
 
            PJ_ASSERT_RETURN(strm->in_engine, PJ_EINVAL);
1026
 
            
1027
 
            TInt max_gain = strm->in_engine->GetMaxGain();
1028
 
            if (max_gain > 0) {
1029
 
                TInt gain;
1030
 
                
1031
 
                gain = *(unsigned*)pval * max_gain / 100;
1032
 
                status = strm->in_engine->SetGain(gain);
1033
 
            } else {
1034
 
                status = PJMEDIA_EAUD_NOTREADY;
1035
 
            }
1036
 
        }
1037
 
        break;
1038
 
    case PJMEDIA_AUD_DEV_CAP_OUTPUT_VOLUME_SETTING:
1039
 
        if (strm->param.dir & PJMEDIA_DIR_CAPTURE) {
1040
 
            PJ_ASSERT_RETURN(strm->out_engine, PJ_EINVAL);
1041
 
            
1042
 
            TInt max_vol = strm->out_engine->GetMaxVolume();
1043
 
            if (max_vol > 0) {
1044
 
                TInt vol;
1045
 
                
1046
 
                vol = *(unsigned*)pval * max_vol / 100;
1047
 
                status = strm->out_engine->SetVolume(vol);
1048
 
            } else {
1049
 
                status = PJMEDIA_EAUD_NOTREADY;
1050
 
            }
1051
 
        }
1052
 
        break;
1053
 
    default:
1054
 
        break;
 
1048
        case PJMEDIA_AUD_DEV_CAP_INPUT_VOLUME_SETTING:
 
1049
 
 
1050
            if (strm->param.dir & PJMEDIA_DIR_CAPTURE) {
 
1051
                PJ_ASSERT_RETURN (strm->in_engine, PJ_EINVAL);
 
1052
 
 
1053
                TInt max_gain = strm->in_engine->GetMaxGain();
 
1054
 
 
1055
                if (max_gain > 0) {
 
1056
                    TInt gain;
 
1057
 
 
1058
                    gain = * (unsigned*) pval * max_gain / 100;
 
1059
                    status = strm->in_engine->SetGain (gain);
 
1060
                } else {
 
1061
                    status = PJMEDIA_EAUD_NOTREADY;
 
1062
                }
 
1063
            }
 
1064
 
 
1065
            break;
 
1066
        case PJMEDIA_AUD_DEV_CAP_OUTPUT_VOLUME_SETTING:
 
1067
 
 
1068
            if (strm->param.dir & PJMEDIA_DIR_CAPTURE) {
 
1069
                PJ_ASSERT_RETURN (strm->out_engine, PJ_EINVAL);
 
1070
 
 
1071
                TInt max_vol = strm->out_engine->GetMaxVolume();
 
1072
 
 
1073
                if (max_vol > 0) {
 
1074
                    TInt vol;
 
1075
 
 
1076
                    vol = * (unsigned*) pval * max_vol / 100;
 
1077
                    status = strm->out_engine->SetVolume (vol);
 
1078
                } else {
 
1079
                    status = PJMEDIA_EAUD_NOTREADY;
 
1080
                }
 
1081
            }
 
1082
 
 
1083
            break;
 
1084
        default:
 
1085
            break;
1055
1086
    }
1056
 
    
 
1087
 
1057
1088
    return status;
1058
1089
}
1059
1090
 
1060
1091
/* API: Start stream. */
1061
 
static pj_status_t stream_start(pjmedia_aud_stream *strm)
 
1092
static pj_status_t stream_start (pjmedia_aud_stream *strm)
1062
1093
{
1063
 
    struct mda_stream *stream = (struct mda_stream*)strm;
 
1094
    struct mda_stream *stream = (struct mda_stream*) strm;
1064
1095
 
1065
 
    PJ_ASSERT_RETURN(stream, PJ_EINVAL);
 
1096
    PJ_ASSERT_RETURN (stream, PJ_EINVAL);
1066
1097
 
1067
1098
    if (stream->out_engine) {
1068
 
        pj_status_t status;
1069
 
        status = stream->out_engine->StartPlay();
1070
 
        if (status != PJ_SUCCESS)
1071
 
            return status;
 
1099
        pj_status_t status;
 
1100
        status = stream->out_engine->StartPlay();
 
1101
 
 
1102
        if (status != PJ_SUCCESS)
 
1103
            return status;
1072
1104
    }
1073
 
    
 
1105
 
1074
1106
    if (stream->in_engine) {
1075
 
        pj_status_t status;
1076
 
        status = stream->in_engine->StartRecord();
1077
 
        if (status != PJ_SUCCESS)
1078
 
            return status;
 
1107
        pj_status_t status;
 
1108
        status = stream->in_engine->StartRecord();
 
1109
 
 
1110
        if (status != PJ_SUCCESS)
 
1111
            return status;
1079
1112
    }
1080
1113
 
1081
1114
    return PJ_SUCCESS;
1082
1115
}
1083
1116
 
1084
1117
/* API: Stop stream. */
1085
 
static pj_status_t stream_stop(pjmedia_aud_stream *strm)
 
1118
static pj_status_t stream_stop (pjmedia_aud_stream *strm)
1086
1119
{
1087
 
    struct mda_stream *stream = (struct mda_stream*)strm;
 
1120
    struct mda_stream *stream = (struct mda_stream*) strm;
1088
1121
 
1089
 
    PJ_ASSERT_RETURN(stream, PJ_EINVAL);
 
1122
    PJ_ASSERT_RETURN (stream, PJ_EINVAL);
1090
1123
 
1091
1124
    if (stream->in_engine) {
1092
 
        stream->in_engine->Stop();
 
1125
        stream->in_engine->Stop();
1093
1126
    }
1094
 
        
 
1127
 
1095
1128
    if (stream->out_engine) {
1096
 
        stream->out_engine->Stop();
 
1129
        stream->out_engine->Stop();
1097
1130
    }
1098
1131
 
1099
1132
    return PJ_SUCCESS;
1101
1134
 
1102
1135
 
1103
1136
/* API: Destroy stream. */
1104
 
static pj_status_t stream_destroy(pjmedia_aud_stream *strm)
 
1137
static pj_status_t stream_destroy (pjmedia_aud_stream *strm)
1105
1138
{
1106
 
    struct mda_stream *stream = (struct mda_stream*)strm;
1107
 
 
1108
 
    PJ_ASSERT_RETURN(stream, PJ_EINVAL);
1109
 
 
1110
 
    stream_stop(strm);
 
1139
    struct mda_stream *stream = (struct mda_stream*) strm;
 
1140
 
 
1141
    PJ_ASSERT_RETURN (stream, PJ_EINVAL);
 
1142
 
 
1143
    stream_stop (strm);
1111
1144
 
1112
1145
    delete stream->in_engine;
1113
1146
    stream->in_engine = NULL;
1117
1150
 
1118
1151
    pj_pool_t *pool;
1119
1152
    pool = stream->pool;
 
1153
 
1120
1154
    if (pool) {
1121
 
        stream->pool = NULL;
1122
 
        pj_pool_release(pool);
 
1155
        stream->pool = NULL;
 
1156
        pj_pool_release (pool);
1123
1157
    }
1124
1158
 
1125
1159
    return PJ_SUCCESS;