~ubuntu-branches/ubuntu/trusty/sflphone/trusty

« back to all changes in this revision

Viewing changes to daemon/src/audio/opensl/opensllayer.cpp

  • Committer: Package Import Robot
  • Author(s): Mark Purcell
  • Date: 2014-01-28 18:23:36 UTC
  • mfrom: (4.3.4 sid)
  • Revision ID: package-import@ubuntu.com-20140128182336-jrsv0k9u6cawc068
Tags: 1.3.0-1
* New upstream release 
  - Fixes "New Upstream Release" (Closes: #735846)
  - Fixes "Ringtone does not stop" (Closes: #727164)
  - Fixes "[sflphone-kde] crash on startup" (Closes: #718178)
  - Fixes "sflphone GUI crashes when call is hung up" (Closes: #736583)
* Build-Depends: ensure GnuTLS 2.6
  - libucommon-dev (>= 6.0.7-1.1), libccrtp-dev (>= 2.0.6-3)
  - Fixes "FTBFS Build-Depends libgnutls{26,28}-dev" (Closes: #722040)
* Fix "boost 1.49 is going away" unversioned Build-Depends: (Closes: #736746)
* Add Build-Depends: libsndfile-dev, nepomuk-core-dev

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *  Copyright (C) 2004, 2005, 2006, 2008, 2009, 2010, 2011 Savoir-Faire Linux Inc.
 
3
 *  Author: Alexandre Savard <alexandre.savard@savoirfairelinux.com>
 
4
 *
 
5
 *  This program is free software; you can redistribute it and/or modify
 
6
 *  it under the terms of the GNU General Public License as published by
 
7
 *  the Free Software Foundation; either version 3 of the License, or
 
8
 *  (at your option) any later version.
 
9
 *
 
10
 *  This program is distributed in the hope that it will be useful,
 
11
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
13
 *  GNU General Public License for more details.
 
14
 *
 
15
 *  You should have received a copy of the GNU General Public License
 
16
 *  along with this program; if not, write to the Free Software
 
17
 *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
18
 *
 
19
 *  Additional permission under GNU GPL version 3 section 7:
 
20
 *
 
21
 *  If you modify this program, or any covered work, by linking or
 
22
 *  combining it with the OpenSSL project's OpenSSL library (or a
 
23
 *  modified version of that library), containing parts covered by the
 
24
 *  terms of the OpenSSL or SSLeay licenses, Savoir-Faire Linux Inc.
 
25
 *  grants you additional permission to convey the resulting work.
 
26
 *  Corresponding Source for a non-source form of such a combination
 
27
 *  shall include the source code for the parts of OpenSSL used as well
 
28
 *  as that of the covered work.
 
29
 */
 
30
 
 
31
#include <cstdio>
 
32
#include <cassert>
 
33
#include <unistd.h>
 
34
 
 
35
#include "logger.h"
 
36
#include "array_size.h"
 
37
#include "manager.h"
 
38
#include "mainbuffer.h"
 
39
#include "audio/dcblocker.h"
 
40
 
 
41
#include "opensllayer.h"
 
42
 
 
43
const int OpenSLLayer::NB_BUFFER_PLAYBACK_QUEUE = ANDROID_BUFFER_QUEUE_LENGTH;
 
44
const int OpenSLLayer::NB_BUFFER_CAPTURE_QUEUE = ANDROID_BUFFER_QUEUE_LENGTH;
 
45
 
 
46
class OpenSLThread {
 
47
    public:
 
48
        OpenSLThread(OpenSLLayer *opensl);
 
49
        ~OpenSLThread();
 
50
        void initAudioLayer();
 
51
        void start();
 
52
        bool isRunning() const;
 
53
 
 
54
    private:
 
55
        void run();
 
56
        static void *runCallback(void *context);
 
57
 
 
58
        NON_COPYABLE(OpenSLThread);
 
59
        pthread_t thread_;
 
60
        OpenSLLayer* opensl_;
 
61
        bool running_;
 
62
};
 
63
 
 
64
OpenSLThread::OpenSLThread(OpenSLLayer *opensl)
 
65
    : thread_(0), opensl_(opensl), running_(false)
 
66
{}
 
67
 
 
68
bool
 
69
OpenSLThread::isRunning() const
 
70
{
 
71
    return running_;
 
72
}
 
73
 
 
74
OpenSLThread::~OpenSLThread()
 
75
{
 
76
    running_ = false;
 
77
    opensl_->shutdownAudioEngine();
 
78
 
 
79
    if (thread_)
 
80
        pthread_join(thread_, nullptr);
 
81
}
 
82
 
 
83
void
 
84
OpenSLThread::start()
 
85
{
 
86
    running_ = true;
 
87
    pthread_create(&thread_, nullptr, &runCallback, this);
 
88
}
 
89
 
 
90
void *
 
91
OpenSLThread::runCallback(void *data)
 
92
{
 
93
    OpenSLThread *context = static_cast<OpenSLThread*>(data);
 
94
    context->run();
 
95
    return nullptr;
 
96
}
 
97
 
 
98
void
 
99
OpenSLThread::initAudioLayer()
 
100
{
 
101
    opensl_->initAudioEngine();
 
102
    opensl_->initAudioPlayback();
 
103
    opensl_->initAudioCapture();
 
104
 
 
105
    opensl_->flushMain();
 
106
    opensl_->flushUrgent();
 
107
}
 
108
 
 
109
/**
 
110
 * Reimplementation of run()
 
111
 */
 
112
void
 
113
OpenSLThread::run()
 
114
{
 
115
    initAudioLayer();
 
116
 
 
117
    opensl_->startAudioPlayback();
 
118
    opensl_->startAudioCapture();
 
119
    opensl_->isStarted_ = true;
 
120
 
 
121
    while (opensl_->isStarted_)
 
122
        usleep(20000); // 20 ms
 
123
}
 
124
 
 
125
// Constructor
 
126
OpenSLLayer::OpenSLLayer(const AudioPreference &pref)
 
127
    : AudioLayer(pref)
 
128
    , indexIn_(0)
 
129
    , indexOut_(0)
 
130
    , indexRing_(0)
 
131
    , audioThread_(0)
 
132
    , engineObject_(0)
 
133
    , engineInterface_(0)
 
134
    , outputMixer_(0)
 
135
    , playerObject_(0)
 
136
    , recorderObject_(0)
 
137
    , playerInterface_(0)
 
138
    , recorderInterface_(0)
 
139
    , playbackBufferQueue_(0)
 
140
    , recorderBufferQueue_(0)
 
141
    , playbackBufferIndex_(0)
 
142
    , recordBufferIndex_(0)
 
143
    , playbackBufferStack_(ANDROID_BUFFER_QUEUE_LENGTH, AudioBuffer(BUFFER_SIZE, 1, 8000))
 
144
    , recordBufferStack_(ANDROID_BUFFER_QUEUE_LENGTH, AudioBuffer(BUFFER_SIZE, 1, 8000))
 
145
{
 
146
}
 
147
 
 
148
// Destructor
 
149
OpenSLLayer::~OpenSLLayer()
 
150
{
 
151
    isStarted_ = false;
 
152
    delete audioThread_;
 
153
 
 
154
    /* Then close the audio devices */
 
155
    stopAudioPlayback();
 
156
    stopAudioCapture();
 
157
}
 
158
 
 
159
void
 
160
OpenSLLayer::startStream()
 
161
{
 
162
    dcblocker_.reset();
 
163
 
 
164
    if (isStarted_)
 
165
        return;
 
166
 
 
167
    DEBUG("Start OpenSL audio layer");
 
168
 
 
169
    if (audioThread_ == nullptr) {
 
170
        audioThread_ = new OpenSLThread(this);
 
171
        audioThread_->start();
 
172
    } else if (!audioThread_->isRunning()) {
 
173
        audioThread_->start();
 
174
    }
 
175
 
 
176
}
 
177
 
 
178
void
 
179
OpenSLLayer::stopStream()
 
180
{
 
181
    if (not isStarted_)
 
182
        return;
 
183
 
 
184
    DEBUG("Stop OpenSL audio layer");
 
185
 
 
186
    stopAudioPlayback();
 
187
    stopAudioCapture();
 
188
 
 
189
    isStarted_ = false;
 
190
 
 
191
    delete audioThread_;
 
192
    audioThread_ = nullptr;
 
193
 
 
194
    flushMain();
 
195
    flushUrgent();
 
196
}
 
197
 
 
198
void
 
199
OpenSLLayer::initAudioEngine()
 
200
{
 
201
    SLresult result;
 
202
 
 
203
    DEBUG("Create Audio Engine\n");
 
204
    result = slCreateEngine(&engineObject_, 0, nullptr, 0, nullptr, nullptr);
 
205
    assert(SL_RESULT_SUCCESS == result);
 
206
 
 
207
    DEBUG("Realize Audio Engine\n");
 
208
    result = (*engineObject_)->Realize(engineObject_, SL_BOOLEAN_FALSE);
 
209
    assert(SL_RESULT_SUCCESS == result);
 
210
 
 
211
    DEBUG("Create Audio Engine Interface\n");
 
212
    result = (*engineObject_)->GetInterface(engineObject_, SL_IID_ENGINE, &engineInterface_);
 
213
    assert(SL_RESULT_SUCCESS == result);
 
214
 
 
215
    DEBUG("Create Output Mixer\n");
 
216
    result = (*engineInterface_)->CreateOutputMix(engineInterface_, &outputMixer_, 0, nullptr, nullptr);
 
217
    assert(SL_RESULT_SUCCESS == result);
 
218
 
 
219
    DEBUG("Realize Output Mixer\n");
 
220
    result = (*outputMixer_)->Realize(outputMixer_, SL_BOOLEAN_FALSE);
 
221
    assert(SL_RESULT_SUCCESS == result);
 
222
 
 
223
    DEBUG("Audio Engine Initialization Done\n");
 
224
}
 
225
 
 
226
void
 
227
OpenSLLayer::shutdownAudioEngine()
 
228
{
 
229
 
 
230
    // destroy buffer queue audio player object, and invalidate all associated interfaces
 
231
    DEBUG("Shutdown audio player\n");
 
232
 
 
233
    if (playerObject_ != nullptr) {
 
234
        (*playerObject_)->Destroy(playerObject_);
 
235
        playerObject_ = nullptr;
 
236
        playerInterface_ = nullptr;
 
237
        playbackBufferQueue_ = nullptr;
 
238
    }
 
239
 
 
240
    // destroy output mix object, and invalidate all associated interfaces
 
241
    DEBUG("Shutdown audio mixer\n");
 
242
 
 
243
    if (outputMixer_ != nullptr) {
 
244
        (*outputMixer_)->Destroy(outputMixer_);
 
245
        outputMixer_ = nullptr;
 
246
    }
 
247
 
 
248
        if(recorderObject_ != nullptr){
 
249
                (*recorderObject_)->Destroy(recorderObject_);
 
250
                recorderObject_ = nullptr;
 
251
                recorderInterface_ = nullptr;
 
252
                recorderBufferQueue_ = nullptr;
 
253
        }
 
254
 
 
255
    // destroy engine object, and invalidate all associated interfaces
 
256
    DEBUG("Shutdown audio engine\n");
 
257
    if (engineObject_ != nullptr) {
 
258
        (*engineObject_)->Destroy(engineObject_);
 
259
        engineObject_ = nullptr;
 
260
        engineInterface_ = nullptr;
 
261
    }
 
262
}
 
263
 
 
264
void
 
265
OpenSLLayer::initAudioPlayback()
 
266
{
 
267
    assert(nullptr != engineObject_);
 
268
    assert(nullptr != engineInterface_);
 
269
    assert(nullptr != outputMixer_);
 
270
 
 
271
    SLresult result;
 
272
 
 
273
    // Initialize the location of the buffer queue
 
274
    DEBUG("Create playback queue\n");
 
275
    SLDataLocator_AndroidSimpleBufferQueue bufferLocation = {SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE,
 
276
                                                            NB_BUFFER_PLAYBACK_QUEUE
 
277
                                                            };
 
278
 
 
279
    // Initnialize the audio format for this queue
 
280
    DEBUG("Setting audio format\n");
 
281
    SLDataFormat_PCM audioFormat = {SL_DATAFORMAT_PCM,
 
282
                                    1,
 
283
                                    sampleRate_ * 1000,
 
284
                                    SL_PCMSAMPLEFORMAT_FIXED_16,
 
285
                                    SL_PCMSAMPLEFORMAT_FIXED_16,
 
286
                                    SL_SPEAKER_FRONT_CENTER,
 
287
                                    SL_BYTEORDER_LITTLEENDIAN
 
288
                                   };
 
289
 
 
290
    // Create the audio source
 
291
    DEBUG("Set Audio Sources\n");
 
292
    SLDataSource audioSource = {&bufferLocation, &audioFormat};
 
293
 
 
294
    DEBUG("Get Output Mixer interface\n");
 
295
    result = (*outputMixer_)->GetInterface(outputMixer_, SL_IID_OUTPUTMIX, &outputMixInterface_);
 
296
    CheckErr(result);
 
297
 
 
298
    // Cofiguration fo the audio sink as an output mixer
 
299
    DEBUG("Set output mixer location\n");
 
300
    SLDataLocator_OutputMix mixerLocation = {SL_DATALOCATOR_OUTPUTMIX, outputMixer_};
 
301
    SLDataSink audioSink = {&mixerLocation, nullptr};
 
302
 
 
303
    const SLInterfaceID ids[] = {SL_IID_ANDROIDSIMPLEBUFFERQUEUE,
 
304
                                SL_IID_VOLUME,
 
305
                                SL_IID_ANDROIDCONFIGURATION,
 
306
                                SL_IID_PLAY
 
307
                                };
 
308
    const SLboolean req[] = {SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE};
 
309
 
 
310
    const unsigned nbInterface = ARRAYSIZE(ids);
 
311
 
 
312
    // create audio player
 
313
    DEBUG("Create audio player\n");
 
314
    result = (*engineInterface_)->CreateAudioPlayer(engineInterface_, &playerObject_, &audioSource, &audioSink, nbInterface, ids, req);
 
315
    assert(SL_RESULT_SUCCESS == result);
 
316
 
 
317
    SLAndroidConfigurationItf playerConfig;
 
318
    SLint32 streamType = SL_ANDROID_STREAM_VOICE;
 
319
 
 
320
 
 
321
    result = (*playerObject_)->GetInterface(playerObject_,
 
322
                                            SL_IID_ANDROIDCONFIGURATION,
 
323
                                            &playerConfig);
 
324
 
 
325
    if (result == SL_RESULT_SUCCESS && playerConfig) {
 
326
        result = (*playerConfig)->SetConfiguration(
 
327
                     playerConfig, SL_ANDROID_KEY_STREAM_TYPE,
 
328
                     &streamType, sizeof(SLint32));
 
329
    }
 
330
 
 
331
        DEBUG("Realize audio player\n");
 
332
    result = (*playerObject_)->Realize(playerObject_, SL_BOOLEAN_FALSE);
 
333
    assert(SL_RESULT_SUCCESS == result);
 
334
 
 
335
    if (result != SL_RESULT_SUCCESS) {
 
336
        ERROR("Unable to set android player configuration");
 
337
    }
 
338
 
 
339
    // create audio interface
 
340
    DEBUG("Create audio player interface\n");
 
341
    result = (*playerObject_)->GetInterface(playerObject_, SL_IID_PLAY, &playerInterface_);
 
342
    assert(SL_RESULT_SUCCESS == result);
 
343
 
 
344
    // create the buffer queue interface
 
345
    DEBUG("Create buffer queue interface\n");
 
346
    result = (*playerObject_)->GetInterface(playerObject_, SL_IID_BUFFERQUEUE, &playbackBufferQueue_);
 
347
    assert(SL_RESULT_SUCCESS == result);
 
348
 
 
349
    // register the buffer queue on the buffer object
 
350
    DEBUG("Register audio callback\n");
 
351
    result = (*playbackBufferQueue_)->RegisterCallback(playbackBufferQueue_, audioPlaybackCallback, this);
 
352
    assert(SL_RESULT_SUCCESS == result);
 
353
 
 
354
    DEBUG("Audio Playback Initialization Done\n");
 
355
}
 
356
 
 
357
void
 
358
OpenSLLayer::initAudioCapture()
 
359
{
 
360
    SLresult result;
 
361
 
 
362
    // configure audio source
 
363
    DEBUG("Configure audio source\n");
 
364
    SLDataLocator_IODevice deviceLocator = {SL_DATALOCATOR_IODEVICE,
 
365
                                            SL_IODEVICE_AUDIOINPUT,
 
366
                                            SL_DEFAULTDEVICEID_AUDIOINPUT,
 
367
                                            nullptr
 
368
                                           };
 
369
 
 
370
    SLDataSource audioSource = {&deviceLocator,
 
371
                                nullptr
 
372
                               };
 
373
 
 
374
    // configure audio sink
 
375
    DEBUG("Configure audio sink\n");
 
376
 
 
377
    SLDataLocator_AndroidSimpleBufferQueue bufferLocator = {SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE,
 
378
                                           NB_BUFFER_CAPTURE_QUEUE
 
379
                                                           };
 
380
 
 
381
        DEBUG("Capture-> Sampling Rate: %d", sampleRate_);
 
382
        DEBUG("Capture-> getInternalSamplingRate: %d", Manager::instance().getMainBuffer().getInternalSamplingRate());
 
383
    SLDataFormat_PCM audioFormat = {SL_DATAFORMAT_PCM, 1,
 
384
                                    sampleRate_ * 1000,
 
385
                                    SL_PCMSAMPLEFORMAT_FIXED_16,
 
386
                                    SL_PCMSAMPLEFORMAT_FIXED_16,
 
387
                                    SL_SPEAKER_FRONT_CENTER,
 
388
                                    SL_BYTEORDER_LITTLEENDIAN
 
389
                                   };
 
390
 
 
391
    SLDataSink audioSink = {&bufferLocator,
 
392
                            &audioFormat
 
393
                           };
 
394
 
 
395
    // create audio recorder
 
396
    // (requires the RECORD_AUDIO permission)
 
397
    DEBUG("Create audio recorder\n");
 
398
    const SLInterfaceID id[] = {SL_IID_ANDROIDSIMPLEBUFFERQUEUE};
 
399
    const SLboolean req[] = {SL_BOOLEAN_TRUE};
 
400
 
 
401
    if (engineInterface_ != nullptr) {
 
402
        result = (*engineInterface_)->CreateAudioRecorder(engineInterface_,
 
403
                 &recorderObject_, &audioSource, &audioSink, 1, id, req);
 
404
    }
 
405
 
 
406
    if (SL_RESULT_SUCCESS != result) {
 
407
        DEBUG("Error: could not create audio recorder");
 
408
        return;
 
409
    }
 
410
 
 
411
    // realize the audio recorder
 
412
    DEBUG("Realize the audio recorder\n");
 
413
    result = (*recorderObject_)->Realize(recorderObject_, SL_BOOLEAN_FALSE);
 
414
 
 
415
    if (SL_RESULT_SUCCESS != result) {
 
416
        DEBUG("Error: could not realize audio recorder");
 
417
        return;
 
418
    }
 
419
 
 
420
    // get the record interface
 
421
    DEBUG("Create the record interface\n");
 
422
    result = (*recorderObject_)->GetInterface(recorderObject_, SL_IID_RECORD, &recorderInterface_);
 
423
    assert(SL_RESULT_SUCCESS == result);
 
424
 
 
425
    // get the buffer queue interface
 
426
    DEBUG("Create the buffer queue interface\n");
 
427
    result = (*recorderObject_)->GetInterface(recorderObject_, SL_IID_ANDROIDSIMPLEBUFFERQUEUE,
 
428
             &recorderBufferQueue_);
 
429
    assert(SL_RESULT_SUCCESS == result);
 
430
 
 
431
    // register callback on the buffer queue
 
432
    DEBUG("Register the audio capture callback\n");
 
433
    result = (*recorderBufferQueue_)->RegisterCallback(recorderBufferQueue_, audioCaptureCallback, this);
 
434
    assert(SL_RESULT_SUCCESS == result);
 
435
 
 
436
    DEBUG("Audio capture initialized\n");
 
437
}
 
438
 
 
439
 
 
440
void
 
441
OpenSLLayer::startAudioPlayback()
 
442
{
 
443
    assert(nullptr != playbackBufferQueue_);
 
444
 
 
445
    DEBUG("Start audio playback\n");
 
446
 
 
447
    SLresult result;
 
448
 
 
449
    for (int i = 0; i < NB_BUFFER_PLAYBACK_QUEUE; i++) {
 
450
        AudioBuffer &buffer = getNextPlaybackBuffer();
 
451
        incrementPlaybackIndex();
 
452
 
 
453
        buffer.reset();
 
454
 
 
455
        result = (*playbackBufferQueue_)->Enqueue(playbackBufferQueue_, buffer.getChannel(0)->data(), buffer.frames());
 
456
 
 
457
        if (SL_RESULT_SUCCESS != result) {
 
458
            DEBUG("Error could not enqueue initial buffers\n");
 
459
        }
 
460
    }
 
461
 
 
462
    result = (*playerInterface_)->SetPlayState(playerInterface_, SL_PLAYSTATE_PLAYING);
 
463
    assert(SL_RESULT_SUCCESS == result);
 
464
 
 
465
    DEBUG("Audio playback started\n");
 
466
}
 
467
 
 
468
void
 
469
OpenSLLayer::startAudioCapture()
 
470
{
 
471
    assert(nullptr != playbackBufferQueue_);
 
472
 
 
473
    DEBUG("Start audio capture\n");
 
474
 
 
475
    SLresult result;
 
476
 
 
477
 
 
478
    // in case already recording, stop recording and clear buffer queue
 
479
    if (recorderInterface_ != nullptr) {
 
480
        result = (*recorderInterface_)->SetRecordState(recorderInterface_, SL_RECORDSTATE_STOPPED);
 
481
        assert(SL_RESULT_SUCCESS == result);
 
482
    }
 
483
 
 
484
    DEBUG("Clearing recorderBufferQueue\n");
 
485
    result = (*recorderBufferQueue_)->Clear(recorderBufferQueue_);
 
486
    assert(SL_RESULT_SUCCESS == result);
 
487
 
 
488
    DEBUG("getting next record buffer\n");
 
489
    // enqueue an empty buffer to be filled by the recorder
 
490
    // (for streaming recording, we enqueue at least 2 empty buffers to start things off)
 
491
    AudioBuffer &buffer = getNextRecordBuffer();
 
492
    incrementRecordIndex();
 
493
 
 
494
    buffer.reset();
 
495
 
 
496
    DEBUG("Enqueue record buffer\n");
 
497
    result = (*recorderBufferQueue_)->Enqueue(recorderBufferQueue_, buffer.getChannel(0)->data(), buffer.frames());
 
498
 
 
499
    // the most likely other result is SL_RESULT_BUFFER_INSUFFICIENT,
 
500
    // which for this code example would indicate a programming error
 
501
    if (SL_RESULT_SUCCESS != result) {
 
502
        DEBUG("Error could not enqueue buffers in audio capture\n");
 
503
        return;
 
504
    }
 
505
 
 
506
    // start recording
 
507
    result = (*recorderInterface_)->SetRecordState(recorderInterface_, SL_RECORDSTATE_RECORDING);
 
508
    assert(SL_RESULT_SUCCESS == result);
 
509
 
 
510
    DEBUG("Audio capture started\n");
 
511
}
 
512
 
 
513
void
 
514
OpenSLLayer::stopAudioPlayback()
 
515
{
 
516
    DEBUG("Stop audio playback\n");
 
517
 
 
518
    if (playerInterface_ != nullptr) {
 
519
        SLresult result;
 
520
        result = (*playerInterface_)->SetPlayState(playerInterface_, SL_PLAYSTATE_STOPPED);
 
521
        assert(SL_RESULT_SUCCESS == result);
 
522
    }
 
523
 
 
524
    DEBUG("Audio playback stopped\n");
 
525
}
 
526
 
 
527
void
 
528
OpenSLLayer::stopAudioCapture()
 
529
{
 
530
    DEBUG("Stop audio capture\n");
 
531
 
 
532
    if (recorderInterface_ != nullptr) {
 
533
        SLresult result;
 
534
        result = (*recorderInterface_)->SetRecordState(recorderInterface_, SL_RECORDSTATE_STOPPED);
 
535
        assert(SL_RESULT_SUCCESS == result);
 
536
    }
 
537
 
 
538
    DEBUG("Audio capture stopped\n");
 
539
 
 
540
}
 
541
 
 
542
std::vector<std::string>
 
543
OpenSLLayer::getCaptureDeviceList() const
 
544
{
 
545
        std::vector<std::string> captureDeviceList;
 
546
 
 
547
 
 
548
 
 
549
// Although OpenSL ES specification allows enumerating
 
550
// available output (and also input) devices, NDK implementation is not mature enough to
 
551
// obtain or select proper one (SLAudioIODeviceCapabilitiesItf, the official interface
 
552
// to obtain such an information)-> SL_FEATURE_UNSUPPORTED
 
553
 
 
554
        SLuint32 InputDeviceIDs[MAX_NUMBER_INPUT_DEVICES];
 
555
        SLint32 numInputs = 0;
 
556
        SLboolean mic_available = SL_BOOLEAN_FALSE;
 
557
        SLuint32 mic_deviceID = 0;
 
558
 
 
559
        SLresult res;
 
560
 
 
561
        initAudioEngine();
 
562
    initAudioPlayback();
 
563
    initAudioCapture();
 
564
 
 
565
 
 
566
        // Get the Audio IO DEVICE CAPABILITIES interface, implicit
 
567
        DEBUG("Get the Audio IO DEVICE CAPABILITIES interface, implicit");
 
568
 
 
569
    res = (*engineObject_)->GetInterface(engineObject_, SL_IID_AUDIOIODEVICECAPABILITIES, (void*)&AudioIODeviceCapabilitiesItf);
 
570
    CheckErr(res);
 
571
 
 
572
        DEBUG("Get the Audio IO DEVICE CAPABILITIES interface, implicit");
 
573
        numInputs = MAX_NUMBER_INPUT_DEVICES;
 
574
 
 
575
        res = (*AudioIODeviceCapabilitiesItf)->GetAvailableAudioInputs(AudioIODeviceCapabilitiesItf, &numInputs, InputDeviceIDs);
 
576
        CheckErr(res);
 
577
 
 
578
        int i;
 
579
        // Search for either earpiece microphone or headset microphone input
 
580
        // device - with a preference for the latter
 
581
        for (i=0;i<numInputs; i++)
 
582
        {
 
583
                res = (*AudioIODeviceCapabilitiesItf)->QueryAudioInputCapabilities(AudioIODeviceCapabilitiesItf,
 
584
                                                                                                                                                                InputDeviceIDs[i],
 
585
                                                                                                                                                                &AudioInputDescriptor);
 
586
                CheckErr(res);
 
587
 
 
588
                if((AudioInputDescriptor.deviceConnection == SL_DEVCONNECTION_ATTACHED_WIRED) &&
 
589
                        (AudioInputDescriptor.deviceScope == SL_DEVSCOPE_USER) &&
 
590
                        (AudioInputDescriptor.deviceLocation == SL_DEVLOCATION_HEADSET))
 
591
                {
 
592
                        DEBUG("SL_DEVCONNECTION_ATTACHED_WIRED : mic_deviceID: %d", InputDeviceIDs[i] );
 
593
                        mic_deviceID = InputDeviceIDs[i];
 
594
                        mic_available = SL_BOOLEAN_TRUE;
 
595
                        break;
 
596
                } else if((AudioInputDescriptor.deviceConnection == SL_DEVCONNECTION_INTEGRATED) &&
 
597
                                        (AudioInputDescriptor.deviceScope == SL_DEVSCOPE_USER) &&
 
598
                                        (AudioInputDescriptor.deviceLocation == SL_DEVLOCATION_HANDSET))
 
599
                {
 
600
                        DEBUG("SL_DEVCONNECTION_INTEGRATED : mic_deviceID: %d", InputDeviceIDs[i] );
 
601
                        mic_deviceID = InputDeviceIDs[i];
 
602
                        mic_available = SL_BOOLEAN_TRUE;
 
603
                        break;
 
604
                }
 
605
        }
 
606
 
 
607
        if (!mic_available) {
 
608
                // Appropriate error message here
 
609
                ERROR("No mic available quitting");
 
610
                exit(1);
 
611
        }
 
612
 
 
613
 
 
614
    return captureDeviceList;
 
615
}
 
616
 
 
617
/* Checks for error. If any errors exit the application! */
 
618
void
 
619
OpenSLLayer::CheckErr( SLresult res )
 
620
{
 
621
        if ( res != SL_RESULT_SUCCESS )
 
622
        {
 
623
                // Debug printing to be placed here
 
624
                exit(1);
 
625
        }
 
626
}
 
627
 
 
628
std::vector<std::string>
 
629
OpenSLLayer::getPlaybackDeviceList() const
 
630
{
 
631
    std::vector<std::string> playbackDeviceList;
 
632
 
 
633
    return playbackDeviceList;
 
634
}
 
635
 
 
636
void
 
637
OpenSLLayer::audioPlaybackCallback(SLAndroidSimpleBufferQueueItf queue, void *context)
 
638
{
 
639
    assert(nullptr != context);
 
640
    static_cast<OpenSLLayer*>(context)->playback(queue);
 
641
}
 
642
 
 
643
void
 
644
OpenSLLayer::playback(SLAndroidSimpleBufferQueueItf queue)
 
645
{
 
646
    assert(nullptr != queue);
 
647
 
 
648
        notifyIncomingCall();
 
649
 
 
650
    AudioBuffer &buffer = getNextPlaybackBuffer();
 
651
 
 
652
    size_t samplesToGet = Manager::instance().getMainBuffer().availableForGet(MainBuffer::DEFAULT_ID);
 
653
    size_t urgentSamplesToGet = urgentRingBuffer_.availableForGet(MainBuffer::DEFAULT_ID);
 
654
 
 
655
        bufferIsFilled_ = false;
 
656
        //DEBUG("samplesToGet:%d", samplesToGet);
 
657
        //DEBUG("urgentSamplesToGet:%d", urgentSamplesToGet);
 
658
 
 
659
    if (urgentSamplesToGet > 0)
 
660
        bufferIsFilled_ = audioPlaybackFillWithUrgent(buffer, urgentSamplesToGet);
 
661
    else {
 
662
                if (samplesToGet > 0)
 
663
                        bufferIsFilled_ = audioPlaybackFillWithVoice(buffer, samplesToGet);
 
664
        else {
 
665
            bufferIsFilled_ = audioPlaybackFillWithToneOrRingtone(buffer);
 
666
        }
 
667
        }
 
668
 
 
669
    if (bufferIsFilled_) {
 
670
        SLresult result = (*queue)->Enqueue(queue, buffer.getChannel(0)->data(), buffer.frames()*sizeof(SFLAudioSample));
 
671
 
 
672
        if (SL_RESULT_SUCCESS != result) {
 
673
            DEBUG("Error could not enqueue buffers in playback callback\n");
 
674
        }
 
675
 
 
676
        incrementPlaybackIndex();
 
677
    } else {
 
678
                DEBUG("Error buffer not filled in audio playback\n");
 
679
        }
 
680
}
 
681
 
 
682
void
 
683
OpenSLLayer::audioCaptureCallback(SLAndroidSimpleBufferQueueItf queue, void *context)
 
684
{
 
685
    assert(nullptr != context);
 
686
    static_cast<OpenSLLayer*>(context)->capture(queue);
 
687
}
 
688
 
 
689
void
 
690
OpenSLLayer::capture(SLAndroidSimpleBufferQueueItf queue)
 
691
{
 
692
    assert(nullptr != queue);
 
693
 
 
694
    AudioBuffer &old_buffer = getNextRecordBuffer();
 
695
    incrementRecordIndex();
 
696
    AudioBuffer &buffer = getNextRecordBuffer();
 
697
 
 
698
    SLresult result;
 
699
    // enqueue an empty buffer to be filled by the recorder
 
700
    // (for streaming recording, we enqueue at least 2 empty buffers to start things off)
 
701
    result = (*recorderBufferQueue_)->Enqueue(recorderBufferQueue_, buffer.getChannel(0)->data(), buffer.frames()*sizeof(SFLAudioSample));
 
702
    
 
703
 
 
704
    audioCaptureFillBuffer(old_buffer);
 
705
 
 
706
    // the most likely other result is SL_RESULT_BUFFER_INSUFFICIENT,
 
707
    // which for this code example would indicate a programming error
 
708
    assert(SL_RESULT_SUCCESS == result);
 
709
}
 
710
 
 
711
 
 
712
 
 
713
void
 
714
OpenSLLayer::updatePreference(AudioPreference &preference, int index, PCMType type)
 
715
{
 
716
#ifdef OUTSIDE_TESTING
 
717
 
 
718
    switch (type) {
 
719
        case SFL_PCM_PLAYBACK:
 
720
            break;
 
721
 
 
722
        case SFL_PCM_CAPTURE:
 
723
            break;
 
724
 
 
725
        case SFL_PCM_RINGTONE:
 
726
            break;
 
727
 
 
728
        default:
 
729
            break;
 
730
    }
 
731
 
 
732
#endif
 
733
}
 
734
 
 
735
void OpenSLLayer::audioCaptureFillBuffer(AudioBuffer &buffer)
 
736
{
 
737
    MainBuffer &mbuffer = Manager::instance().getMainBuffer();
 
738
 
 
739
    const unsigned mainBufferSampleRate = mbuffer.getInternalSamplingRate();
 
740
    const bool resample = mainBufferSampleRate != sampleRate_;
 
741
 
 
742
    buffer.applyGain(isCaptureMuted_ ? 0.0 : captureGain_);
 
743
 
 
744
    if (resample) {
 
745
                int outSamples = buffer.frames() * (static_cast<double>(sampleRate_) / mainBufferSampleRate);
 
746
        AudioBuffer out(outSamples, 1, mainBufferSampleRate);
 
747
        converter_.resample(buffer, out);
 
748
        dcblocker_.process(out);
 
749
        mbuffer.putData(out, MainBuffer::DEFAULT_ID);
 
750
    } else {
 
751
        dcblocker_.process(buffer);
 
752
        mbuffer.putData(buffer, MainBuffer::DEFAULT_ID);
 
753
    }
 
754
}
 
755
 
 
756
bool OpenSLLayer::audioPlaybackFillWithToneOrRingtone(AudioBuffer &buffer)
 
757
{
 
758
    buffer.resize(BUFFER_SIZE);
 
759
    AudioLoop *tone = Manager::instance().getTelephoneTone();
 
760
    AudioLoop *file_tone = Manager::instance().getTelephoneFile();
 
761
 
 
762
    // In case of a dtmf, the pointers will be set to nullptr once the dtmf length is
 
763
    // reached. For this reason we need to fill audio buffer with zeros if pointer is nullptr
 
764
    if (tone) {
 
765
        tone->getNext(buffer, playbackGain_);
 
766
    } else if (file_tone) {
 
767
        file_tone->getNext(buffer, playbackGain_);
 
768
    } else {
 
769
        buffer.reset();
 
770
    }
 
771
 
 
772
    return true;
 
773
}
 
774
 
 
775
bool OpenSLLayer::audioPlaybackFillWithUrgent(AudioBuffer &buffer, size_t samplesToGet)
 
776
{
 
777
    // Urgent data (dtmf, incoming call signal) come first.
 
778
    samplesToGet = std::min(samplesToGet, BUFFER_SIZE);
 
779
    buffer.resize(samplesToGet);
 
780
    urgentRingBuffer_.get(buffer, MainBuffer::DEFAULT_ID);
 
781
    buffer.applyGain(isPlaybackMuted_ ? 0.0 : playbackGain_);
 
782
 
 
783
    // Consume the regular one as well (same amount of samples)
 
784
    Manager::instance().getMainBuffer().discard(samplesToGet, MainBuffer::DEFAULT_ID);
 
785
 
 
786
    return true;
 
787
}
 
788
 
 
789
bool OpenSLLayer::audioPlaybackFillWithVoice(AudioBuffer &buffer, size_t samplesAvail)
 
790
{
 
791
    MainBuffer &mainBuffer = Manager::instance().getMainBuffer();
 
792
 
 
793
    buffer.resize(samplesAvail);
 
794
    mainBuffer.getData(buffer, MainBuffer::DEFAULT_ID);
 
795
    buffer.applyGain(isPlaybackMuted_ ? 0.0 : playbackGain_);
 
796
 
 
797
    if (sampleRate_ != mainBuffer.getInternalSamplingRate()) {
 
798
        DEBUG("OpenSLLayer::audioPlaybackFillWithVoice sampleRate_ != mainBuffer.getInternalSamplingRate() \n");
 
799
        AudioBuffer out(buffer, false);
 
800
        out.setSampleRate(sampleRate_);
 
801
        converter_.resample(buffer, out);
 
802
        buffer = out;
 
803
    }
 
804
 
 
805
    return true;
 
806
}
 
807
 
 
808
void dumpAvailableEngineInterfaces()
 
809
{
 
810
    SLresult result;
 
811
    DEBUG("Engine Interfaces\n");
 
812
    SLuint32 numSupportedInterfaces;
 
813
    result = slQueryNumSupportedEngineInterfaces(&numSupportedInterfaces);
 
814
    assert(SL_RESULT_SUCCESS == result);
 
815
    result = slQueryNumSupportedEngineInterfaces(NULL);
 
816
    assert(SL_RESULT_PARAMETER_INVALID == result);
 
817
 
 
818
    DEBUG("Engine number of supported interfaces %lu\n", numSupportedInterfaces);
 
819
    for(SLuint32 i=0; i< numSupportedInterfaces; i++){
 
820
        SLInterfaceID  pInterfaceId;
 
821
        slQuerySupportedEngineInterfaces(i, &pInterfaceId);
 
822
        const char* nm = "unknown iid";
 
823
 
 
824
        if (pInterfaceId==SL_IID_NULL) nm="null";
 
825
        else if (pInterfaceId==SL_IID_OBJECT) nm="object";
 
826
        else if (pInterfaceId==SL_IID_AUDIOIODEVICECAPABILITIES) nm="audiodevicecapabilities";
 
827
        else if (pInterfaceId==SL_IID_LED) nm="led";
 
828
        else if (pInterfaceId==SL_IID_VIBRA) nm="vibra";
 
829
        else if (pInterfaceId==SL_IID_METADATAEXTRACTION) nm="metadataextraction";
 
830
        else if (pInterfaceId==SL_IID_METADATATRAVERSAL) nm="metadatatraversal";
 
831
        else if (pInterfaceId==SL_IID_DYNAMICSOURCE) nm="dynamicsource";
 
832
        else if (pInterfaceId==SL_IID_OUTPUTMIX) nm="outputmix";
 
833
        else if (pInterfaceId==SL_IID_PLAY) nm="play";
 
834
        else if (pInterfaceId==SL_IID_PREFETCHSTATUS) nm="prefetchstatus";
 
835
        else if (pInterfaceId==SL_IID_PLAYBACKRATE) nm="playbackrate";
 
836
        else if (pInterfaceId==SL_IID_SEEK) nm="seek";
 
837
        else if (pInterfaceId==SL_IID_RECORD) nm="record";
 
838
        else if (pInterfaceId==SL_IID_EQUALIZER) nm="equalizer";
 
839
        else if (pInterfaceId==SL_IID_VOLUME) nm="volume";
 
840
        else if (pInterfaceId==SL_IID_DEVICEVOLUME) nm="devicevolume";
 
841
        else if (pInterfaceId==SL_IID_BUFFERQUEUE) nm="bufferqueue";
 
842
        else if (pInterfaceId==SL_IID_PRESETREVERB) nm="presetreverb";
 
843
        else if (pInterfaceId==SL_IID_ENVIRONMENTALREVERB) nm="environmentalreverb";
 
844
        else if (pInterfaceId==SL_IID_EFFECTSEND) nm="effectsend";
 
845
        else if (pInterfaceId==SL_IID_3DGROUPING) nm="3dgrouping";
 
846
        else if (pInterfaceId==SL_IID_3DCOMMIT) nm="3dcommit";
 
847
        else if (pInterfaceId==SL_IID_3DLOCATION) nm="3dlocation";
 
848
        else if (pInterfaceId==SL_IID_3DDOPPLER) nm="3ddoppler";
 
849
        else if (pInterfaceId==SL_IID_3DSOURCE) nm="3dsource";
 
850
        else if (pInterfaceId==SL_IID_3DMACROSCOPIC) nm="3dmacroscopic";
 
851
        else if (pInterfaceId==SL_IID_MUTESOLO) nm="mutesolo";
 
852
        else if (pInterfaceId==SL_IID_DYNAMICINTERFACEMANAGEMENT) nm="dynamicinterfacemanagement";
 
853
        else if (pInterfaceId==SL_IID_MIDIMESSAGE) nm="midimessage";
 
854
        else if (pInterfaceId==SL_IID_MIDIMUTESOLO) nm="midimutesolo";
 
855
        else if (pInterfaceId==SL_IID_MIDITEMPO) nm="miditempo";
 
856
        else if (pInterfaceId==SL_IID_MIDITIME) nm="miditime";
 
857
        else if (pInterfaceId==SL_IID_AUDIODECODERCAPABILITIES) nm="audiodecodercapabilities";
 
858
        else if (pInterfaceId==SL_IID_AUDIOENCODERCAPABILITIES) nm="audioencodercapabilities";
 
859
        else if (pInterfaceId==SL_IID_AUDIOENCODER) nm="audioencoder";
 
860
        else if (pInterfaceId==SL_IID_BASSBOOST) nm="bassboost";
 
861
        else if (pInterfaceId==SL_IID_PITCH) nm="pitch";
 
862
        else if (pInterfaceId==SL_IID_RATEPITCH) nm="ratepitch";
 
863
        else if (pInterfaceId==SL_IID_VIRTUALIZER) nm="virtualizer";
 
864
        else if (pInterfaceId==SL_IID_VISUALIZATION) nm="visualization";
 
865
        else if (pInterfaceId==SL_IID_ENGINE) nm="engine";
 
866
        else if (pInterfaceId==SL_IID_ENGINECAPABILITIES) nm="enginecapabilities";
 
867
        else if (pInterfaceId==SL_IID_THREADSYNC) nm="theadsync";
 
868
        else if (pInterfaceId==SL_IID_ANDROIDEFFECT) nm="androideffect";
 
869
        else if (pInterfaceId==SL_IID_ANDROIDEFFECTSEND) nm="androideffectsend";
 
870
        else if (pInterfaceId==SL_IID_ANDROIDEFFECTCAPABILITIES) nm="androideffectcapabilities";
 
871
        else if (pInterfaceId==SL_IID_ANDROIDCONFIGURATION) nm="androidconfiguration";
 
872
        else if (pInterfaceId==SL_IID_ANDROIDSIMPLEBUFFERQUEUE) nm="simplebuferqueue";
 
873
        //else if (pInterfaceId==//SL_IID_ANDROIDBUFFERQUEUESOURCE) nm="bufferqueuesource";
 
874
        DEBUG("%s,",nm);
 
875
    }
 
876
}