Loading media/libaaudio/examples/input_monitor/jni/Android.mk +15 −17 Original line number Diff line number Diff line Loading @@ -4,32 +4,30 @@ include $(CLEAR_VARS) LOCAL_MODULE_TAGS := tests LOCAL_C_INCLUDES := \ $(call include-path-for, audio-utils) \ frameworks/av/media/liboboe/include frameworks/av/media/libaaudio/include \ frameworks/av/media/libaaudio/src \ frameworks/av/media/libaaudio/examples/utils LOCAL_SRC_FILES:= frameworks/av/media/liboboe/src/write_sine.cpp LOCAL_SHARED_LIBRARIES := libaudioutils libmedia libtinyalsa \ libbinder libcutils libutils LOCAL_STATIC_LIBRARIES := libsndfile LOCAL_MODULE := write_sine_ndk LOCAL_SHARED_LIBRARIES += liboboe_prebuilt # NDK recommends using this kind of relative path instead of an absolute path. LOCAL_SRC_FILES:= ../src/input_monitor.cpp LOCAL_SHARED_LIBRARIES := libaaudio LOCAL_MODULE := input_monitor_ndk include $(BUILD_EXECUTABLE) include $(CLEAR_VARS) LOCAL_MODULE_TAGS := tests LOCAL_C_INCLUDES := \ $(call include-path-for, audio-utils) \ frameworks/av/media/liboboe/include frameworks/av/media/libaaudio/include \ frameworks/av/media/libaaudio/examples/utils LOCAL_SRC_FILES:= frameworks/av/media/liboboe/src/write_sine_threaded.cpp LOCAL_SHARED_LIBRARIES := libaudioutils libmedia libtinyalsa \ libbinder libcutils libutils LOCAL_STATIC_LIBRARIES := libsndfile LOCAL_MODULE := write_sine_threaded_ndk LOCAL_SHARED_LIBRARIES += liboboe_prebuilt LOCAL_SRC_FILES:= ../src/input_monitor_callback.cpp LOCAL_SHARED_LIBRARIES := libaaudio LOCAL_MODULE := input_monitor_callback_ndk include $(BUILD_EXECUTABLE) include $(CLEAR_VARS) LOCAL_MODULE := liboboe_prebuilt LOCAL_SRC_FILES := liboboe.so LOCAL_MODULE := libaaudio_prebuilt LOCAL_SRC_FILES := libaaudio.so LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include include $(PREBUILT_SHARED_LIBRARY) No newline at end of file media/libaaudio/examples/input_monitor/src/input_monitor.cpp +22 −48 Original line number Diff line number Diff line Loading @@ -22,36 +22,21 @@ #include <stdlib.h> #include <math.h> #include <aaudio/AAudio.h> #include "AAudioExampleUtils.h" #include "AAudioSimpleRecorder.h" #define SAMPLE_RATE 48000 #define NUM_SECONDS 5 #define NANOS_PER_MICROSECOND ((int64_t)1000) #define NANOS_PER_MILLISECOND (NANOS_PER_MICROSECOND * 1000) #define NANOS_PER_SECOND (NANOS_PER_MILLISECOND * 1000) #define MIN_FRAMES_TO_READ 48 /* arbitrary, 1 msec at 48000 Hz */ #define NUM_SECONDS 10 static const char *getSharingModeText(aaudio_sharing_mode_t mode) { const char *modeText = "unknown"; switch (mode) { case AAUDIO_SHARING_MODE_EXCLUSIVE: modeText = "EXCLUSIVE"; break; case AAUDIO_SHARING_MODE_SHARED: modeText = "SHARED"; break; default: break; } return modeText; } #define MIN_FRAMES_TO_READ 48 /* arbitrary, 1 msec at 48000 Hz */ int main(int argc, char **argv) { (void)argc; // unused aaudio_result_t result; AAudioSimpleRecorder recorder; int actualSamplesPerFrame; int actualSampleRate; const aaudio_audio_format_t requestedDataFormat = AAUDIO_FORMAT_PCM_I16; Loading @@ -66,7 +51,6 @@ int main(int argc, char **argv) //const aaudio_sharing_mode_t requestedSharingMode = AAUDIO_SHARING_MODE_EXCLUSIVE; aaudio_sharing_mode_t actualSharingMode; AAudioStreamBuilder *aaudioBuilder = nullptr; AAudioStream *aaudioStream = nullptr; aaudio_stream_state_t state; int32_t framesPerBurst = 0; Loading @@ -84,24 +68,16 @@ int main(int argc, char **argv) printf("%s - Monitor input level using AAudio\n", argv[0]); // Use an AAudioStreamBuilder to contain requested parameters. result = AAudio_createStreamBuilder(&aaudioBuilder); if (result != AAUDIO_OK) { goto finish; } // Request stream properties. AAudioStreamBuilder_setDirection(aaudioBuilder, AAUDIO_DIRECTION_INPUT); AAudioStreamBuilder_setFormat(aaudioBuilder, requestedDataFormat); AAudioStreamBuilder_setSharingMode(aaudioBuilder, requestedSharingMode); AAudioStreamBuilder_setPerformanceMode(aaudioBuilder, requestedPerformanceMode); AAudioStreamBuilder_setChannelCount(aaudioBuilder, requestedInputChannelCount); recorder.setPerformanceMode(requestedPerformanceMode); recorder.setSharingMode(requestedSharingMode); // Create an AAudioStream using the Builder. result = AAudioStreamBuilder_openStream(aaudioBuilder, &aaudioStream); result = recorder.open(requestedInputChannelCount, 48000, requestedDataFormat, nullptr, nullptr, nullptr); if (result != AAUDIO_OK) { fprintf(stderr, "ERROR - recorder.open() returned %d\n", result); goto finish; } aaudioStream = recorder.getStream(); actualSamplesPerFrame = AAudioStream_getSamplesPerFrame(aaudioStream); printf("SamplesPerFrame = %d\n", actualSamplesPerFrame); Loading Loading @@ -143,10 +119,9 @@ int main(int argc, char **argv) } // Start the stream. printf("call AAudioStream_requestStart()\n"); result = AAudioStream_requestStart(aaudioStream); result = recorder.start(); if (result != AAUDIO_OK) { fprintf(stderr, "ERROR - AAudioStream_requestStart() returned %d\n", result); fprintf(stderr, "ERROR - recorder.start() returned %d\n", result); goto finish; } Loading Loading @@ -181,12 +156,7 @@ int main(int argc, char **argv) // Display level as stars, eg. "******". if ((loopCounter++ % 10) == 0) { printf("%5.3f ", peakLevel); int numStars = (int)(peakLevel * 50); for (int i = 0; i < numStars; i++) { printf("*"); } printf("\n"); displayPeakLevel(peakLevel); peakLevel = 0.0; } } Loading @@ -194,9 +164,13 @@ int main(int argc, char **argv) xRunCount = AAudioStream_getXRunCount(aaudioStream); printf("AAudioStream_getXRunCount %d\n", xRunCount); result = recorder.stop(); if (result != AAUDIO_OK) { goto finish; } finish: AAudioStream_close(aaudioStream); AAudioStreamBuilder_delete(aaudioBuilder); recorder.close(); delete[] data; printf("exiting - AAudio result = %d = %s\n", result, AAudio_convertResultToText(result)); return (result != AAUDIO_OK) ? EXIT_FAILURE : EXIT_SUCCESS; Loading media/libaaudio/examples/input_monitor/src/input_monitor_callback.cpp +25 −218 Original line number Diff line number Diff line Loading @@ -23,229 +23,18 @@ #include <math.h> #include <time.h> #include <aaudio/AAudio.h> #include "AAudioExampleUtils.h" #include "AAudioSimpleRecorder.h" #define NUM_SECONDS 5 #define NANOS_PER_MICROSECOND ((int64_t)1000) #define NANOS_PER_MILLISECOND (NANOS_PER_MICROSECOND * 1000) #define NANOS_PER_SECOND (NANOS_PER_MILLISECOND * 1000) //#define SHARING_MODE AAUDIO_SHARING_MODE_EXCLUSIVE #define SHARING_MODE AAUDIO_SHARING_MODE_SHARED /** * Simple wrapper for AAudio that opens an input stream and then calls * a callback function to process the input data. */ class SimpleAAudioRecorder { public: SimpleAAudioRecorder() {} ~SimpleAAudioRecorder() { close(); }; /** * Call this before calling open(). * @param requestedSharingMode */ void setSharingMode(aaudio_sharing_mode_t requestedSharingMode) { mRequestedSharingMode = requestedSharingMode; } /** * Also known as "sample rate" * Only call this after open() has been called. */ int32_t getFramesPerSecond() { if (mStream == nullptr) { return AAUDIO_ERROR_INVALID_STATE; } return AAudioStream_getSampleRate(mStream);; } /** * Only call this after open() has been called. */ int32_t getSamplesPerFrame() { if (mStream == nullptr) { return AAUDIO_ERROR_INVALID_STATE; } return AAudioStream_getSamplesPerFrame(mStream);; } /** * Only call this after open() has been called. */ int64_t getFramesRead() { if (mStream == nullptr) { return AAUDIO_ERROR_INVALID_STATE; } return AAudioStream_getFramesRead(mStream);; } /** * Open a stream */ aaudio_result_t open(AAudioStream_dataCallback proc, void *userContext) { aaudio_result_t result = AAUDIO_OK; // Use an AAudioStreamBuilder to contain requested parameters. result = AAudio_createStreamBuilder(&mBuilder); if (result != AAUDIO_OK) return result; AAudioStreamBuilder_setDirection(mBuilder, AAUDIO_DIRECTION_INPUT); AAudioStreamBuilder_setSharingMode(mBuilder, mRequestedSharingMode); AAudioStreamBuilder_setDataCallback(mBuilder, proc, userContext); AAudioStreamBuilder_setFormat(mBuilder, AAUDIO_FORMAT_PCM_I16); // Open an AAudioStream using the Builder. result = AAudioStreamBuilder_openStream(mBuilder, &mStream); if (result != AAUDIO_OK) { fprintf(stderr, "ERROR - AAudioStreamBuilder_openStream() returned %d %s\n", result, AAudio_convertResultToText(result)); goto finish1; } printf("AAudioStream_getFramesPerBurst() = %d\n", AAudioStream_getFramesPerBurst(mStream)); printf("AAudioStream_getBufferSizeInFrames() = %d\n", AAudioStream_getBufferSizeInFrames(mStream)); printf("AAudioStream_getBufferCapacityInFrames() = %d\n", AAudioStream_getBufferCapacityInFrames(mStream)); return result; finish1: AAudioStreamBuilder_delete(mBuilder); mBuilder = nullptr; return result; } aaudio_result_t close() { if (mStream != nullptr) { printf("call AAudioStream_close(%p)\n", mStream); fflush(stdout); AAudioStream_close(mStream); mStream = nullptr; AAudioStreamBuilder_delete(mBuilder); mBuilder = nullptr; } return AAUDIO_OK; } // Write zero data to fill up the buffer and prevent underruns. aaudio_result_t prime() { int32_t samplesPerFrame = AAudioStream_getSamplesPerFrame(mStream); const int numFrames = 32; // arbitrary float zeros[numFrames * samplesPerFrame]; memset(zeros, 0, sizeof(zeros)); aaudio_result_t result = numFrames; while (result == numFrames) { result = AAudioStream_write(mStream, zeros, numFrames, 0); } return result; } // Start the stream. AAudio will start calling your callback function. aaudio_result_t start() { aaudio_result_t result = AAudioStream_requestStart(mStream); if (result != AAUDIO_OK) { fprintf(stderr, "ERROR - AAudioStream_requestStart() returned %d %s\n", result, AAudio_convertResultToText(result)); } return result; } // Stop the stream. AAudio will stop calling your callback function. aaudio_result_t stop() { aaudio_result_t result = AAudioStream_requestStop(mStream); if (result != AAUDIO_OK) { fprintf(stderr, "ERROR - AAudioStream_requestStop() returned %d %s\n", result, AAudio_convertResultToText(result)); } return result; } // Pause the stream. AAudio will stop calling your callback function. aaudio_result_t pause() { aaudio_result_t result = AAudioStream_requestPause(mStream); if (result != AAUDIO_OK) { fprintf(stderr, "ERROR - AAudioStream_requestPause() returned %d %s\n", result, AAudio_convertResultToText(result)); } return result; } private: AAudioStreamBuilder *mBuilder = nullptr; AAudioStream *mStream = nullptr; aaudio_sharing_mode_t mRequestedSharingMode = SHARING_MODE; }; // Application data that gets passed to the callback. typedef struct PeakTrackerData { float peakLevel; } PeakTrackerData_t; #define DECAY_FACTOR 0.999 // Callback function that fills the audio output buffer. aaudio_data_callback_result_t MyDataCallbackProc( AAudioStream *stream, void *userData, void *audioData, int32_t numFrames ) { PeakTrackerData_t *data = (PeakTrackerData_t *) userData; // printf("MyCallbackProc(): frameCount = %d\n", numFrames); int32_t samplesPerFrame = AAudioStream_getSamplesPerFrame(stream); float sample; // This code assume mono or stereo. switch (AAudioStream_getFormat(stream)) { case AAUDIO_FORMAT_PCM_I16: { int16_t *audioBuffer = (int16_t *) audioData; // Peak follower for (int frameIndex = 0; frameIndex < numFrames; frameIndex++) { sample = audioBuffer[frameIndex * samplesPerFrame] * (1.0/32768); data->peakLevel *= DECAY_FACTOR; if (sample > data->peakLevel) { data->peakLevel = sample; } } } break; case AAUDIO_FORMAT_PCM_FLOAT: { float *audioBuffer = (float *) audioData; // Peak follower for (int frameIndex = 0; frameIndex < numFrames; frameIndex++) { sample = audioBuffer[frameIndex * samplesPerFrame]; data->peakLevel *= DECAY_FACTOR; if (sample > data->peakLevel) { data->peakLevel = sample; } } } break; default: return AAUDIO_CALLBACK_RESULT_STOP; } return AAUDIO_CALLBACK_RESULT_CONTINUE; } void displayPeakLevel(float peakLevel) { printf("%5.3f ", peakLevel); const int maxStars = 50; // arbitrary, fits on one line int numStars = (int) (peakLevel * maxStars); for (int i = 0; i < numStars; i++) { printf("*"); } printf("\n"); } int main(int argc, char **argv) { (void)argc; // unused SimpleAAudioRecorder recorder; AAudioSimpleRecorder recorder; PeakTrackerData_t myData = {0.0}; aaudio_result_t result; aaudio_stream_state_t state; const int displayRateHz = 20; // arbitrary const int loopsNeeded = NUM_SECONDS * displayRateHz; Loading @@ -254,9 +43,8 @@ int main(int argc, char **argv) setvbuf(stdout, nullptr, _IONBF, (size_t) 0); printf("%s - Display audio input using an AAudio callback\n", argv[0]); recorder.setSharingMode(SHARING_MODE); result = recorder.open(MyDataCallbackProc, &myData); result = recorder.open(2, 48000, AAUDIO_FORMAT_PCM_I16, SimpleRecorderDataCallbackProc, SimpleRecorderErrorCallbackProc, &myData); if (result != AAUDIO_OK) { fprintf(stderr, "ERROR - recorder.open() returned %d\n", result); goto error; Loading @@ -278,6 +66,19 @@ int main(int argc, char **argv) (void) clock_nanosleep(CLOCK_MONOTONIC, 0 /*flags*/, &request, NULL /*remain*/); printf("%08d: ", (int)recorder.getFramesRead()); displayPeakLevel(myData.peakLevel); result = AAudioStream_waitForStateChange(recorder.getStream(), AAUDIO_STREAM_STATE_CLOSED, &state, 0); if (result != AAUDIO_OK) { fprintf(stderr, "ERROR - AAudioStream_waitForStateChange() returned %d\n", result); goto error; } if (state != AAUDIO_STREAM_STATE_STARTING && state != AAUDIO_STREAM_STATE_STARTED) { printf("Stream state is %d %s!\n", state, AAudio_convertStreamStateToText(state)); break; } } printf("Woke up. Stop for a moment.\n"); Loading @@ -300,6 +101,12 @@ int main(int argc, char **argv) (void) clock_nanosleep(CLOCK_MONOTONIC, 0 /*flags*/, &request, NULL /*remain*/); printf("%08d: ", (int)recorder.getFramesRead()); displayPeakLevel(myData.peakLevel); state = AAudioStream_getState(recorder.getStream()); if (state != AAUDIO_STREAM_STATE_STARTING && state != AAUDIO_STREAM_STATE_STARTED) { printf("Stream state is %d %s!\n", state, AAudio_convertStreamStateToText(state)); break; } } printf("Woke up now.\n"); Loading media/libaaudio/examples/input_monitor/static/Android.mk +4 −2 Original line number Diff line number Diff line Loading @@ -4,7 +4,8 @@ include $(CLEAR_VARS) LOCAL_MODULE_TAGS := examples LOCAL_C_INCLUDES := \ $(call include-path-for, audio-utils) \ frameworks/av/media/libaaudio/include frameworks/av/media/libaaudio/include \ frameworks/av/media/libaaudio/examples/utils # TODO reorganize folders to avoid using ../ LOCAL_SRC_FILES:= ../src/input_monitor.cpp Loading @@ -22,7 +23,8 @@ include $(CLEAR_VARS) LOCAL_MODULE_TAGS := tests LOCAL_C_INCLUDES := \ $(call include-path-for, audio-utils) \ frameworks/av/media/libaaudio/include frameworks/av/media/libaaudio/include \ frameworks/av/media/libaaudio/examples/utils LOCAL_SRC_FILES:= ../src/input_monitor_callback.cpp Loading media/libaaudio/examples/utils/AAudioExampleUtils.h 0 → 100644 +62 −0 Original line number Diff line number Diff line /* * Copyright (C) 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. */ #ifndef AAUDIO_EXAMPLE_UTILS_H #define AAUDIO_EXAMPLE_UTILS_H #include <unistd.h> #include <sched.h> #include <aaudio/AAudio.h> #define NANOS_PER_MICROSECOND ((int64_t)1000) #define NANOS_PER_MILLISECOND (NANOS_PER_MICROSECOND * 1000) #define NANOS_PER_SECOND (NANOS_PER_MILLISECOND * 1000) static const char *getSharingModeText(aaudio_sharing_mode_t mode) { const char *modeText = "unknown"; switch (mode) { case AAUDIO_SHARING_MODE_EXCLUSIVE: modeText = "EXCLUSIVE"; break; case AAUDIO_SHARING_MODE_SHARED: modeText = "SHARED"; break; default: break; } return modeText; } static int64_t getNanoseconds(clockid_t clockId = CLOCK_MONOTONIC) { struct timespec time; int result = clock_gettime(clockId, &time); if (result < 0) { return -errno; } return (time.tv_sec * NANOS_PER_SECOND) + time.tv_nsec; } void displayPeakLevel(float peakLevel) { printf("%5.3f ", peakLevel); const int maxStars = 50; // arbitrary, fits on one line int numStars = (int) (peakLevel * maxStars); for (int i = 0; i < numStars; i++) { printf("*"); } printf("\n"); } #endif // AAUDIO_EXAMPLE_UTILS_H Loading
media/libaaudio/examples/input_monitor/jni/Android.mk +15 −17 Original line number Diff line number Diff line Loading @@ -4,32 +4,30 @@ include $(CLEAR_VARS) LOCAL_MODULE_TAGS := tests LOCAL_C_INCLUDES := \ $(call include-path-for, audio-utils) \ frameworks/av/media/liboboe/include frameworks/av/media/libaaudio/include \ frameworks/av/media/libaaudio/src \ frameworks/av/media/libaaudio/examples/utils LOCAL_SRC_FILES:= frameworks/av/media/liboboe/src/write_sine.cpp LOCAL_SHARED_LIBRARIES := libaudioutils libmedia libtinyalsa \ libbinder libcutils libutils LOCAL_STATIC_LIBRARIES := libsndfile LOCAL_MODULE := write_sine_ndk LOCAL_SHARED_LIBRARIES += liboboe_prebuilt # NDK recommends using this kind of relative path instead of an absolute path. LOCAL_SRC_FILES:= ../src/input_monitor.cpp LOCAL_SHARED_LIBRARIES := libaaudio LOCAL_MODULE := input_monitor_ndk include $(BUILD_EXECUTABLE) include $(CLEAR_VARS) LOCAL_MODULE_TAGS := tests LOCAL_C_INCLUDES := \ $(call include-path-for, audio-utils) \ frameworks/av/media/liboboe/include frameworks/av/media/libaaudio/include \ frameworks/av/media/libaaudio/examples/utils LOCAL_SRC_FILES:= frameworks/av/media/liboboe/src/write_sine_threaded.cpp LOCAL_SHARED_LIBRARIES := libaudioutils libmedia libtinyalsa \ libbinder libcutils libutils LOCAL_STATIC_LIBRARIES := libsndfile LOCAL_MODULE := write_sine_threaded_ndk LOCAL_SHARED_LIBRARIES += liboboe_prebuilt LOCAL_SRC_FILES:= ../src/input_monitor_callback.cpp LOCAL_SHARED_LIBRARIES := libaaudio LOCAL_MODULE := input_monitor_callback_ndk include $(BUILD_EXECUTABLE) include $(CLEAR_VARS) LOCAL_MODULE := liboboe_prebuilt LOCAL_SRC_FILES := liboboe.so LOCAL_MODULE := libaaudio_prebuilt LOCAL_SRC_FILES := libaaudio.so LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include include $(PREBUILT_SHARED_LIBRARY) No newline at end of file
media/libaaudio/examples/input_monitor/src/input_monitor.cpp +22 −48 Original line number Diff line number Diff line Loading @@ -22,36 +22,21 @@ #include <stdlib.h> #include <math.h> #include <aaudio/AAudio.h> #include "AAudioExampleUtils.h" #include "AAudioSimpleRecorder.h" #define SAMPLE_RATE 48000 #define NUM_SECONDS 5 #define NANOS_PER_MICROSECOND ((int64_t)1000) #define NANOS_PER_MILLISECOND (NANOS_PER_MICROSECOND * 1000) #define NANOS_PER_SECOND (NANOS_PER_MILLISECOND * 1000) #define MIN_FRAMES_TO_READ 48 /* arbitrary, 1 msec at 48000 Hz */ #define NUM_SECONDS 10 static const char *getSharingModeText(aaudio_sharing_mode_t mode) { const char *modeText = "unknown"; switch (mode) { case AAUDIO_SHARING_MODE_EXCLUSIVE: modeText = "EXCLUSIVE"; break; case AAUDIO_SHARING_MODE_SHARED: modeText = "SHARED"; break; default: break; } return modeText; } #define MIN_FRAMES_TO_READ 48 /* arbitrary, 1 msec at 48000 Hz */ int main(int argc, char **argv) { (void)argc; // unused aaudio_result_t result; AAudioSimpleRecorder recorder; int actualSamplesPerFrame; int actualSampleRate; const aaudio_audio_format_t requestedDataFormat = AAUDIO_FORMAT_PCM_I16; Loading @@ -66,7 +51,6 @@ int main(int argc, char **argv) //const aaudio_sharing_mode_t requestedSharingMode = AAUDIO_SHARING_MODE_EXCLUSIVE; aaudio_sharing_mode_t actualSharingMode; AAudioStreamBuilder *aaudioBuilder = nullptr; AAudioStream *aaudioStream = nullptr; aaudio_stream_state_t state; int32_t framesPerBurst = 0; Loading @@ -84,24 +68,16 @@ int main(int argc, char **argv) printf("%s - Monitor input level using AAudio\n", argv[0]); // Use an AAudioStreamBuilder to contain requested parameters. result = AAudio_createStreamBuilder(&aaudioBuilder); if (result != AAUDIO_OK) { goto finish; } // Request stream properties. AAudioStreamBuilder_setDirection(aaudioBuilder, AAUDIO_DIRECTION_INPUT); AAudioStreamBuilder_setFormat(aaudioBuilder, requestedDataFormat); AAudioStreamBuilder_setSharingMode(aaudioBuilder, requestedSharingMode); AAudioStreamBuilder_setPerformanceMode(aaudioBuilder, requestedPerformanceMode); AAudioStreamBuilder_setChannelCount(aaudioBuilder, requestedInputChannelCount); recorder.setPerformanceMode(requestedPerformanceMode); recorder.setSharingMode(requestedSharingMode); // Create an AAudioStream using the Builder. result = AAudioStreamBuilder_openStream(aaudioBuilder, &aaudioStream); result = recorder.open(requestedInputChannelCount, 48000, requestedDataFormat, nullptr, nullptr, nullptr); if (result != AAUDIO_OK) { fprintf(stderr, "ERROR - recorder.open() returned %d\n", result); goto finish; } aaudioStream = recorder.getStream(); actualSamplesPerFrame = AAudioStream_getSamplesPerFrame(aaudioStream); printf("SamplesPerFrame = %d\n", actualSamplesPerFrame); Loading Loading @@ -143,10 +119,9 @@ int main(int argc, char **argv) } // Start the stream. printf("call AAudioStream_requestStart()\n"); result = AAudioStream_requestStart(aaudioStream); result = recorder.start(); if (result != AAUDIO_OK) { fprintf(stderr, "ERROR - AAudioStream_requestStart() returned %d\n", result); fprintf(stderr, "ERROR - recorder.start() returned %d\n", result); goto finish; } Loading Loading @@ -181,12 +156,7 @@ int main(int argc, char **argv) // Display level as stars, eg. "******". if ((loopCounter++ % 10) == 0) { printf("%5.3f ", peakLevel); int numStars = (int)(peakLevel * 50); for (int i = 0; i < numStars; i++) { printf("*"); } printf("\n"); displayPeakLevel(peakLevel); peakLevel = 0.0; } } Loading @@ -194,9 +164,13 @@ int main(int argc, char **argv) xRunCount = AAudioStream_getXRunCount(aaudioStream); printf("AAudioStream_getXRunCount %d\n", xRunCount); result = recorder.stop(); if (result != AAUDIO_OK) { goto finish; } finish: AAudioStream_close(aaudioStream); AAudioStreamBuilder_delete(aaudioBuilder); recorder.close(); delete[] data; printf("exiting - AAudio result = %d = %s\n", result, AAudio_convertResultToText(result)); return (result != AAUDIO_OK) ? EXIT_FAILURE : EXIT_SUCCESS; Loading
media/libaaudio/examples/input_monitor/src/input_monitor_callback.cpp +25 −218 Original line number Diff line number Diff line Loading @@ -23,229 +23,18 @@ #include <math.h> #include <time.h> #include <aaudio/AAudio.h> #include "AAudioExampleUtils.h" #include "AAudioSimpleRecorder.h" #define NUM_SECONDS 5 #define NANOS_PER_MICROSECOND ((int64_t)1000) #define NANOS_PER_MILLISECOND (NANOS_PER_MICROSECOND * 1000) #define NANOS_PER_SECOND (NANOS_PER_MILLISECOND * 1000) //#define SHARING_MODE AAUDIO_SHARING_MODE_EXCLUSIVE #define SHARING_MODE AAUDIO_SHARING_MODE_SHARED /** * Simple wrapper for AAudio that opens an input stream and then calls * a callback function to process the input data. */ class SimpleAAudioRecorder { public: SimpleAAudioRecorder() {} ~SimpleAAudioRecorder() { close(); }; /** * Call this before calling open(). * @param requestedSharingMode */ void setSharingMode(aaudio_sharing_mode_t requestedSharingMode) { mRequestedSharingMode = requestedSharingMode; } /** * Also known as "sample rate" * Only call this after open() has been called. */ int32_t getFramesPerSecond() { if (mStream == nullptr) { return AAUDIO_ERROR_INVALID_STATE; } return AAudioStream_getSampleRate(mStream);; } /** * Only call this after open() has been called. */ int32_t getSamplesPerFrame() { if (mStream == nullptr) { return AAUDIO_ERROR_INVALID_STATE; } return AAudioStream_getSamplesPerFrame(mStream);; } /** * Only call this after open() has been called. */ int64_t getFramesRead() { if (mStream == nullptr) { return AAUDIO_ERROR_INVALID_STATE; } return AAudioStream_getFramesRead(mStream);; } /** * Open a stream */ aaudio_result_t open(AAudioStream_dataCallback proc, void *userContext) { aaudio_result_t result = AAUDIO_OK; // Use an AAudioStreamBuilder to contain requested parameters. result = AAudio_createStreamBuilder(&mBuilder); if (result != AAUDIO_OK) return result; AAudioStreamBuilder_setDirection(mBuilder, AAUDIO_DIRECTION_INPUT); AAudioStreamBuilder_setSharingMode(mBuilder, mRequestedSharingMode); AAudioStreamBuilder_setDataCallback(mBuilder, proc, userContext); AAudioStreamBuilder_setFormat(mBuilder, AAUDIO_FORMAT_PCM_I16); // Open an AAudioStream using the Builder. result = AAudioStreamBuilder_openStream(mBuilder, &mStream); if (result != AAUDIO_OK) { fprintf(stderr, "ERROR - AAudioStreamBuilder_openStream() returned %d %s\n", result, AAudio_convertResultToText(result)); goto finish1; } printf("AAudioStream_getFramesPerBurst() = %d\n", AAudioStream_getFramesPerBurst(mStream)); printf("AAudioStream_getBufferSizeInFrames() = %d\n", AAudioStream_getBufferSizeInFrames(mStream)); printf("AAudioStream_getBufferCapacityInFrames() = %d\n", AAudioStream_getBufferCapacityInFrames(mStream)); return result; finish1: AAudioStreamBuilder_delete(mBuilder); mBuilder = nullptr; return result; } aaudio_result_t close() { if (mStream != nullptr) { printf("call AAudioStream_close(%p)\n", mStream); fflush(stdout); AAudioStream_close(mStream); mStream = nullptr; AAudioStreamBuilder_delete(mBuilder); mBuilder = nullptr; } return AAUDIO_OK; } // Write zero data to fill up the buffer and prevent underruns. aaudio_result_t prime() { int32_t samplesPerFrame = AAudioStream_getSamplesPerFrame(mStream); const int numFrames = 32; // arbitrary float zeros[numFrames * samplesPerFrame]; memset(zeros, 0, sizeof(zeros)); aaudio_result_t result = numFrames; while (result == numFrames) { result = AAudioStream_write(mStream, zeros, numFrames, 0); } return result; } // Start the stream. AAudio will start calling your callback function. aaudio_result_t start() { aaudio_result_t result = AAudioStream_requestStart(mStream); if (result != AAUDIO_OK) { fprintf(stderr, "ERROR - AAudioStream_requestStart() returned %d %s\n", result, AAudio_convertResultToText(result)); } return result; } // Stop the stream. AAudio will stop calling your callback function. aaudio_result_t stop() { aaudio_result_t result = AAudioStream_requestStop(mStream); if (result != AAUDIO_OK) { fprintf(stderr, "ERROR - AAudioStream_requestStop() returned %d %s\n", result, AAudio_convertResultToText(result)); } return result; } // Pause the stream. AAudio will stop calling your callback function. aaudio_result_t pause() { aaudio_result_t result = AAudioStream_requestPause(mStream); if (result != AAUDIO_OK) { fprintf(stderr, "ERROR - AAudioStream_requestPause() returned %d %s\n", result, AAudio_convertResultToText(result)); } return result; } private: AAudioStreamBuilder *mBuilder = nullptr; AAudioStream *mStream = nullptr; aaudio_sharing_mode_t mRequestedSharingMode = SHARING_MODE; }; // Application data that gets passed to the callback. typedef struct PeakTrackerData { float peakLevel; } PeakTrackerData_t; #define DECAY_FACTOR 0.999 // Callback function that fills the audio output buffer. aaudio_data_callback_result_t MyDataCallbackProc( AAudioStream *stream, void *userData, void *audioData, int32_t numFrames ) { PeakTrackerData_t *data = (PeakTrackerData_t *) userData; // printf("MyCallbackProc(): frameCount = %d\n", numFrames); int32_t samplesPerFrame = AAudioStream_getSamplesPerFrame(stream); float sample; // This code assume mono or stereo. switch (AAudioStream_getFormat(stream)) { case AAUDIO_FORMAT_PCM_I16: { int16_t *audioBuffer = (int16_t *) audioData; // Peak follower for (int frameIndex = 0; frameIndex < numFrames; frameIndex++) { sample = audioBuffer[frameIndex * samplesPerFrame] * (1.0/32768); data->peakLevel *= DECAY_FACTOR; if (sample > data->peakLevel) { data->peakLevel = sample; } } } break; case AAUDIO_FORMAT_PCM_FLOAT: { float *audioBuffer = (float *) audioData; // Peak follower for (int frameIndex = 0; frameIndex < numFrames; frameIndex++) { sample = audioBuffer[frameIndex * samplesPerFrame]; data->peakLevel *= DECAY_FACTOR; if (sample > data->peakLevel) { data->peakLevel = sample; } } } break; default: return AAUDIO_CALLBACK_RESULT_STOP; } return AAUDIO_CALLBACK_RESULT_CONTINUE; } void displayPeakLevel(float peakLevel) { printf("%5.3f ", peakLevel); const int maxStars = 50; // arbitrary, fits on one line int numStars = (int) (peakLevel * maxStars); for (int i = 0; i < numStars; i++) { printf("*"); } printf("\n"); } int main(int argc, char **argv) { (void)argc; // unused SimpleAAudioRecorder recorder; AAudioSimpleRecorder recorder; PeakTrackerData_t myData = {0.0}; aaudio_result_t result; aaudio_stream_state_t state; const int displayRateHz = 20; // arbitrary const int loopsNeeded = NUM_SECONDS * displayRateHz; Loading @@ -254,9 +43,8 @@ int main(int argc, char **argv) setvbuf(stdout, nullptr, _IONBF, (size_t) 0); printf("%s - Display audio input using an AAudio callback\n", argv[0]); recorder.setSharingMode(SHARING_MODE); result = recorder.open(MyDataCallbackProc, &myData); result = recorder.open(2, 48000, AAUDIO_FORMAT_PCM_I16, SimpleRecorderDataCallbackProc, SimpleRecorderErrorCallbackProc, &myData); if (result != AAUDIO_OK) { fprintf(stderr, "ERROR - recorder.open() returned %d\n", result); goto error; Loading @@ -278,6 +66,19 @@ int main(int argc, char **argv) (void) clock_nanosleep(CLOCK_MONOTONIC, 0 /*flags*/, &request, NULL /*remain*/); printf("%08d: ", (int)recorder.getFramesRead()); displayPeakLevel(myData.peakLevel); result = AAudioStream_waitForStateChange(recorder.getStream(), AAUDIO_STREAM_STATE_CLOSED, &state, 0); if (result != AAUDIO_OK) { fprintf(stderr, "ERROR - AAudioStream_waitForStateChange() returned %d\n", result); goto error; } if (state != AAUDIO_STREAM_STATE_STARTING && state != AAUDIO_STREAM_STATE_STARTED) { printf("Stream state is %d %s!\n", state, AAudio_convertStreamStateToText(state)); break; } } printf("Woke up. Stop for a moment.\n"); Loading @@ -300,6 +101,12 @@ int main(int argc, char **argv) (void) clock_nanosleep(CLOCK_MONOTONIC, 0 /*flags*/, &request, NULL /*remain*/); printf("%08d: ", (int)recorder.getFramesRead()); displayPeakLevel(myData.peakLevel); state = AAudioStream_getState(recorder.getStream()); if (state != AAUDIO_STREAM_STATE_STARTING && state != AAUDIO_STREAM_STATE_STARTED) { printf("Stream state is %d %s!\n", state, AAudio_convertStreamStateToText(state)); break; } } printf("Woke up now.\n"); Loading
media/libaaudio/examples/input_monitor/static/Android.mk +4 −2 Original line number Diff line number Diff line Loading @@ -4,7 +4,8 @@ include $(CLEAR_VARS) LOCAL_MODULE_TAGS := examples LOCAL_C_INCLUDES := \ $(call include-path-for, audio-utils) \ frameworks/av/media/libaaudio/include frameworks/av/media/libaaudio/include \ frameworks/av/media/libaaudio/examples/utils # TODO reorganize folders to avoid using ../ LOCAL_SRC_FILES:= ../src/input_monitor.cpp Loading @@ -22,7 +23,8 @@ include $(CLEAR_VARS) LOCAL_MODULE_TAGS := tests LOCAL_C_INCLUDES := \ $(call include-path-for, audio-utils) \ frameworks/av/media/libaaudio/include frameworks/av/media/libaaudio/include \ frameworks/av/media/libaaudio/examples/utils LOCAL_SRC_FILES:= ../src/input_monitor_callback.cpp Loading
media/libaaudio/examples/utils/AAudioExampleUtils.h 0 → 100644 +62 −0 Original line number Diff line number Diff line /* * Copyright (C) 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. */ #ifndef AAUDIO_EXAMPLE_UTILS_H #define AAUDIO_EXAMPLE_UTILS_H #include <unistd.h> #include <sched.h> #include <aaudio/AAudio.h> #define NANOS_PER_MICROSECOND ((int64_t)1000) #define NANOS_PER_MILLISECOND (NANOS_PER_MICROSECOND * 1000) #define NANOS_PER_SECOND (NANOS_PER_MILLISECOND * 1000) static const char *getSharingModeText(aaudio_sharing_mode_t mode) { const char *modeText = "unknown"; switch (mode) { case AAUDIO_SHARING_MODE_EXCLUSIVE: modeText = "EXCLUSIVE"; break; case AAUDIO_SHARING_MODE_SHARED: modeText = "SHARED"; break; default: break; } return modeText; } static int64_t getNanoseconds(clockid_t clockId = CLOCK_MONOTONIC) { struct timespec time; int result = clock_gettime(clockId, &time); if (result < 0) { return -errno; } return (time.tv_sec * NANOS_PER_SECOND) + time.tv_nsec; } void displayPeakLevel(float peakLevel) { printf("%5.3f ", peakLevel); const int maxStars = 50; // arbitrary, fits on one line int numStars = (int) (peakLevel * maxStars); for (int i = 0; i < numStars; i++) { printf("*"); } printf("\n"); } #endif // AAUDIO_EXAMPLE_UTILS_H