opensllayer.cpp 22 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
/*
 *  Copyright (C) 2004, 2005, 2006, 2008, 2009, 2010, 2011 Savoir-Faire Linux Inc.
 *  Author: Alexandre Savard <alexandre.savard@savoirfairelinux.com>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 *  Additional permission under GNU GPL version 3 section 7:
 *
 *  If you modify this program, or any covered work, by linking or
 *  combining it with the OpenSSL project's OpenSSL library (or a
 *  modified version of that library), containing parts covered by the
 *  terms of the OpenSSL or SSLeay licenses, Savoir-Faire Linux Inc.
 *  grants you additional permission to convey the resulting work.
 *  Corresponding Source for a non-source form of such a combination
 *  shall include the source code for the parts of OpenSSL used as well
 *  as that of the covered work.
 */

Tristan Matthews's avatar
Tristan Matthews committed
31
32
#include <cstdio>
#include <cassert>
33

34
#include "logger.h"
35
#include "array_size.h"
36
#include "manager.h"
37
#include "mainbuffer.h"
38

39
40
#include "opensllayer.h"

41
42
43
const int OpenSLLayer::NB_BUFFER_PLAYBACK_QUEUE = ANDROID_BUFFER_QUEUE_LENGTH;
const int OpenSLLayer::NB_BUFFER_CAPTURE_QUEUE = ANDROID_BUFFER_QUEUE_LENGTH;

44
static long sawPtr = 0;
45
46
static void generateSawTooth(short *buffer, int length)
{
47
48
49
50
    assert(NULL != buffer);
    assert(length > 0);

    unsigned int i;
51

52
    for (i = 0; i < length; ++i, ++sawPtr) {
53
        buffer[i] = 32768 - ((sawPtr % 10) * 6600);
54
55
56
    }
}

57
class OpenSLThread {
58
59
    public:
        OpenSLThread(OpenSLLayer *opensl);
60
        ~OpenSLThread();
61
        void initAudioLayer();
62
63
        void start();
        bool isRunning() const;
64
65

    private:
66
67
68
        void run();
        static void *runCallback(void *context);

69
        NON_COPYABLE(OpenSLThread);
70
        pthread_t thread_;
71
        OpenSLLayer* opensl_;
72
        bool running_;
73
74
75
};

OpenSLThread::OpenSLThread(OpenSLLayer *opensl)
76
    : thread_(0), opensl_(opensl), running_(false)
77
{}
78

79
OpenSLThread::~OpenSLThread()
80
{
81
    running_ = false;
82
83
    opensl_->shutdownAudioEngine();

84
85
86
87
    if (thread_)
        pthread_join(thread_, NULL);
}

Tristan Matthews's avatar
Tristan Matthews committed
88
89
void
OpenSLThread::start()
90
91
92
93
94
95
96
97
98
99
100
101
102
{
    running_ = true;
    pthread_create(&thread_, NULL, &runCallback, this);
}

void *
OpenSLThread::runCallback(void *data)
{
    OpenSLThread *context = static_cast<OpenSLThread*>(data);
    context->run();
    return NULL;
}

Tristan Matthews's avatar
Tristan Matthews committed
103
104
bool
OpenSLThread::isRunning() const
105
106
{
    return running_;
107
108
}

Tristan Matthews's avatar
Tristan Matthews committed
109
110
void
OpenSLThread::initAudioLayer()
111
112
113
{
    opensl_->initAudioEngine();
    opensl_->initAudioPlayback();
114
    opensl_->initAudioCapture();
115
116
117
118
119
}

/**
 * Reimplementation of run()
 */
Tristan Matthews's avatar
Tristan Matthews committed
120
121
void
OpenSLThread::run()
122
123
124
125
{
    initAudioLayer();

    opensl_->startAudioPlayback();
126
    opensl_->startAudioCapture();
127

128
129
    while (opensl_->isStarted_)
        usleep(20000); // 20 ms
130
131
132
133
134
135
136
}

// Constructor
OpenSLLayer::OpenSLLayer()
    : indexIn_(0)
    , indexOut_(0)
    , indexRing_(0)
137
    , audioThread_(0)
138
    , isStarted_(false)
139
140
141
142
143
144
145
146
147
148
149
    , engineObject_(0)
    , engineInterface_(0)
    , outputMixer_(0)
    , playerObject_(0)
    , recorderObject_(0)
    , playerInterface_(0)
    , recorderInterface_(0)
    , playbackBufferQueue_(0)
    , recorderBufferQueue_(0)
    , playbackBufferIndex_(0)
    , recordBufferIndex_(0)
150
151
    , playbackBufferStack_(ANDROID_BUFFER_QUEUE_LENGTH, AudioBuffer(0))
    , recordBufferStack_(ANDROID_BUFFER_QUEUE_LENGTH, AudioBuffer(0))
152
153
154
155
156
157
{
}

// Destructor
OpenSLLayer::~OpenSLLayer()
{
Alexandre Savard's avatar
Alexandre Savard committed
158
    stopStream();
159
160
}

161
//#define RECORD_AUDIO_TODISK
162
163
#ifdef RECORD_AUDIO_TODISK
#include <fstream>
164
std::ofstream opensl_outfile;
165
std::ofstream opensl_infile;
166
167
#endif

168
169
170
void
OpenSLLayer::startStream()
{
171
    if (isStarted_)
172
173
        return;

174
175
    DEBUG("Start OpenSL audio layer");

176
    if (audioThread_ == NULL) {
177
#ifdef RECORD_AUDIO_TODISK
178
179
        opensl_outfile.open("/data/data/com.savoirfairelinux.sflphone/opensl_playback.raw", std::ofstream::out | std::ofstream::binary);
        opensl_infile.open("/data/data/com.savoirfairelinux.sflphone/opensl_record.raw", std::ofstream::out | std::ofstream::binary);
180
181
#endif

182
        audioThread_ = new OpenSLThread(this);
183
        isStarted_ = true;
184
185
        audioThread_->start();
    }
186

187
188
189
190
191
}

void
OpenSLLayer::stopStream()
{
192
    if (not isStarted_)
193
194
        return;

195
196
197
198
199
    DEBUG("Stop OpenSL audio layer");

    stopAudioPlayback();
    stopAudioCapture();

200
201
202
203
    isStarted_ = false;

    delete audioThread_;
    audioThread_ = NULL;
204
#ifdef RECORD_AUDIO_TODISK
205
    opensl_outfile.close();
206
    opensl_infile.close();
207
#endif
208
209
210
211
212
213
214
}

void
OpenSLLayer::initAudioEngine()
{
    SLresult result;

215
    DEBUG("Create Audio Engine\n");
216
    result = slCreateEngine(&engineObject_, 0, NULL, 0, NULL, NULL);
217
218
    assert(SL_RESULT_SUCCESS == result);

219
    DEBUG("Realize Audio Engine\n");
220
    result = (*engineObject_)->Realize(engineObject_, SL_BOOLEAN_FALSE);
221
222
    assert(SL_RESULT_SUCCESS == result);

223
    DEBUG("Create Audio Engine Interface\n");
224
    result = (*engineObject_)->GetInterface(engineObject_, SL_IID_ENGINE, &engineInterface_);
225
226
    assert(SL_RESULT_SUCCESS == result);

227
    DEBUG("Create Output Mixer\n");
228
    result = (*engineInterface_)->CreateOutputMix(engineInterface_, &outputMixer_, 0, NULL, NULL);
229
230
    assert(SL_RESULT_SUCCESS == result);

231
    DEBUG("Realize Output Mixer\n");
232
    result = (*outputMixer_)->Realize(outputMixer_, SL_BOOLEAN_FALSE);
233
234
    assert(SL_RESULT_SUCCESS == result);

235
    DEBUG("Audio Engine Initialization Done\n");
236
237
}

238
void
239
240
OpenSLLayer::shutdownAudioEngine()
{
241

242
    // destroy buffer queue audio player object, and invalidate all associated interfaces
243
    DEBUG("Shutdown audio player\n");
244

245
246
247
248
249
    if (playerObject_ != NULL) {
        (*playerObject_)->Destroy(playerObject_);
        playerObject_ = NULL;
        playerInterface_ = NULL;
        playbackBufferQueue_ = NULL;
250
    }
251

252
    // destroy output mix object, and invalidate all associated interfaces
253
    DEBUG("Shutdown audio mixer\n");
254

255
256
    if (outputMixer_ != NULL) {
        (*outputMixer_)->Destroy(outputMixer_);
257
        outputMixer_ = NULL;
258
259
260
    }

    // destroy engine object, and invalidate all associated interfaces
261
    DEBUG("Shutdown audio engine\n");
262

263
264
265
266
    if (engineObject_ != NULL) {
        (*engineObject_)->Destroy(engineObject_);
        engineObject_ = NULL;
        engineInterface_ = NULL;
267
    }
268
269
270
271
272
}

void
OpenSLLayer::initAudioPlayback()
{
273
274
275
    assert(NULL != engineObject_);
    assert(NULL != engineInterface_);
    assert(NULL != outputMixer_);
276
277
278
279

    SLresult result;

    // Initialize the location of the buffer queue
280
    DEBUG("Create playback queue\n");
281
    SLDataLocator_AndroidSimpleBufferQueue bufferLocation = {SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE,
282
283
                                           NB_BUFFER_PLAYBACK_QUEUE
                                                            };
284
285

    // Initnialize the audio format for this queue
286
    DEBUG("Setting audio format\n");
287
    SLDataFormat_PCM audioFormat = {SL_DATAFORMAT_PCM, 1,
288
289
                                    SL_SAMPLINGRATE_8,
                                    SL_PCMSAMPLEFORMAT_FIXED_16,
290
291
292
293
                                    SL_PCMSAMPLEFORMAT_FIXED_16,
                                    SL_SPEAKER_FRONT_CENTER,
                                    SL_BYTEORDER_LITTLEENDIAN
                                   };
294
295

    // Create the audio source
296
    DEBUG("Set Audio Sources\n");
297
298
    SLDataSource audioSource = {&bufferLocation, &audioFormat};

299
    // Cofiguration fo the audio sink as an output mixer
300
    DEBUG("Set output mixer location\n");
301
    SLDataLocator_OutputMix mixerLocation = {SL_DATALOCATOR_OUTPUTMIX, outputMixer_};
302
303
    SLDataSink audioSink = {&mixerLocation, NULL};

304
    const SLInterfaceID ids[] = {SL_IID_ANDROIDSIMPLEBUFFERQUEUE,
305
306
                                 SL_IID_VOLUME, SL_IID_ANDROIDCONFIGURATION
                                };
307
    const SLboolean req[] = {SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE};
308

309
    const unsigned nbInterface = ARRAYSIZE(ids);
310

311
    // create audio player
312
    DEBUG("Create audio player\n");
313
    result = (*engineInterface_)->CreateAudioPlayer(engineInterface_, &playerObject_, &audioSource, &audioSink, nbInterface, ids, req);
314
315
    assert(SL_RESULT_SUCCESS == result);

Tristan Matthews's avatar
Tristan Matthews committed
316
317
318
    SLAndroidConfigurationItf playerConfig;
    SLint32 streamType = SL_ANDROID_STREAM_VOICE;

319
    result = (*playerObject_)->GetInterface(playerObject_,
320
321
322
                                            SL_IID_ANDROIDCONFIGURATION,
                                            &playerConfig);

323
324
    if (result == SL_RESULT_SUCCESS && playerConfig) {
        result = (*playerConfig)->SetConfiguration(
325
326
                     playerConfig, SL_ANDROID_KEY_STREAM_TYPE,
                     &streamType, sizeof(SLint32));
327
    }
328

329
330
331
332
    if (result != SL_RESULT_SUCCESS) {
        ERROR("Unable to set android player configuration");
    }

333
    DEBUG("Realize audio player\n");
334
    result = (*playerObject_)->Realize(playerObject_, SL_BOOLEAN_FALSE);
335
336
337
    assert(SL_RESULT_SUCCESS == result);

    // create audio interface
338
    DEBUG("Create audio player interface\n");
339
    result = (*playerObject_)->GetInterface(playerObject_, SL_IID_PLAY, &playerInterface_);
340
341
342
    assert(SL_RESULT_SUCCESS == result);

    // create the buffer queue interface
343
    DEBUG("Create buffer queue interface\n");
344
    result = (*playerObject_)->GetInterface(playerObject_, SL_IID_BUFFERQUEUE, &playbackBufferQueue_);
345
346
347
    assert(SL_RESULT_SUCCESS == result);

    // register the buffer queue on the buffer object
348
    DEBUG("Register audio callback\n");
349
    result = (*playbackBufferQueue_)->RegisterCallback(playbackBufferQueue_, audioPlaybackCallback, this);
350
351
    assert(SL_RESULT_SUCCESS == result);

352
    DEBUG("Audio Playback Initialization Done\n");
353
354
355
356
357
358
359
360
}

void
OpenSLLayer::initAudioCapture()
{
    SLresult result;

    // configure audio source
361
    DEBUG("Configure audio source\n");
362
    SLDataLocator_IODevice deviceLocator = {SL_DATALOCATOR_IODEVICE,
363
                                            SL_IODEVICE_AUDIOINPUT,
364
365
366
                                            SL_DEFAULTDEVICEID_AUDIOINPUT,
                                            NULL
                                           };
367
368

    SLDataSource audioSource = {&deviceLocator,
369
370
                                NULL
                               };
371
372

    // configure audio sink
373
374
    DEBUG("Configure audio sink\n");

375
376
377
    SLDataLocator_AndroidSimpleBufferQueue bufferLocator = {SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE,
                                           NB_BUFFER_CAPTURE_QUEUE
                                                           };
378

379
    SLDataFormat_PCM audioFormat = {SL_DATAFORMAT_PCM, 1,
380
                                    SL_SAMPLINGRATE_8,
381
382
383
384
385
                                    SL_PCMSAMPLEFORMAT_FIXED_16,
                                    SL_PCMSAMPLEFORMAT_FIXED_16,
                                    SL_SPEAKER_FRONT_CENTER,
                                    SL_BYTEORDER_LITTLEENDIAN
                                   };
386

387
388
389
    SLDataSink audioSink = {&bufferLocator,
                            &audioFormat
                           };
390
391
392

    // create audio recorder
    // (requires the RECORD_AUDIO permission)
393
    DEBUG("Create audio recorder\n");
394
395
    const SLInterfaceID id[] = {SL_IID_ANDROIDSIMPLEBUFFERQUEUE};
    const SLboolean req[] = {SL_BOOLEAN_TRUE};
396

397
398
    if (engineInterface_ != NULL) {
        result = (*engineInterface_)->CreateAudioRecorder(engineInterface_,
399
                 &recorderObject_, &audioSource, &audioSink, 1, id, req);
alision's avatar
alision committed
400
    }
401

402
    if (SL_RESULT_SUCCESS != result) {
403
        DEBUG("Error: could not create audio recorder");
404
405
406
407
        return;
    }

    // realize the audio recorder
408
    DEBUG("Realize the audio recorder\n");
409
    result = (*recorderObject_)->Realize(recorderObject_, SL_BOOLEAN_FALSE);
410

411
    if (SL_RESULT_SUCCESS != result) {
412
        DEBUG("Error: could not realize audio recorder");
413
414
415
416
        return;
    }

    // get the record interface
417
    DEBUG("Create the record interface\n");
418
    result = (*recorderObject_)->GetInterface(recorderObject_, SL_IID_RECORD, &recorderInterface_);
419
420
421
    assert(SL_RESULT_SUCCESS == result);

    // get the buffer queue interface
422
    DEBUG("Create the buffer queue interface\n");
423
    result = (*recorderObject_)->GetInterface(recorderObject_, SL_IID_ANDROIDSIMPLEBUFFERQUEUE,
424
             &recorderBufferQueue_);
425
426
427
    assert(SL_RESULT_SUCCESS == result);

    // register callback on the buffer queue
428
    DEBUG("Register the audio capture callback\n");
429
    result = (*recorderBufferQueue_)->RegisterCallback(recorderBufferQueue_, audioCaptureCallback, this);
430
431
    assert(SL_RESULT_SUCCESS == result);

432
    DEBUG("Audio capture initialized\n");
433
434
435
}


436
void
437
438
OpenSLLayer::startAudioPlayback()
{
439
    assert(NULL != playbackBufferQueue_);
440

441
    DEBUG("Start audio playback\n");
442
443
444

    SLresult result;

445
    for (int i = 0; i < NB_BUFFER_PLAYBACK_QUEUE; i++) {
446
447
448
        AudioBuffer &buffer = getNextPlaybackBuffer();
        incrementPlaybackIndex();

449
        buffer.reset();
450

451
        result = (*playbackBufferQueue_)->Enqueue(playbackBufferQueue_, buffer.getData()[0].data(), buffer.getData()[0].size());
452

453
        if (SL_RESULT_SUCCESS != result) {
454
            DEBUG("Error could not enqueue initial buffers\n");
455
456
457
        }
    }

458
    result = (*playerInterface_)->SetPlayState(playerInterface_, SL_PLAYSTATE_PLAYING);
459
460
    assert(SL_RESULT_SUCCESS == result);

461
    DEBUG("Audio playback started\n");
462
463
464
465
466
}

void
OpenSLLayer::startAudioCapture()
{
467
    assert(NULL != playbackBufferQueue_);
468

469
    DEBUG("Start audio capture\n");
470
471
472

    SLresult result;

473

474
    // in case already recording, stop recording and clear buffer queue
475
476
    if (recorderInterface_ != NULL) {
        result = (*recorderInterface_)->SetRecordState(recorderInterface_, SL_RECORDSTATE_STOPPED);
alision's avatar
alision committed
477
478
        assert(SL_RESULT_SUCCESS == result);
    }
alision's avatar
alision committed
479
480

    DEBUG("Clearing recorderBufferQueue\n");
481
    result = (*recorderBufferQueue_)->Clear(recorderBufferQueue_);
482
483
    assert(SL_RESULT_SUCCESS == result);

alision's avatar
alision committed
484
    DEBUG("getting next record buffer\n");
485
486
    // enqueue an empty buffer to be filled by the recorder
    // (for streaming recording, we enqueue at least 2 empty buffers to start things off)
487
488
489
    AudioBuffer &buffer = getNextRecordBuffer();
    incrementRecordIndex();

490
    buffer.reset();
491

alision's avatar
alision committed
492
    DEBUG("Enqueue record buffer\n");
493
494
	DEBUG("buffer.getData()[0].size():%d", buffer.getData()[0].size());
    result = (*recorderBufferQueue_)->Enqueue(recorderBufferQueue_, buffer.getData()[0].data(), buffer.getData()[0].size());
495

496
497
    // the most likely other result is SL_RESULT_BUFFER_INSUFFICIENT,
    // which for this code example would indicate a programming error
498
499
500
    if (SL_RESULT_SUCCESS != result) {
        DEBUG("Error could not enqueue buffers in audio capture\n");
        return;
alision's avatar
alision committed
501
    }
502
503

    // start recording
504
    result = (*recorderInterface_)->SetRecordState(recorderInterface_, SL_RECORDSTATE_RECORDING);
505
506
    assert(SL_RESULT_SUCCESS == result);

507
    DEBUG("Audio capture started\n");
508
509
510
511
512
}

void
OpenSLLayer::stopAudioPlayback()
{
513
    DEBUG("Stop audio playback\n");
514

515
    if (playerInterface_ != NULL) {
alision's avatar
alision committed
516
        SLresult result;
517
        result = (*playerInterface_)->SetPlayState(playerInterface_, SL_PLAYSTATE_STOPPED);
alision's avatar
alision committed
518
519
520
521
        assert(SL_RESULT_SUCCESS == result);
    }

    DEBUG("Audio playback stopped\n");
522
523
524
525
526
}

void
OpenSLLayer::stopAudioCapture()
{
527
    DEBUG("Stop audio capture\n");
528

529
    if (recorderInterface_ != NULL) {
alision's avatar
alision committed
530
        SLresult result;
531
        result = (*recorderInterface_)->SetRecordState(recorderInterface_, SL_RECORDSTATE_STOPPED);
alision's avatar
alision committed
532
533
534
535
        assert(SL_RESULT_SUCCESS == result);
    }

    DEBUG("Audio capture stopped\n");
536

537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
}

std::vector<std::string>
OpenSLLayer::getCaptureDeviceList() const
{
    std::vector<std::string> captureDeviceList;

    return captureDeviceList;
}

std::vector<std::string>
OpenSLLayer::getPlaybackDeviceList() const
{
    std::vector<std::string> playbackDeviceList;

    return playbackDeviceList;
}

555
556
void
OpenSLLayer::playback(SLAndroidSimpleBufferQueueItf queue)
557
558
559
{
    assert(NULL != queue);

560
561
    usleep(20000);

562
    AudioBuffer &buffer = getNextPlaybackBuffer();
563

564
    buffer.reset();
Alexandre Savard's avatar
Alexandre Savard committed
565

Tristan Matthews's avatar
Tristan Matthews committed
566
    const bool bufferFilled = audioPlaybackFillBuffer(buffer);
567

568
    if (bufferFilled) {
569
#ifdef RECORD_AUDIO_TODISK
570
        opensl_outfile.write((char const *)(buffer.getData()[0].data()), buffer.getData()[0].size());
571
#endif
572
        SLresult result = (*queue)->Enqueue(queue, buffer.getData()[0].data(), buffer.getData()[0].size());
573

574
        if (SL_RESULT_SUCCESS != result) {
575
            DEBUG("Error could not enqueue buffers in playback callback\n");
576
        }
577

578
        incrementPlaybackIndex();
579
580
581
    }
}

Tristan Matthews's avatar
Tristan Matthews committed
582
583
void
OpenSLLayer::audioPlaybackCallback(SLAndroidSimpleBufferQueueItf queue, void *context)
584
585
586
587
588
{
    assert(NULL != context);
    static_cast<OpenSLLayer*>(context)->playback(queue);
}

Tristan Matthews's avatar
Tristan Matthews committed
589
590
void
OpenSLLayer::capture(SLAndroidSimpleBufferQueueItf queue)
591
592
593
{
    assert(NULL != queue);

594
595
    AudioBuffer &buffer = getNextRecordBuffer();
    incrementRecordIndex();
596
597
598
599
600

    SLresult result;

    // enqueue an empty buffer to be filled by the recorder
    // (for streaming recording, we enqueue at least 2 empty buffers to start things off)
601
    result = (*recorderBufferQueue_)->Enqueue(recorderBufferQueue_, buffer.getData()[0].data(), buffer.getData()[0].size());
602
603
604
    // the most likely other result is SL_RESULT_BUFFER_INSUFFICIENT,
    // which for this code example would indicate a programming error
    assert(SL_RESULT_SUCCESS == result);
605

606
    audioCaptureFillBuffer(buffer);
607
#ifdef RECORD_AUDIO_TODISK
608
    opensl_infile.write((char const *)(buffer.getData()[0].data()), buffer.getData()[0].size());
609
#endif
610
611
}

Tristan Matthews's avatar
Tristan Matthews committed
612
613
void
OpenSLLayer::audioCaptureCallback(SLAndroidSimpleBufferQueueItf queue, void *context)
614
615
616
617
618
619
{
    assert(NULL != context);
    static_cast<OpenSLLayer*>(context)->capture(queue);
}


Tristan Matthews's avatar
Tristan Matthews committed
620
621
void
OpenSLLayer::updatePreference(AudioPreference &preference, int index, PCMType type)
622
623
{
#ifdef OUTSIDE_TESTING
624

625
626
627
    switch (type) {
        case SFL_PCM_PLAYBACK:
            break;
628

629
        case SFL_PCM_CAPTURE:
630
            break;
631

632
        case SFL_PCM_RINGTONE:
633
            break;
634

635
636
637
        default:
            break;
    }
638

639
640
#endif
}
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771

bool OpenSLLayer::audioPlaybackFillBuffer(AudioBuffer &buffer)
{
    // Looks if there's any voice audio from rtp to be played
    MainBuffer &mbuffer = Manager::instance().getMainBuffer();
    size_t bytesToGet = mbuffer.availableForGet(MainBuffer::DEFAULT_ID);
    size_t urgentBytesToGet = urgentRingBuffer_.availableForGet(MainBuffer::DEFAULT_ID);


    PlaybackMode mode = getPlaybackMode();

    bool bufferFilled = false;

    switch (mode) {
        case NONE:
        case TONE:
        case RINGTONE:
        case URGENT: {
            if (urgentBytesToGet > 0)
                bufferFilled = audioPlaybackFillWithUrgent(buffer, urgentBytesToGet);
            else
                bufferFilled = audioPlaybackFillWithToneOrRingtone(buffer);
        }
        break;

        case VOICE: {
            if (bytesToGet > 0)
                bufferFilled = audioPlaybackFillWithVoice(buffer, bytesToGet);
            else {
                buffer.reset();
                bufferFilled = true;
            }
        }
        break;

        case ZEROS:
        default: {
            buffer.reset();
            bufferFilled = true;
        }
    }

    if (!bufferFilled)
        printf("Error buffer not filled in audio playback\n");

    return bufferFilled;
}

// #define RECORD_TOMAIN_TODISK
#ifdef RECORD_TOMAIN_TODISK
#include <fstream>
std::ofstream opensl_tomainbuffer("/data/data/com.savoirfairelinux.sflphone/opensl_tomain.raw", std::ofstream::out | std::ofstream::binary);
#endif

void OpenSLLayer::audioCaptureFillBuffer(AudioBuffer &buffer)
{
    MainBuffer &mbuffer = Manager::instance().getMainBuffer();

    const unsigned mainBufferSampleRate = mbuffer.getInternalSamplingRate();
    const bool resample = mainBufferSampleRate != sampleRate_;

    buffer.applyGain(captureGain_);

    if (resample) {
        AudioBuffer out(buffer);
        out.setSampleRate(sampleRate_);

        converter_.resample(buffer, out);
        dcblocker_.process(out);
        mbuffer.putData(out, MainBuffer::DEFAULT_ID);
    } else {
        dcblocker_.process(buffer);
#ifdef RECORD_TOMAIN_TODISK
        opensl_tomainbuffer.write((char const *)in_ptr, toGetBytes /);
#endif
        mbuffer.putData(buffer, MainBuffer::DEFAULT_ID);
    }
}

bool OpenSLLayer::audioPlaybackFillWithToneOrRingtone(AudioBuffer &buffer)
{
    AudioLoop *tone = Manager::instance().getTelephoneTone();
    AudioLoop *file_tone = Manager::instance().getTelephoneFile();

    // In case of a dtmf, the pointers will be set to NULL once the dtmf length is
    // reached. For this reason we need to fill audio buffer with zeros if pointer is NULL
    if (tone) {
        tone->getNext(buffer, playbackGain_);
    } else if (file_tone) {
        file_tone->getNext(buffer, playbackGain_);
    } else {
        buffer.reset();
    }

    return true;
}

bool OpenSLLayer::audioPlaybackFillWithUrgent(AudioBuffer &buffer, size_t bytesToGet)
{
    // Urgent data (dtmf, incoming call signal) come first.
    bytesToGet = std::min(bytesToGet, buffer.capacity());
    urgentRingBuffer_.get(buffer, MainBuffer::DEFAULT_ID);
    buffer.applyGain(playbackGain_);

    // Consume the regular one as well (same amount of bytes)
    Manager::instance().getMainBuffer().discard(bytesToGet, MainBuffer::DEFAULT_ID);

    return true;
}

bool OpenSLLayer::audioPlaybackFillWithVoice(AudioBuffer &buffer, size_t bytesAvail)
{
    const size_t bytesToCpy = buffer.capacity();

    if (bytesAvail == 0)
        return false;

    MainBuffer &mainBuffer = Manager::instance().getMainBuffer();

    mainBuffer.getData(buffer, MainBuffer::DEFAULT_ID);
    buffer.applyGain(getPlaybackGain());

    if (sampleRate_ != mainBuffer.getInternalSamplingRate()) {
        AudioBuffer out(buffer, false);
        out.setSampleRate(sampleRate_);
        converter_.resample(buffer, out);
        buffer = out;
    }

    return true;
}