stt(mic): вынести кадровую арифметику в micChunkBytes + регрессионные тесты MicChunkTest
- CHUNK_BYTES=3200, micChunkBytes(buf, frames): кадры read() -> байты (*2) - 4 теста: полный чанк 3200 Б без копирования, короткий read, документация старого бага (copyOf(кадры) = полка), inFrameCount=1600
This commit is contained in:
@@ -58,16 +58,11 @@ class SttMicStream(
|
||||
try {
|
||||
recorder.startRecording()
|
||||
log("stt", "микрофон запущен (16 кГц, s16, mono)")
|
||||
val buf = ByteArray(3_200) // = 1600 кадров (16-бит моно) = 100 мс
|
||||
val buf = ByteArray(CHUNK_BYTES) // = 1600 кадров (16-бит моно) = 100 мс
|
||||
while (isActive && shouldRun()) {
|
||||
// AudioRecord.read(byte[], int, inFrameCount): 3-й аргумент — В КАДРАХ,
|
||||
// а НЕ в байтах (16-бит моно: кадр = 2 байта). Просим buf.size/2 кадров
|
||||
// (= buf.size байт = 100 мс), получаем frames — и переводиМ В БАЙТЫ (×2).
|
||||
// Старый баг: n (кадры) брался как байты → ушла половина куска.
|
||||
val frames = recorder.read(buf, 0, buf.size / 2)
|
||||
val frames = recorder.read(buf, 0, CHUNK_BYTES / 2) // inFrameCount — КАДРЫ
|
||||
if (frames > 0) {
|
||||
val bytes = frames * 2
|
||||
val chunk = if (bytes == buf.size) buf else buf.copyOf(bytes)
|
||||
val chunk = micChunkBytes(buf, frames)
|
||||
if (dumpWriter != null) {
|
||||
runCatching { dumpWriter.write(chunk) }
|
||||
.onFailure { log("stt", "dump микрофона: ${it.message}") }
|
||||
@@ -143,6 +138,20 @@ class SttMicStream(
|
||||
}
|
||||
}
|
||||
|
||||
/** 100 мс при 16 кГц, s16, моно: 1600 кадров × 2 байта = 3200 байт. */
|
||||
internal const val CHUNK_BYTES = 3_200
|
||||
|
||||
/**
|
||||
* AudioRecord.read(byte[], int, inFrameCount) возвращает ЧИСЛО КАДРОВ, а не байт.
|
||||
* 16-бит моно: кадр = 2 байта. Байты = frames * 2.
|
||||
* Старый баг (заделан в c940a7e): return read() (кадры) сравнивали с buf.size (байты)
|
||||
* — всегда ложь → copyOf(n) резал кусок пополам (терялись 2-е 50 мс каждого 100 мс).
|
||||
*/
|
||||
internal fun micChunkBytes(buf: ByteArray, frames: Int): ByteArray {
|
||||
val bytes = frames * 2
|
||||
return if (bytes == buf.size) buf else buf.copyOf(bytes)
|
||||
}
|
||||
|
||||
/** FloatArray [-1, 1] → s16le ByteArray (16 кГц, mono). */
|
||||
internal fun floatSamplesToPcm16(samples: FloatArray): ByteArray {
|
||||
val out = ByteArray(samples.size * 2)
|
||||
|
||||
Reference in New Issue
Block a user