1
0
Fork 0

Use sound generator to calculate real lesson duration

Approximation of farnsworth WPM wasn't accurate enough.
This can go a second or two over, but that feels alright.
This commit is contained in:
Eoin Mcloughlin 2022-08-28 10:01:55 +01:00
parent d6cfc78298
commit cb72fb0d5a
2 changed files with 21 additions and 8 deletions

View file

@ -414,7 +414,7 @@ class DitDahSoundStream {
// Apply an attack and release envelope to each of the samples to avoid a pop // Apply an attack and release envelope to each of the samples to avoid a pop
// in the audio that's generated. Empirically, 8ms seems to eliminate it while // in the audio that's generated. Empirically, 8ms seems to eliminate it while
// still being fast enough that it works on the fastest WPM setting: // still being fast enough that it works on the fastest WPM setting:
var attackReleaseDuration = 0.008f; val attackReleaseDuration = 0.008f;
val attackReleaseTimeInSamples = (attackReleaseDuration * mAudioSampleRate).toInt(); val attackReleaseTimeInSamples = (attackReleaseDuration * mAudioSampleRate).toInt();
for(i in 0 until attackReleaseTimeInSamples) { for(i in 0 until attackReleaseTimeInSamples) {
val frac = i.toFloat() / attackReleaseTimeInSamples.toFloat(); val frac = i.toFloat() / attackReleaseTimeInSamples.toFloat();
@ -436,6 +436,21 @@ class DitDahSoundStream {
} }
} }
// Returns the duration of the sequence, in seconds
fun durationOf(symbols : List<SoundTypes>): Float {
var numSamples = 0
for(sym in symbols) {
numSamples += when(sym) {
SoundTypes.DIT -> mDitSound
SoundTypes.DAH -> mDahSound
SoundTypes.LETTER_SPACE -> mCharacterSpacingSound
SoundTypes.WORD_SPACE -> mWordSpacingSound
}.size
}
return numSamples.toFloat() / mAudioSampleRate.toFloat();
}
fun quit() { fun quit() {
mShouldQuit = true; mShouldQuit = true;
@ -539,4 +554,4 @@ class DitDahSoundStream {
.setTransferMode(AudioTrack.MODE_STREAM) .setTransferMode(AudioTrack.MODE_STREAM)
.setBufferSizeInBytes(mAudioSampleRate) .setBufferSizeInBytes(mAudioSampleRate)
.build(); .build();
} }

View file

@ -79,8 +79,6 @@ class TrainingActivity : AppCompatActivity(),
if(mLessonStarted) if(mLessonStarted)
return return
val generatorSettings = DitDahGeneratorSettings()
val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this) val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this)
val lessonLengthInMinutes = sharedPreferences.getInt(getString(R.string.setting_koch_lesson_length_key), 1) val lessonLengthInMinutes = sharedPreferences.getInt(getString(R.string.setting_koch_lesson_length_key), 1)
@ -93,12 +91,12 @@ class TrainingActivity : AppCompatActivity(),
var sharedPrefs = PreferenceManager.getDefaultSharedPreferences(this) var sharedPrefs = PreferenceManager.getDefaultSharedPreferences(this)
val shortLessonDebug = sharedPrefs.getBoolean("debug_override_lesson_length", false) val shortLessonDebug = sharedPrefs.getBoolean("debug_override_lesson_length", false)
val numberOfWords = if(shortLessonDebug) { val lessonDurationS = if(shortLessonDebug) {
// This makes it much faster to test functionality, if enabled in preferences // This makes it much faster to test functionality, if enabled in preferences
2 15
} else { } else {
// This is only an approximation // This is only an approximation
generatorSettings.farnsworthWordsPerMinute * lessonLengthInMinutes lessonLengthInMinutes * 60
} }
// If selected in preferences, modify the alphabet used for the lesson so that // If selected in preferences, modify the alphabet used for the lesson so that
@ -117,7 +115,7 @@ class TrainingActivity : AppCompatActivity(),
// Create the actual text used for the lesson // Create the actual text used for the lesson
var lessonText = String() var lessonText = String()
var rng = Random.Default var rng = Random.Default
for(i in 0 until numberOfWords) { while(mSoundPlayer!!.durationOf(StringToSoundSequence(lessonText)) < lessonDurationS) {
val thisWordSize = rng.nextInt(minWordSize, maxWordSize + 1) val thisWordSize = rng.nextInt(minWordSize, maxWordSize + 1)
for(c in 0 until thisWordSize) { for(c in 0 until thisWordSize) {
val randomLetterIndex = rng.nextInt(0, lessonAlphabet.length) val randomLetterIndex = rng.nextInt(0, lessonAlphabet.length)