stt(glasses): VAD на очках (WebRTC, схема pair-view) — речевые сегменты с пре-роллом, межфразовая тишина не шлётся
This commit is contained in:
@@ -120,34 +120,50 @@ class MicChunkTest {
|
||||
private fun recorderWouldReturn(frames: Int) = frames
|
||||
|
||||
/*
|
||||
* Даунсемплинг 48→16 кГц (TASK-mic-48k): микрофон ARGT78 на 16 кГц пишет
|
||||
* рвано (ровные провалы тишины с периодом 100 мс) — пишем на 48 кГц
|
||||
* (нативная частота драйвера) и прореживаем каждый 3-й сэмпл.
|
||||
* VAD на очках (схема pair-view): фреймы 20 мс (320 сэмплов @ 16 кГц),
|
||||
* усиление ×10 перед VAD и whisper, склейка речевых сегментов в s16le.
|
||||
*/
|
||||
|
||||
@Test
|
||||
fun downsample_4800Frames_gives3200Bytes() {
|
||||
val buf = ByteArray(MIC_CHUNK_FRAMES * 2) // 4800 кадров = 9600 байт
|
||||
val out = downsample48To16(buf, MIC_CHUNK_FRAMES)
|
||||
assertEquals(3_200, out.size, "4800 кадров 48кГц → 1600 сэмплов 16кГц = 3200 байт")
|
||||
fun gainShort_quietSamples_boosted10_saturated() {
|
||||
val samples = shortArrayOf(1_000, -1_000, 20_000, -32_768, 0)
|
||||
val out = gainShort(samples, 10f)
|
||||
assertEquals(samples.size, out.size)
|
||||
assertEquals(10_000, out[0].toInt(), "1000 × 10")
|
||||
assertEquals(-10_000, out[1].toInt(), "-1000 × 10")
|
||||
assertEquals(32_767, out[2].toInt(), "20000 × 10 → насыщение")
|
||||
assertEquals(-32_768, out[3].toInt(), "-32768 × 10 → насыщение")
|
||||
assertEquals(0, out[4].toInt())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun downsample_takesEveryThirdSample() {
|
||||
// 6 кадров 48кГц (12 байт): 0,1,2,3,4,5 → 0 и 3 (каждый 3-й)
|
||||
val buf = byteArrayOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12)
|
||||
val out = downsample48To16(buf, 6)
|
||||
assertEquals(4, out.size, "6 кадров → 2 сэмпла = 4 байта")
|
||||
fun gainShort_gain1_returnsSameArray() {
|
||||
val samples = shortArrayOf(1, 2, 3)
|
||||
assertSame(samples, gainShort(samples, 1f), "gain=1 не аллоцирует")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun shortsToPcm16_concatenatesLittleEndian() {
|
||||
val frames = listOf(shortArrayOf(1, 2), shortArrayOf(3))
|
||||
val out = shortsToPcm16(frames)
|
||||
assertEquals(6, out.size, "3 сэмпла × 2 байта")
|
||||
assertEquals(1, out[0].toInt() and 0xff)
|
||||
assertEquals(2, out[1].toInt() and 0xff)
|
||||
assertEquals(7, out[2].toInt() and 0xff)
|
||||
assertEquals(8, out[3].toInt() and 0xff)
|
||||
assertEquals(0, out[1].toInt())
|
||||
assertEquals(2, out[2].toInt() and 0xff)
|
||||
assertEquals(0, out[3].toInt())
|
||||
assertEquals(3, out[4].toInt() and 0xff)
|
||||
assertEquals(0, out[5].toInt())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun downsample_nonMultipleOf3_dropsTail() {
|
||||
val buf = ByteArray(14) // 7 кадров: 6 usable + 1 отброшен
|
||||
val out = downsample48To16(buf, 7)
|
||||
assertEquals(4, out.size, "6 usable кадров → 2 сэмпла")
|
||||
fun shortsToPcm16_negativeSample_twoBytesComplement() {
|
||||
val out = shortsToPcm16(listOf(shortArrayOf(-1)))
|
||||
assertEquals(0xff, out[0].toInt() and 0xff)
|
||||
assertEquals(0xff, out[1].toInt() and 0xff)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun shortsToPcm16_empty_returnsEmpty() {
|
||||
assertEquals(0, shortsToPcm16(emptyList()).size)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user