From 26cc60adf5fe3b965ac9cb5fce89fc14357ba8ae Mon Sep 17 00:00:00 2001 From: Eoin Mcloughlin Date: Wed, 13 May 2020 18:15:49 +0100 Subject: [PATCH] Write audio samples on a worker thread, enqueued on main --- TODO | 1 - .../java/com/example/ecwt/DitDahGenerator.kt | 38 ++++++++++++++----- .../java/com/example/ecwt/TrainingActivity.kt | 15 +++++++- 3 files changed, 43 insertions(+), 11 deletions(-) diff --git a/TODO b/TODO index a2b1402..efa9831 100644 --- a/TODO +++ b/TODO @@ -1,5 +1,4 @@ Basic: -* Multithreaded sounder * Correct tone length calculation * Settings diff --git a/app/src/main/java/com/example/ecwt/DitDahGenerator.kt b/app/src/main/java/com/example/ecwt/DitDahGenerator.kt index 24c76a7..2eda682 100644 --- a/app/src/main/java/com/example/ecwt/DitDahGenerator.kt +++ b/app/src/main/java/com/example/ecwt/DitDahGenerator.kt @@ -5,6 +5,9 @@ import android.media.AudioFormat import android.media.AudioTrack import android.media.MediaDataSource import android.view.KeyEvent +import java.util.concurrent.ArrayBlockingQueue +import java.util.concurrent.BlockingQueue +import kotlin.concurrent.thread import kotlin.math.PI import kotlin.math.sin @@ -164,25 +167,42 @@ class DitDahSoundStream { for(i in 0 until dahLengthInSamples) { mDahSound[i] = (0x7fff.toFloat() * sin(2.0f * PI * i * config.toneFrequency * invSampleRate) ).toShort(); } + + thread() { makeSoundsWorkerThreadFunc() } } fun enqueue(symbols : List) { - // TODO want to be able to call this multi-threaded, while this owns a thread which writes the samples - for (sym in symbols) { + for(sym in symbols) { + mSymbolQueue.put(sym) + } + } + + fun quit() { + mShouldQuit = true; + mSymbolQueue.put(SoundTypes.WORD_SPACE) + } + + fun makeSoundsWorkerThreadFunc() { + while(true) { + val sym : SoundTypes = mSymbolQueue.take() + if(mShouldQuit) + return; + when (sym) { - //TODO These sounds should include a blank space SoundTypes.DIT -> mSoundPlayer.write(mDitSound, 0, mDitSound.size) SoundTypes.DAH -> mSoundPlayer.write(mDahSound, 0, mDahSound.size) - SoundTypes.LETTER_SPACE -> mSoundPlayer.write(mCharacterSpacingSound, 0, mCharacterSpacingSound.size) - SoundTypes.WORD_SPACE -> mSoundPlayer.write(mWordSpacingSound, 0, mWordSpacingSound.size) + SoundTypes.LETTER_SPACE -> mSoundPlayer.write( mCharacterSpacingSound, 0, mCharacterSpacingSound.size) + SoundTypes.WORD_SPACE -> mSoundPlayer.write( mWordSpacingSound, 0, mWordSpacingSound.size) } + + if (mSoundPlayer.playState != AudioTrack.PLAYSTATE_PLAYING) + mSoundPlayer.play() } - - if(mSoundPlayer.playState != AudioTrack.PLAYSTATE_PLAYING) - mSoundPlayer.play() - } + private var mShouldQuit = false; + private var mSymbolQueue = ArrayBlockingQueue(1000); + private val mAudioSampleRate = 44100; private val mDitSound : ShortArray; diff --git a/app/src/main/java/com/example/ecwt/TrainingActivity.kt b/app/src/main/java/com/example/ecwt/TrainingActivity.kt index 2c1b16c..2fc2cfc 100644 --- a/app/src/main/java/com/example/ecwt/TrainingActivity.kt +++ b/app/src/main/java/com/example/ecwt/TrainingActivity.kt @@ -17,10 +17,16 @@ class TrainingActivity : AppCompatActivity() { mTextViewTest = findViewById(R.id.TestEnteredText); - mSoundPlayer = DitDahSoundStream(DitDahGeneratorSettings()) + initSoundPlayer() onKeyUp(KeyEvent.KEYCODE_E, KeyEvent(0,0)) } + override fun onResume() { + super.onResume() + mSoundPlayer = DitDahSoundStream(DitDahGeneratorSettings()) + } + + fun startTraining(view: View) { } @@ -35,6 +41,9 @@ class TrainingActivity : AppCompatActivity() { override fun onPause() { super.onPause(); + + mSoundPlayer?.quit() + mSoundPlayer = null } @@ -51,6 +60,10 @@ class TrainingActivity : AppCompatActivity() { return ret } + private fun initSoundPlayer() { + mSoundPlayer = DitDahSoundStream(DitDahGeneratorSettings()) + } + private var mTextViewTest : TextView? = null; private var mMediaPlayer : MediaPlayer? = null;