Loading media/libaaudio/examples/utils/AAudioArgsParser.h +3 −1 Original line number Diff line number Diff line Loading @@ -421,7 +421,9 @@ public: printf(" -f{0|1|2} set format\n"); printf(" 0 = UNSPECIFIED\n"); printf(" 1 = PCM_I16\n"); printf(" 2 = FLOAT\n"); printf(" 2 = PCM_FLOAT\n"); printf(" 3 = PCM_I24_PACKED\n"); printf(" 4 = PCM_I32\n"); printf(" -i{inputPreset} eg. 5 for AAUDIO_INPUT_PRESET_CAMCORDER\n"); printf(" -m{0|1|2|3} set MMAP policy\n"); printf(" 0 = _UNSPECIFIED, use aaudio.mmap_policy system property, default\n"); Loading media/libaaudio/examples/utils/AAudioExampleUtils.h +26 −0 Original line number Diff line number Diff line Loading @@ -32,6 +32,7 @@ #define NANOS_PER_MILLISECOND (NANOS_PER_MICROSECOND * 1000) #define NANOS_PER_SECOND (NANOS_PER_MILLISECOND * 1000) // Use template functions to avoid warning of unused static functions. template <class T = aaudio_sharing_mode_t> const char *getSharingModeText(aaudio_sharing_mode_t mode) { const char *text = "unknown"; Loading @@ -48,6 +49,7 @@ const char *getSharingModeText(aaudio_sharing_mode_t mode) { return text; } template <class T = aaudio_performance_mode_t> const char *getPerformanceModeText(aaudio_performance_mode_t mode) { const char *text = "unknown"; switch (mode) { Loading @@ -66,6 +68,7 @@ const char *getPerformanceModeText(aaudio_performance_mode_t mode) { return text; } template <class T = aaudio_direction_t> const char *getDirectionText(aaudio_direction_t direction) { const char *text = "unknown"; switch (direction) { Loading @@ -81,6 +84,29 @@ const char *getDirectionText(aaudio_direction_t direction) { return text; } template <class T = aaudio_direction_t> constexpr int32_t getBytesPerSample(aaudio_format_t format) { switch (format) { case AAUDIO_FORMAT_PCM_I16: return 2; case AAUDIO_FORMAT_PCM_FLOAT: return 4; case AAUDIO_FORMAT_PCM_I24_PACKED: return 3; case AAUDIO_FORMAT_PCM_I32: return 4; default: return -1; } } // Return true if CPU is native Little Endian inline bool isNativeLittleEndian() { // If the first byte of the data word in memory is 1 then Little Endian. constexpr union { unsigned u; unsigned char c[sizeof(unsigned)]; } one = {1}; return one.c[0] != 0; } template <class T = int64_t> void convertNanosecondsToTimespec(int64_t nanoseconds, struct timespec *time) { time->tv_sec = nanoseconds / NANOS_PER_SECOND; Loading media/libaaudio/examples/utils/AAudioSimplePlayer.h +24 −8 Original line number Diff line number Diff line Loading @@ -359,22 +359,38 @@ aaudio_data_callback_result_t SimplePlayerDataCallbackProc( int32_t samplesPerFrame = AAudioStream_getChannelCount(stream); int numActiveOscilators = (samplesPerFrame > MAX_CHANNELS) ? MAX_CHANNELS : samplesPerFrame; int numActiveOscillators = std::min(samplesPerFrame, MAX_CHANNELS); switch (AAudioStream_getFormat(stream)) { case AAUDIO_FORMAT_PCM_I16: { int16_t *audioBuffer = (int16_t *) audioData; for (int i = 0; i < numActiveOscilators; ++i) { sineData->sineOscillators[i].render(&audioBuffer[i], samplesPerFrame, numFrames); for (int i = 0; i < numActiveOscillators; ++i) { sineData->sineOscillators[i].render(&audioBuffer[i], samplesPerFrame, numFrames); } } break; case AAUDIO_FORMAT_PCM_FLOAT: { float *audioBuffer = (float *) audioData; for (int i = 0; i < numActiveOscilators; ++i) { sineData->sineOscillators[i].render(&audioBuffer[i], samplesPerFrame, numFrames); for (int i = 0; i < numActiveOscillators; ++i) { sineData->sineOscillators[i].render(&audioBuffer[i], samplesPerFrame, numFrames); } } break; case AAUDIO_FORMAT_PCM_I24_PACKED: { uint8_t *audioBuffer = (uint8_t *) audioData; for (int i = 0; i < numActiveOscillators; ++i) { static const int bytesPerSample = getBytesPerSample(AAUDIO_FORMAT_PCM_I24_PACKED); sineData->sineOscillators[i].render24(&audioBuffer[i * bytesPerSample], samplesPerFrame, numFrames); } } break; case AAUDIO_FORMAT_PCM_I32: { int32_t *audioBuffer = (int32_t *) audioData; for (int i = 0; i < numActiveOscillators; ++i) { sineData->sineOscillators[i].render(&audioBuffer[i], samplesPerFrame, numFrames); } } break; Loading media/libaaudio/examples/utils/SineGenerator.h +38 −5 Original line number Diff line number Diff line Loading @@ -41,20 +41,54 @@ public: } } float next() { float value = sinf(mPhase) * mAmplitude; advancePhase(); return value; } void render(int16_t *buffer, int32_t channelStride, int32_t numFrames) { int sampleIndex = 0; for (int i = 0; i < numFrames; i++) { buffer[sampleIndex] = (int16_t) (INT16_MAX * sin(mPhase) * mAmplitude); buffer[sampleIndex] = (int16_t) (INT16_MAX * next()); sampleIndex += channelStride; advancePhase(); } } void render(float *buffer, int32_t channelStride, int32_t numFrames) { int sampleIndex = 0; for (int i = 0; i < numFrames; i++) { buffer[sampleIndex] = sin(mPhase) * mAmplitude; buffer[sampleIndex] = next(); sampleIndex += channelStride; advancePhase(); } } void render(int32_t *buffer, int32_t channelStride, int32_t numFrames) { int sampleIndex = 0; for (int i = 0; i < numFrames; i++) { buffer[sampleIndex] = (int32_t) (INT32_MAX * next()); sampleIndex += channelStride; } } void render24(uint8_t *buffer, int32_t channelStride, int32_t numFrames) { int sampleIndex = 0; constexpr int32_t INT24_MAX = (1 << 23) - 1; constexpr int bytesPerSample = getBytesPerSample(AAUDIO_FORMAT_PCM_I24_PACKED); const bool isLittleEndian = isNativeLittleEndian(); for (int i = 0; i < numFrames; i++) { int32_t sample = (int32_t) (INT24_MAX * next()); uint32_t usample = (uint32_t) sample; if (isLittleEndian) { buffer[sampleIndex] = usample; // little end first buffer[sampleIndex + 1] = usample >> 8; buffer[sampleIndex + 2] = usample >> 16; } else { buffer[sampleIndex] = usample >> 16; // big end first buffer[sampleIndex + 1] = usample >> 8; buffer[sampleIndex + 2] = usample; } sampleIndex += channelStride * bytesPerSample; } } Loading Loading @@ -100,4 +134,3 @@ private: }; #endif /* SINE_GENERATOR_H */ media/libaaudio/examples/write_sine/src/write_sine.cpp +65 −24 Original line number Diff line number Diff line Loading @@ -47,9 +47,11 @@ int main(int argc, const char **argv) int32_t framesToPlay = 0; int32_t framesLeft = 0; int32_t xRunCount = 0; int numActiveOscilators = 0; int numActiveOscillators = 0; float *floatData = nullptr; int16_t *shortData = nullptr; int32_t *int32Data = nullptr; uint8_t *byteData = nullptr; int testFd = -1; Loading @@ -57,7 +59,7 @@ int main(int argc, const char **argv) // in a buffer if we hang or crash. setvbuf(stdout, nullptr, _IONBF, (size_t) 0); printf("%s - Play a sine wave using AAudio V0.1.3\n", argv[0]); printf("%s - Play a sine wave using AAudio V0.1.4\n", argv[0]); if (argParser.parseArgs(argc, argv)) { return EXIT_FAILURE; Loading Loading @@ -91,11 +93,21 @@ int main(int argc, const char **argv) printf("Buffer: framesPerWrite = %d\n",framesPerWrite); // Allocate a buffer for the audio data. if (actualDataFormat == AAUDIO_FORMAT_PCM_FLOAT) { switch (actualDataFormat) { case AAUDIO_FORMAT_PCM_FLOAT: floatData = new float[framesPerWrite * actualChannelCount]; } else if (actualDataFormat == AAUDIO_FORMAT_PCM_I16) { break; case AAUDIO_FORMAT_PCM_I16: shortData = new int16_t[framesPerWrite * actualChannelCount]; } else { break; case AAUDIO_FORMAT_PCM_I24_PACKED: byteData = new uint8_t[framesPerWrite * actualChannelCount * getBytesPerSample(AAUDIO_FORMAT_PCM_I24_PACKED)]; break; case AAUDIO_FORMAT_PCM_I32: int32Data = new int32_t[framesPerWrite * actualChannelCount]; break; default: printf("ERROR Unsupported data format!\n"); goto finish; } Loading @@ -117,29 +129,56 @@ int main(int argc, const char **argv) // Play for a while. framesToPlay = actualSampleRate * argParser.getDurationSeconds(); framesLeft = framesToPlay; numActiveOscilators = (actualChannelCount > MAX_CHANNELS) ? MAX_CHANNELS : actualChannelCount; numActiveOscillators = (actualChannelCount > MAX_CHANNELS) ? MAX_CHANNELS : actualChannelCount; while (framesLeft > 0) { // Render as FLOAT or PCM if (actualDataFormat == AAUDIO_FORMAT_PCM_FLOAT) { for (int i = 0; i < numActiveOscilators; ++i) { switch (actualDataFormat) { case AAUDIO_FORMAT_PCM_FLOAT: for (int i = 0; i < numActiveOscillators; ++i) { myData.sineOscillators[i].render(&floatData[i], actualChannelCount, framesPerWrite); } } else if (actualDataFormat == AAUDIO_FORMAT_PCM_I16) { for (int i = 0; i < numActiveOscilators; ++i) { break; case AAUDIO_FORMAT_PCM_I16: for (int i = 0; i < numActiveOscillators; ++i) { myData.sineOscillators[i].render(&shortData[i], actualChannelCount, framesPerWrite); } break; case AAUDIO_FORMAT_PCM_I32: for (int i = 0; i < numActiveOscillators; ++i) { myData.sineOscillators[i].render(&int32Data[i], actualChannelCount, framesPerWrite); } break; case AAUDIO_FORMAT_PCM_I24_PACKED: for (int i = 0; i < numActiveOscillators; ++i) { static const int bytesPerSample = getBytesPerSample(AAUDIO_FORMAT_PCM_I24_PACKED); myData.sineOscillators[i].render24(&byteData[i * bytesPerSample], actualChannelCount, framesPerWrite); } break; } // Write audio data to the stream. int64_t timeoutNanos = 1000 * NANOS_PER_MILLISECOND; int32_t minFrames = (framesToPlay < framesPerWrite) ? framesToPlay : framesPerWrite; int32_t actual = 0; if (actualDataFormat == AAUDIO_FORMAT_PCM_FLOAT) { switch (actualDataFormat) { case AAUDIO_FORMAT_PCM_FLOAT: actual = AAudioStream_write(aaudioStream, floatData, minFrames, timeoutNanos); } else if (actualDataFormat == AAUDIO_FORMAT_PCM_I16) { break; case AAUDIO_FORMAT_PCM_I16: actual = AAudioStream_write(aaudioStream, shortData, minFrames, timeoutNanos); break; case AAUDIO_FORMAT_PCM_I32: actual = AAudioStream_write(aaudioStream, int32Data, minFrames, timeoutNanos); break; case AAUDIO_FORMAT_PCM_I24_PACKED: actual = AAudioStream_write(aaudioStream, byteData, minFrames, timeoutNanos); break; } if (actual < 0) { fprintf(stderr, "ERROR - AAudioStream_write() returned %d\n", actual); Loading Loading @@ -196,6 +235,8 @@ finish: delete[] floatData; delete[] shortData; delete[] int32Data; delete[] byteData; printf("exiting - AAudio result = %d = %s\n", result, AAudio_convertResultToText(result)); return (result != AAUDIO_OK) ? EXIT_FAILURE : EXIT_SUCCESS; } Loading Loading
media/libaaudio/examples/utils/AAudioArgsParser.h +3 −1 Original line number Diff line number Diff line Loading @@ -421,7 +421,9 @@ public: printf(" -f{0|1|2} set format\n"); printf(" 0 = UNSPECIFIED\n"); printf(" 1 = PCM_I16\n"); printf(" 2 = FLOAT\n"); printf(" 2 = PCM_FLOAT\n"); printf(" 3 = PCM_I24_PACKED\n"); printf(" 4 = PCM_I32\n"); printf(" -i{inputPreset} eg. 5 for AAUDIO_INPUT_PRESET_CAMCORDER\n"); printf(" -m{0|1|2|3} set MMAP policy\n"); printf(" 0 = _UNSPECIFIED, use aaudio.mmap_policy system property, default\n"); Loading
media/libaaudio/examples/utils/AAudioExampleUtils.h +26 −0 Original line number Diff line number Diff line Loading @@ -32,6 +32,7 @@ #define NANOS_PER_MILLISECOND (NANOS_PER_MICROSECOND * 1000) #define NANOS_PER_SECOND (NANOS_PER_MILLISECOND * 1000) // Use template functions to avoid warning of unused static functions. template <class T = aaudio_sharing_mode_t> const char *getSharingModeText(aaudio_sharing_mode_t mode) { const char *text = "unknown"; Loading @@ -48,6 +49,7 @@ const char *getSharingModeText(aaudio_sharing_mode_t mode) { return text; } template <class T = aaudio_performance_mode_t> const char *getPerformanceModeText(aaudio_performance_mode_t mode) { const char *text = "unknown"; switch (mode) { Loading @@ -66,6 +68,7 @@ const char *getPerformanceModeText(aaudio_performance_mode_t mode) { return text; } template <class T = aaudio_direction_t> const char *getDirectionText(aaudio_direction_t direction) { const char *text = "unknown"; switch (direction) { Loading @@ -81,6 +84,29 @@ const char *getDirectionText(aaudio_direction_t direction) { return text; } template <class T = aaudio_direction_t> constexpr int32_t getBytesPerSample(aaudio_format_t format) { switch (format) { case AAUDIO_FORMAT_PCM_I16: return 2; case AAUDIO_FORMAT_PCM_FLOAT: return 4; case AAUDIO_FORMAT_PCM_I24_PACKED: return 3; case AAUDIO_FORMAT_PCM_I32: return 4; default: return -1; } } // Return true if CPU is native Little Endian inline bool isNativeLittleEndian() { // If the first byte of the data word in memory is 1 then Little Endian. constexpr union { unsigned u; unsigned char c[sizeof(unsigned)]; } one = {1}; return one.c[0] != 0; } template <class T = int64_t> void convertNanosecondsToTimespec(int64_t nanoseconds, struct timespec *time) { time->tv_sec = nanoseconds / NANOS_PER_SECOND; Loading
media/libaaudio/examples/utils/AAudioSimplePlayer.h +24 −8 Original line number Diff line number Diff line Loading @@ -359,22 +359,38 @@ aaudio_data_callback_result_t SimplePlayerDataCallbackProc( int32_t samplesPerFrame = AAudioStream_getChannelCount(stream); int numActiveOscilators = (samplesPerFrame > MAX_CHANNELS) ? MAX_CHANNELS : samplesPerFrame; int numActiveOscillators = std::min(samplesPerFrame, MAX_CHANNELS); switch (AAudioStream_getFormat(stream)) { case AAUDIO_FORMAT_PCM_I16: { int16_t *audioBuffer = (int16_t *) audioData; for (int i = 0; i < numActiveOscilators; ++i) { sineData->sineOscillators[i].render(&audioBuffer[i], samplesPerFrame, numFrames); for (int i = 0; i < numActiveOscillators; ++i) { sineData->sineOscillators[i].render(&audioBuffer[i], samplesPerFrame, numFrames); } } break; case AAUDIO_FORMAT_PCM_FLOAT: { float *audioBuffer = (float *) audioData; for (int i = 0; i < numActiveOscilators; ++i) { sineData->sineOscillators[i].render(&audioBuffer[i], samplesPerFrame, numFrames); for (int i = 0; i < numActiveOscillators; ++i) { sineData->sineOscillators[i].render(&audioBuffer[i], samplesPerFrame, numFrames); } } break; case AAUDIO_FORMAT_PCM_I24_PACKED: { uint8_t *audioBuffer = (uint8_t *) audioData; for (int i = 0; i < numActiveOscillators; ++i) { static const int bytesPerSample = getBytesPerSample(AAUDIO_FORMAT_PCM_I24_PACKED); sineData->sineOscillators[i].render24(&audioBuffer[i * bytesPerSample], samplesPerFrame, numFrames); } } break; case AAUDIO_FORMAT_PCM_I32: { int32_t *audioBuffer = (int32_t *) audioData; for (int i = 0; i < numActiveOscillators; ++i) { sineData->sineOscillators[i].render(&audioBuffer[i], samplesPerFrame, numFrames); } } break; Loading
media/libaaudio/examples/utils/SineGenerator.h +38 −5 Original line number Diff line number Diff line Loading @@ -41,20 +41,54 @@ public: } } float next() { float value = sinf(mPhase) * mAmplitude; advancePhase(); return value; } void render(int16_t *buffer, int32_t channelStride, int32_t numFrames) { int sampleIndex = 0; for (int i = 0; i < numFrames; i++) { buffer[sampleIndex] = (int16_t) (INT16_MAX * sin(mPhase) * mAmplitude); buffer[sampleIndex] = (int16_t) (INT16_MAX * next()); sampleIndex += channelStride; advancePhase(); } } void render(float *buffer, int32_t channelStride, int32_t numFrames) { int sampleIndex = 0; for (int i = 0; i < numFrames; i++) { buffer[sampleIndex] = sin(mPhase) * mAmplitude; buffer[sampleIndex] = next(); sampleIndex += channelStride; advancePhase(); } } void render(int32_t *buffer, int32_t channelStride, int32_t numFrames) { int sampleIndex = 0; for (int i = 0; i < numFrames; i++) { buffer[sampleIndex] = (int32_t) (INT32_MAX * next()); sampleIndex += channelStride; } } void render24(uint8_t *buffer, int32_t channelStride, int32_t numFrames) { int sampleIndex = 0; constexpr int32_t INT24_MAX = (1 << 23) - 1; constexpr int bytesPerSample = getBytesPerSample(AAUDIO_FORMAT_PCM_I24_PACKED); const bool isLittleEndian = isNativeLittleEndian(); for (int i = 0; i < numFrames; i++) { int32_t sample = (int32_t) (INT24_MAX * next()); uint32_t usample = (uint32_t) sample; if (isLittleEndian) { buffer[sampleIndex] = usample; // little end first buffer[sampleIndex + 1] = usample >> 8; buffer[sampleIndex + 2] = usample >> 16; } else { buffer[sampleIndex] = usample >> 16; // big end first buffer[sampleIndex + 1] = usample >> 8; buffer[sampleIndex + 2] = usample; } sampleIndex += channelStride * bytesPerSample; } } Loading Loading @@ -100,4 +134,3 @@ private: }; #endif /* SINE_GENERATOR_H */
media/libaaudio/examples/write_sine/src/write_sine.cpp +65 −24 Original line number Diff line number Diff line Loading @@ -47,9 +47,11 @@ int main(int argc, const char **argv) int32_t framesToPlay = 0; int32_t framesLeft = 0; int32_t xRunCount = 0; int numActiveOscilators = 0; int numActiveOscillators = 0; float *floatData = nullptr; int16_t *shortData = nullptr; int32_t *int32Data = nullptr; uint8_t *byteData = nullptr; int testFd = -1; Loading @@ -57,7 +59,7 @@ int main(int argc, const char **argv) // in a buffer if we hang or crash. setvbuf(stdout, nullptr, _IONBF, (size_t) 0); printf("%s - Play a sine wave using AAudio V0.1.3\n", argv[0]); printf("%s - Play a sine wave using AAudio V0.1.4\n", argv[0]); if (argParser.parseArgs(argc, argv)) { return EXIT_FAILURE; Loading Loading @@ -91,11 +93,21 @@ int main(int argc, const char **argv) printf("Buffer: framesPerWrite = %d\n",framesPerWrite); // Allocate a buffer for the audio data. if (actualDataFormat == AAUDIO_FORMAT_PCM_FLOAT) { switch (actualDataFormat) { case AAUDIO_FORMAT_PCM_FLOAT: floatData = new float[framesPerWrite * actualChannelCount]; } else if (actualDataFormat == AAUDIO_FORMAT_PCM_I16) { break; case AAUDIO_FORMAT_PCM_I16: shortData = new int16_t[framesPerWrite * actualChannelCount]; } else { break; case AAUDIO_FORMAT_PCM_I24_PACKED: byteData = new uint8_t[framesPerWrite * actualChannelCount * getBytesPerSample(AAUDIO_FORMAT_PCM_I24_PACKED)]; break; case AAUDIO_FORMAT_PCM_I32: int32Data = new int32_t[framesPerWrite * actualChannelCount]; break; default: printf("ERROR Unsupported data format!\n"); goto finish; } Loading @@ -117,29 +129,56 @@ int main(int argc, const char **argv) // Play for a while. framesToPlay = actualSampleRate * argParser.getDurationSeconds(); framesLeft = framesToPlay; numActiveOscilators = (actualChannelCount > MAX_CHANNELS) ? MAX_CHANNELS : actualChannelCount; numActiveOscillators = (actualChannelCount > MAX_CHANNELS) ? MAX_CHANNELS : actualChannelCount; while (framesLeft > 0) { // Render as FLOAT or PCM if (actualDataFormat == AAUDIO_FORMAT_PCM_FLOAT) { for (int i = 0; i < numActiveOscilators; ++i) { switch (actualDataFormat) { case AAUDIO_FORMAT_PCM_FLOAT: for (int i = 0; i < numActiveOscillators; ++i) { myData.sineOscillators[i].render(&floatData[i], actualChannelCount, framesPerWrite); } } else if (actualDataFormat == AAUDIO_FORMAT_PCM_I16) { for (int i = 0; i < numActiveOscilators; ++i) { break; case AAUDIO_FORMAT_PCM_I16: for (int i = 0; i < numActiveOscillators; ++i) { myData.sineOscillators[i].render(&shortData[i], actualChannelCount, framesPerWrite); } break; case AAUDIO_FORMAT_PCM_I32: for (int i = 0; i < numActiveOscillators; ++i) { myData.sineOscillators[i].render(&int32Data[i], actualChannelCount, framesPerWrite); } break; case AAUDIO_FORMAT_PCM_I24_PACKED: for (int i = 0; i < numActiveOscillators; ++i) { static const int bytesPerSample = getBytesPerSample(AAUDIO_FORMAT_PCM_I24_PACKED); myData.sineOscillators[i].render24(&byteData[i * bytesPerSample], actualChannelCount, framesPerWrite); } break; } // Write audio data to the stream. int64_t timeoutNanos = 1000 * NANOS_PER_MILLISECOND; int32_t minFrames = (framesToPlay < framesPerWrite) ? framesToPlay : framesPerWrite; int32_t actual = 0; if (actualDataFormat == AAUDIO_FORMAT_PCM_FLOAT) { switch (actualDataFormat) { case AAUDIO_FORMAT_PCM_FLOAT: actual = AAudioStream_write(aaudioStream, floatData, minFrames, timeoutNanos); } else if (actualDataFormat == AAUDIO_FORMAT_PCM_I16) { break; case AAUDIO_FORMAT_PCM_I16: actual = AAudioStream_write(aaudioStream, shortData, minFrames, timeoutNanos); break; case AAUDIO_FORMAT_PCM_I32: actual = AAudioStream_write(aaudioStream, int32Data, minFrames, timeoutNanos); break; case AAUDIO_FORMAT_PCM_I24_PACKED: actual = AAudioStream_write(aaudioStream, byteData, minFrames, timeoutNanos); break; } if (actual < 0) { fprintf(stderr, "ERROR - AAudioStream_write() returned %d\n", actual); Loading Loading @@ -196,6 +235,8 @@ finish: delete[] floatData; delete[] shortData; delete[] int32Data; delete[] byteData; printf("exiting - AAudio result = %d = %s\n", result, AAudio_convertResultToText(result)); return (result != AAUDIO_OK) ? EXIT_FAILURE : EXIT_SUCCESS; } Loading