AudioStreamLegacy.cpp revision 5204d315c6c6f53188f8d1414dd1b55b6c90142b
1/*
2 * Copyright 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "AudioStreamLegacy"
18//#define LOG_NDEBUG 0
19#include <utils/Log.h>
20
21#include <stdint.h>
22#include <utils/String16.h>
23#include <media/AudioTrack.h>
24#include <aaudio/AAudio.h>
25
26#include "core/AudioStream.h"
27#include "legacy/AudioStreamLegacy.h"
28
29using namespace android;
30using namespace aaudio;
31
32AudioStreamLegacy::AudioStreamLegacy()
33        : AudioStream() {
34}
35
36AudioStreamLegacy::~AudioStreamLegacy() {
37}
38
39// Called from AudioTrack.cpp or AudioRecord.cpp
40static void AudioStreamLegacy_callback(int event, void* userData, void *info) {
41    AudioStreamLegacy *streamLegacy = (AudioStreamLegacy *) userData;
42    streamLegacy->processCallback(event, info);
43}
44
45aaudio_legacy_callback_t AudioStreamLegacy::getLegacyCallback() {
46    return AudioStreamLegacy_callback;
47}
48
49// Implement FixedBlockProcessor
50int32_t AudioStreamLegacy::onProcessFixedBlock(uint8_t *buffer, int32_t numBytes) {
51    int32_t frameCount = numBytes / getBytesPerFrame();
52    // Call using the AAudio callback interface.
53    AAudioStream_dataCallback appCallback = getDataCallbackProc();
54    return (*appCallback)(
55            (AAudioStream *) this,
56            getDataCallbackUserData(),
57            buffer,
58            frameCount);
59}
60
61void AudioStreamLegacy::processCallbackCommon(aaudio_callback_operation_t opcode, void *info) {
62    aaudio_data_callback_result_t callbackResult;
63    switch (opcode) {
64        case AAUDIO_CALLBACK_OPERATION_PROCESS_DATA: {
65            // Note that this code assumes an AudioTrack::Buffer is the same as AudioRecord::Buffer
66            // TODO define our own AudioBuffer and pass it from the subclasses.
67            AudioTrack::Buffer *audioBuffer = static_cast<AudioTrack::Buffer *>(info);
68            if (audioBuffer->frameCount == 0) return;
69
70            // If the caller specified an exact size then use a block size adapter.
71            if (mBlockAdapter != nullptr) {
72                int32_t byteCount = audioBuffer->frameCount * getBytesPerFrame();
73                callbackResult = mBlockAdapter->processVariableBlock((uint8_t *) audioBuffer->raw,
74                                                                     byteCount);
75            } else {
76                // Call using the AAudio callback interface.
77                callbackResult = (*getDataCallbackProc())(
78                        (AAudioStream *) this,
79                        getDataCallbackUserData(),
80                        audioBuffer->raw,
81                        audioBuffer->frameCount
82                        );
83            }
84            if (callbackResult == AAUDIO_CALLBACK_RESULT_CONTINUE) {
85                audioBuffer->size = audioBuffer->frameCount * getBytesPerFrame();
86                incrementClientFrameCounter(audioBuffer->frameCount);
87            } else {
88                audioBuffer->size = 0;
89            }
90        }
91            break;
92
93            // Stream got rerouted so we disconnect.
94        case AAUDIO_CALLBACK_OPERATION_DISCONNECTED: {
95            ALOGD("AudioStreamAAudio(): callbackLoop() stream disconnected");
96            if (getErrorCallbackProc() != nullptr) {
97                (*getErrorCallbackProc())(
98                        (AAudioStream *) this,
99                        getErrorCallbackUserData(),
100                        AAUDIO_OK
101                        );
102            }
103            mCallbackEnabled.store(false);
104        }
105            break;
106
107        default:
108            break;
109    }
110}
111
112aaudio_result_t AudioStreamLegacy::getBestTimestamp(clockid_t clockId,
113                                                   int64_t *framePosition,
114                                                   int64_t *timeNanoseconds,
115                                                   ExtendedTimestamp *extendedTimestamp) {
116    int timebase;
117    switch (clockId) {
118        case CLOCK_BOOTTIME:
119            timebase = ExtendedTimestamp::TIMEBASE_BOOTTIME;
120            break;
121        case CLOCK_MONOTONIC:
122            timebase = ExtendedTimestamp::TIMEBASE_MONOTONIC;
123            break;
124        default:
125            ALOGE("getTimestamp() - Unrecognized clock type %d", (int) clockId);
126            return AAUDIO_ERROR_UNEXPECTED_VALUE;
127            break;
128    }
129    status_t status = extendedTimestamp->getBestTimestamp(framePosition, timeNanoseconds, timebase);
130    return AAudioConvert_androidToAAudioResult(status);
131}
132