diff --git a/audio/src/main/kotlin/com/siya/epistemophile/audio/dsp/NormalizedFrameIterator.kt b/audio/src/main/kotlin/com/siya/epistemophile/audio/dsp/NormalizedFrameIterator.kt index ff05c6a..0af235c 100644 --- a/audio/src/main/kotlin/com/siya/epistemophile/audio/dsp/NormalizedFrameIterator.kt +++ b/audio/src/main/kotlin/com/siya/epistemophile/audio/dsp/NormalizedFrameIterator.kt @@ -16,6 +16,7 @@ class NormalizedFrameIterator( init { require(frameSize > 0) { "Frame size must be larger than zero." } require(shiftAmount > 0) { "Shift size must be larger than zero." } + require(shiftAmount <= frameSize) { "Shift size cannot exceed frame size." } } override fun hasNext(): Boolean { @@ -51,7 +52,11 @@ class NormalizedFrameIterator( DoubleVector(data) } else { val previous = currentFrame!!.data.clone() - System.arraycopy(data, 0, previous, previous.size - shiftAmount, shiftAmount) + val preserved = previous.size - shiftAmount + if (preserved > 0) { + System.arraycopy(previous, shiftAmount, previous, 0, preserved) + } + System.arraycopy(data, 0, previous, preserved, data.size) DoubleVector(previous) } frameCounter++ diff --git a/audio/src/test/kotlin/com/siya/epistemophile/audio/dsp/NormalizedFrameIteratorTest.kt b/audio/src/test/kotlin/com/siya/epistemophile/audio/dsp/NormalizedFrameIteratorTest.kt index 1ed2bbc..8086e14 100644 --- a/audio/src/test/kotlin/com/siya/epistemophile/audio/dsp/NormalizedFrameIteratorTest.kt +++ b/audio/src/test/kotlin/com/siya/epistemophile/audio/dsp/NormalizedFrameIteratorTest.kt @@ -26,7 +26,7 @@ class NormalizedFrameIteratorTest { assertEquals(2, frames.size) val normalization = 0x7fff.toDouble() val expectedFirst = doubleArrayOf(0.0, 1000 / normalization, 2000 / normalization, 3000 / normalization) - val expectedSecond = doubleArrayOf(0.0, 1000 / normalization, 4000 / normalization, 5000 / normalization) + val expectedSecond = doubleArrayOf(2000 / normalization, 3000 / normalization, 4000 / normalization, 5000 / normalization) frames[0].forEachIndexed { index, value -> assertEquals(expectedFirst[index], value, 1e-3) } @@ -51,4 +51,12 @@ class NormalizedFrameIteratorTest { assertEquals(3000 / 0x7fff.toDouble(), first[2], 1e-3) assertEquals(0.0, first[3], 1e-6) } + + @Test(expected = IllegalArgumentException::class) + fun `iterator rejects shift larger than frame size`() { + val format = PcmAudioFormat.mono16BitSignedLittleEndian(8000) + val stream = PcmMonoInputStream(format, ByteArrayInputStream(ByteArray(0))) + + NormalizedFrameIterator(stream, frameSize = 2, shiftAmount = 3, applyPadding = false) + } }