diff options
author | Paul McLean <pmclean@google.com> | 2020-08-27 13:51:57 -0600 |
---|---|---|
committer | Paul McLean <pmclean@google.com> | 2020-08-31 12:52:16 -0600 |
commit | a6f7558591245e60df04bef7511c24f7c1af9eae (patch) | |
tree | 56e28fe0f88f0485535f1912f3625e010b5c6b0a /samples | |
parent | 19143c3f07a074e660113df879862d0826b2a5b2 (diff) | |
download | oboe-a6f7558591245e60df04bef7511c24f7c1af9eae.tar.gz |
Use actual output stream to obtain playback sample rate.
Separate setup/start of audio stream.
Resample input WAVs after stream is open.
Address review comments.
Diffstat (limited to 'samples')
6 files changed, 46 insertions, 44 deletions
diff --git a/samples/drumthumper/src/main/cpp/DrumPlayerJNI.cpp b/samples/drumthumper/src/main/cpp/DrumPlayerJNI.cpp index 9f55e137..d7892db8 100644 --- a/samples/drumthumper/src/main/cpp/DrumPlayerJNI.cpp +++ b/samples/drumthumper/src/main/cpp/DrumPlayerJNI.cpp @@ -52,6 +52,12 @@ JNIEXPORT void JNICALL Java_com_plausiblesoftware_drumthumper_DrumPlayer_setupAu sDTPlayer.setupAudioStream(numChannels); } +JNIEXPORT void JNICALL +Java_com_plausiblesoftware_drumthumper_DrumPlayer_startAudioStreamNative( + JNIEnv *env, jobject thiz) { + sDTPlayer.startStream(); +} + /** * Native (JNI) implementation of DrumPlayer.teardownAudioStreamNative() */ @@ -85,8 +91,8 @@ JNIEXPORT jboolean JNICALL Java_com_plausiblesoftware_drumthumper_DrumPlayer_loa SampleBuffer* sampleBuffer = new SampleBuffer(); sampleBuffer->loadSampleData(&reader); - int sampleRate = sDTPlayer.getDeviceSampleRate(2 /*channelCount*/); - sampleBuffer->resampleData(sampleRate); +// int sampleRate = sDTPlayer.getDeviceSampleRate(2 /*channelCount*/); +// sampleBuffer->resampleData(sampleRate); OneShotSampleSource* source = new OneShotSampleSource(sampleBuffer, pan); sDTPlayer.addSampleSource(source, sampleBuffer); @@ -129,7 +135,7 @@ JNIEXPORT void JNICALL Java_com_plausiblesoftware_drumthumper_DrumPlayer_clearOu */ JNIEXPORT void JNICALL Java_com_plausiblesoftware_drumthumper_DrumPlayer_restartStream(JNIEnv*, jobject) { sDTPlayer.resetAll(); - if (sDTPlayer.openStream()){ + if (sDTPlayer.openStream() && sDTPlayer.startStream()){ __android_log_print(ANDROID_LOG_INFO, TAG, "openStream successful"); } else { __android_log_print(ANDROID_LOG_ERROR, TAG, "openStream failed"); diff --git a/samples/drumthumper/src/main/java/com/plausibleaudio/drumthumper/DrumPlayer.kt b/samples/drumthumper/src/main/java/com/plausibleaudio/drumthumper/DrumPlayer.kt index fbe75539..62c8dbfe 100644 --- a/samples/drumthumper/src/main/java/com/plausibleaudio/drumthumper/DrumPlayer.kt +++ b/samples/drumthumper/src/main/java/com/plausibleaudio/drumthumper/DrumPlayer.kt @@ -27,8 +27,6 @@ class DrumPlayer { // This IS NOT the channel format of the source samples // (which must be mono). val NUM_SAMPLE_CHANNELS: Int = 1; // All WAV resource must be mono -// val SAMPLE_RATE: Int = 44100 // All the input samples are assumed to BE 44.1K -// // All the input samples are assumed to be mono. // Sample Buffer IDs val BASSDRUM: Int = 0 @@ -58,6 +56,10 @@ class DrumPlayer { setupAudioStreamNative(NUM_PLAY_CHANNELS) } + fun startAudioStream() { + startAudioStreamNative(); + } + fun teardownAudioStream() { teardownAudioStreamNative() } @@ -99,6 +101,7 @@ class DrumPlayer { } external fun setupAudioStreamNative(numChannels: Int) + external fun startAudioStreamNative(); external fun teardownAudioStreamNative() external fun loadWavAssetNative( diff --git a/samples/drumthumper/src/main/java/com/plausibleaudio/drumthumper/DrumThumperActivity.kt b/samples/drumthumper/src/main/java/com/plausibleaudio/drumthumper/DrumThumperActivity.kt index eb90cb8e..2bdd6c9f 100644 --- a/samples/drumthumper/src/main/java/com/plausibleaudio/drumthumper/DrumThumperActivity.kt +++ b/samples/drumthumper/src/main/java/com/plausibleaudio/drumthumper/DrumThumperActivity.kt @@ -161,7 +161,13 @@ class DrumThumperActivity : AppCompatActivity(), mAudioMgr = getSystemService(Context.AUDIO_SERVICE) as AudioManager - // mDrumPlayer.allocSampleData() + } + + override fun onStart() { + super.onStart() + + mDrumPlayer.setupAudioStream() + var allAssetsValid = mDrumPlayer.loadWavAssets(getAssets()) if (!allAssetsValid) { @@ -171,12 +177,7 @@ class DrumThumperActivity : AppCompatActivity(), Toast.LENGTH_LONG) toast.show() } - } - - override fun onStart() { - super.onStart() - - mDrumPlayer.setupAudioStream() + mDrumPlayer.startAudioStream() if (mUseDeviceChangeFallback) { mAudioMgr!!.registerAudioDeviceCallback(mDeviceListener, null) @@ -232,11 +233,12 @@ class DrumThumperActivity : AppCompatActivity(), mDrumPlayer.teardownAudioStream() + mDrumPlayer.unloadWavAssets() + super.onStop() } override fun onDestroy() { - mDrumPlayer.unloadWavAssets(); super.onDestroy() } diff --git a/samples/iolib/src/main/cpp/player/SampleBuffer.cpp b/samples/iolib/src/main/cpp/player/SampleBuffer.cpp index a1544bd9..4a170469 100644 --- a/samples/iolib/src/main/cpp/player/SampleBuffer.cpp +++ b/samples/iolib/src/main/cpp/player/SampleBuffer.cpp @@ -60,22 +60,25 @@ void resampleData(const ResampleBlock& input, ResampleBlock* output) { // round up int32_t numOutFrames = (int32_t)(temp + 0.5); + // We iterate thousands of times through the loop. Roundoff error could accumulate + // so add a few more frames for padding + numOutFrames += 8; output->mNumFrames = numOutFrames; + const int channelCount = 1; // 1 for mono, 2 for stereo MultiChannelResampler *resampler = MultiChannelResampler::make( - 1, // channel count + channelCount, // channel count input.mSampleRate, // input sampleRate output->mSampleRate, // output sampleRate MultiChannelResampler::Quality::Medium); // conversion quality float *inputBuffer = input.mBuffer;; // multi-channel buffer to be consumed float *outputBuffer = new float[numOutFrames]; // multi-channel buffer to be filled + memset(outputBuffer, 0, sizeof(float) * numOutFrames); output->mBuffer = outputBuffer; - int numInputFrames = input.mNumFrames; // number of frames of input - int numOutputFrames = 0; - int channelCount = 1; // 1 for mono, 2 for stereo - int inputFramesLeft = numInputFrames; + int numOutputFrames = 0; + int inputFramesLeft = input.mNumFrames; while (inputFramesLeft > 0) { if(resampler->isWriteNeeded()) { resampler->writeNextFrame(inputBuffer); diff --git a/samples/iolib/src/main/cpp/player/SimpleMultiPlayer.cpp b/samples/iolib/src/main/cpp/player/SimpleMultiPlayer.cpp index 3c24b9e0..2cbfae77 100644 --- a/samples/iolib/src/main/cpp/player/SimpleMultiPlayer.cpp +++ b/samples/iolib/src/main/cpp/player/SimpleMultiPlayer.cpp @@ -72,34 +72,13 @@ void SimpleMultiPlayer::onErrorBeforeClose(AudioStream *, Result error) { __android_log_print(ANDROID_LOG_INFO, TAG, "==== onErrorBeforeClose() error:%d", error); } -int SimpleMultiPlayer::getDeviceSampleRate(int32_t channelCount) { - - // Create an audio stream - AudioStreamBuilder builder; - builder.setChannelCount(channelCount); - builder.setPerformanceMode(PerformanceMode::LowLatency); - builder.setSharingMode(SharingMode::Exclusive); - builder.setSampleRateConversionQuality(SampleRateConversionQuality::Medium); - - oboe::ManagedStream audioStream; - Result result = builder.openManagedStream(audioStream); - if (result != Result::OK) { - __android_log_print(ANDROID_LOG_ERROR, TAG, - "openStream failed. Error: %s", convertToText(result)); - return 0; - } else { - int rate = audioStream->getSampleRate(); - return rate; - } -} - bool SimpleMultiPlayer::openStream() { __android_log_print(ANDROID_LOG_INFO, TAG, "openStream()"); // Create an audio stream AudioStreamBuilder builder; builder.setChannelCount(mChannelCount); - // builder.setSampleRate(mSampleRate); // we will resample to device rate + // we will resample source data to device rate, so take default sample rate builder.setCallback(this); builder.setPerformanceMode(PerformanceMode::LowLatency); builder.setSharingMode(SharingMode::Exclusive); @@ -126,7 +105,13 @@ bool SimpleMultiPlayer::openStream() { "setBufferSizeInFrames failed. Error: %s", convertToText(result)); } - result = mAudioStream->requestStart(); + mSampleRate = mAudioStream->getSampleRate(); + + return true; +} + +bool SimpleMultiPlayer::startStream() { + Result result = mAudioStream->requestStart(); if (result != Result::OK){ __android_log_print( ANDROID_LOG_ERROR, @@ -154,6 +139,8 @@ void SimpleMultiPlayer::teardownAudioStream() { } void SimpleMultiPlayer::addSampleSource(SampleSource* source, SampleBuffer* buffer) { + buffer->resampleData(mSampleRate); + mSampleBuffers.push_back(buffer); mSampleSources.push_back(source); mNumSampleBuffers++; diff --git a/samples/iolib/src/main/cpp/player/SimpleMultiPlayer.h b/samples/iolib/src/main/cpp/player/SimpleMultiPlayer.h index efec8b91..d8c9877c 100644 --- a/samples/iolib/src/main/cpp/player/SimpleMultiPlayer.h +++ b/samples/iolib/src/main/cpp/player/SimpleMultiPlayer.h @@ -44,9 +44,10 @@ public: void setupAudioStream(int32_t channelCount); void teardownAudioStream(); - static int getDeviceSampleRate(int32_t channelCount); - bool openStream(); + bool startStream(); + + int getSampleRate() { return mSampleRate; } // Wave Sample Loading... /** @@ -79,7 +80,7 @@ private: // Oboe Audio Stream oboe::ManagedStream mAudioStream; - // Audio attributes + // Playback Audio attributes int32_t mChannelCount; int32_t mSampleRate; |