mirror of
https://github.com/chmouel/liseur.git
synced 2026-10-14 03:39:09 +00:00
fix: Keep the paused point as audio finishes
Some checks are pending
Build / build (push) Waiting to run
Some checks are pending
Build / build (push) Waiting to run
A pause just as a sentence finished could lose the listener's place. The audio had finished, but playback had not yet reported completion, so resuming could repeat the whole sentence instead of its final second. Kept the heard position available through that brief handoff, until playback stopped or the next sentence began. Added a regression test that reproduced the lost position before the fix and checked it for both a full sentence and audio resumed partway through a sentence.
This commit is contained in:
parent
947391f852
commit
8e88960b3e
2 changed files with 33 additions and 1 deletions
|
|
@ -51,6 +51,7 @@ class AudioTrackPcmOutput(
|
|||
private var applied = 1f
|
||||
|
||||
/** The clip of the current turn: where its frames start on the track's head, and its bounds. Under [lock]. */
|
||||
// Retain it through completion: a pause can precede the handoff back to the engine.
|
||||
private var clip: Clip? = null
|
||||
|
||||
/** The speed the track plays at, set to [speed] first. Under [lock]. */
|
||||
|
|
@ -146,7 +147,6 @@ class AudioTrackPcmOutput(
|
|||
val (head, rate) = synchronized(lock) {
|
||||
if (turn != myTurn) return@withContext
|
||||
val head = track.playbackHeadPosition.toLong() and 0xffffffffL
|
||||
if (head >= target && clip === playing) clip = null
|
||||
head to speedLocked(track)
|
||||
}
|
||||
if (head >= target) return@withContext
|
||||
|
|
|
|||
32
app/src/test/kotlin/com/chmouel/liseur/tts/PcmOutputTest.kt
Normal file
32
app/src/test/kotlin/com/chmouel/liseur/tts/PcmOutputTest.kt
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
package com.chmouel.liseur.tts
|
||||
|
||||
import android.app.Application
|
||||
import kotlinx.coroutines.test.StandardTestDispatcher
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Assert.assertNull
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.robolectric.RobolectricTestRunner
|
||||
import org.robolectric.annotation.Config
|
||||
|
||||
@Config(sdk = [35], application = Application::class)
|
||||
@RunWith(RobolectricTestRunner::class)
|
||||
class PcmOutputTest {
|
||||
@Test
|
||||
fun completedAudioKeepsItsHeardPositionUntilHalted() = runTest {
|
||||
val output = AudioTrackPcmOutput(writer = StandardTestDispatcher(testScheduler))
|
||||
val frames = 3 * SpeechAudio.SAMPLE_RATE
|
||||
val pcm = ByteArray(frames * 2)
|
||||
try {
|
||||
output.play(pcm)
|
||||
assertEquals(frames, output.halt())
|
||||
assertNull(output.halt())
|
||||
|
||||
output.play(pcm, fromFrame = SpeechAudio.SAMPLE_RATE)
|
||||
assertEquals(frames, output.halt())
|
||||
} finally {
|
||||
output.release()
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue