libaaudio: implement callback
Use AudioTrack and AudioRecord TRANSFER_CALLBACK.
Add FixedBlockAdapter to provide fixed size callbacks.
Bug: 36489240
Test: CTS test_aaudio.cpp
Change-Id: Id2034dd640f878dd27fee6b43ad80a01c627dfd6
Signed-off-by: Phil Burk <philburk@google.com>
diff --git a/media/libaaudio/src/legacy/AudioStreamLegacy.cpp b/media/libaaudio/src/legacy/AudioStreamLegacy.cpp
new file mode 100644
index 0000000..baa24c9
--- /dev/null
+++ b/media/libaaudio/src/legacy/AudioStreamLegacy.cpp
@@ -0,0 +1,110 @@
+/*
+ * Copyright 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "AudioStreamLegacy"
+//#define LOG_NDEBUG 0
+#include <utils/Log.h>
+
+#include <stdint.h>
+#include <utils/String16.h>
+#include <media/AudioTrack.h>
+#include <aaudio/AAudio.h>
+
+#include "core/AudioStream.h"
+#include "legacy/AudioStreamLegacy.h"
+
+using namespace android;
+using namespace aaudio;
+
+AudioStreamLegacy::AudioStreamLegacy()
+ : AudioStream() {
+}
+
+AudioStreamLegacy::~AudioStreamLegacy() {
+}
+
+// Called from AudioTrack.cpp or AudioRecord.cpp
+static void AudioStreamLegacy_callback(int event, void* userData, void *info) {
+ AudioStreamLegacy *streamLegacy = (AudioStreamLegacy *) userData;
+ streamLegacy->processCallback(event, info);
+}
+
+aaudio_legacy_callback_t AudioStreamLegacy::getLegacyCallback() {
+ return AudioStreamLegacy_callback;
+}
+
+// Implement FixedBlockProcessor
+int32_t AudioStreamLegacy::onProcessFixedBlock(uint8_t *buffer, int32_t numBytes) {
+ int32_t frameCount = numBytes / getBytesPerFrame();
+ // Call using the AAudio callback interface.
+ AAudioStream_dataCallback appCallback = getDataCallbackProc();
+ return (*appCallback)(
+ (AAudioStream *) this,
+ getDataCallbackUserData(),
+ buffer,
+ frameCount);
+}
+
+void AudioStreamLegacy::processCallbackCommon(aaudio_callback_operation_t opcode, void *info) {
+ aaudio_data_callback_result_t callbackResult;
+ switch (opcode) {
+ case AAUDIO_CALLBACK_OPERATION_PROCESS_DATA: {
+ // Note that this code assumes an AudioTrack::Buffer is the same as AudioRecord::Buffer
+ // TODO define our own AudioBuffer and pass it from the subclasses.
+ AudioTrack::Buffer *audioBuffer = static_cast<AudioTrack::Buffer *>(info);
+ if (audioBuffer->frameCount == 0) return;
+
+ // If the caller specified an exact size then use a block size adapter.
+ if (mBlockAdapter != nullptr) {
+ int32_t byteCount = audioBuffer->frameCount * getBytesPerFrame();
+ callbackResult = mBlockAdapter->processVariableBlock((uint8_t *) audioBuffer->raw,
+ byteCount);
+ } else {
+ // Call using the AAudio callback interface.
+ callbackResult = (*getDataCallbackProc())(
+ (AAudioStream *) this,
+ getDataCallbackUserData(),
+ audioBuffer->raw,
+ audioBuffer->frameCount
+ );
+ }
+ if (callbackResult == AAUDIO_CALLBACK_RESULT_CONTINUE) {
+ audioBuffer->size = audioBuffer->frameCount * getBytesPerFrame();
+ } else {
+ audioBuffer->size = 0;
+ }
+ }
+ break;
+
+ // Stream got rerouted so we disconnect.
+ case AAUDIO_CALLBACK_OPERATION_DISCONNECTED: {
+ ALOGD("AudioStreamAAudio(): callbackLoop() stream disconnected");
+ if (getErrorCallbackProc() != nullptr) {
+ (*getErrorCallbackProc())(
+ (AAudioStream *) this,
+ getErrorCallbackUserData(),
+ AAUDIO_OK
+ );
+ }
+ mCallbackEnabled.store(false);
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+