stt(dump): WAV-заголовок — размеры little-endian (плееры открывают дампы)
This commit is contained in:
@@ -0,0 +1,62 @@
|
||||
# TASK-wav-header.md — починить размеры в WAV-заголовке (big-endian → little-endian)
|
||||
|
||||
## Симптом
|
||||
|
||||
Дампы `stt_dump_*.wav` (app-glasses WavWriter) не открываются в плеерах. Проверка hexdump:
|
||||
- `RIFF 00 02 e1 a4` — размер записан big-endian (Java `RandomAccessFile.writeInt`), а WAV требует little-endian.
|
||||
- Правильно: `a4 e1 02 00` для файла 188844 байт (data 188800).
|
||||
|
||||
## Точка правки
|
||||
|
||||
`app-glasses/src/main/kotlin/pw/binom/viewmate/glasses/stt/WavWriter.kt`, метод `close()`:
|
||||
```kotlin
|
||||
runCatching {
|
||||
RandomAccessFile(path, "rw").use { raf ->
|
||||
raf.seek(4)
|
||||
raf.writeInt((36 + dataBytes).toInt()) // RIFF size — BIG-ENDIAN, БАГ
|
||||
raf.seek(40)
|
||||
raf.writeInt(dataBytes.toInt()) // data size — BIG-ENDIAN, БАГ
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
`headerBytes()` уже использует `ByteBuffer.order(LITTLE_ENDIAN)` — там всё правильно (placeholder -1 одинаков в любом порядке, поэтому баг не виден до close()).
|
||||
|
||||
## Фикс
|
||||
|
||||
Писать размеры little-endian. Минимальная правка без новых зависимостей:
|
||||
```kotlin
|
||||
runCatching {
|
||||
RandomAccessFile(path, "rw").use { raf ->
|
||||
raf.seek(4)
|
||||
raf.write(leInt(36 + dataBytes))
|
||||
raf.seek(40)
|
||||
raf.write(leInt(dataBytes))
|
||||
}
|
||||
}
|
||||
```
|
||||
с helper рядом:
|
||||
```kotlin
|
||||
/** 4 байта little-endian (WAV-заголовок), в отличие от RandomAccessFile.writeInt (big-endian). */
|
||||
private fun leInt(v: Long): ByteArray =
|
||||
ByteBuffer.allocate(4).order(ByteOrder.LITTLE_ENDIAN).putInt(v.toInt()).array()
|
||||
```
|
||||
(`ByteBuffer`/`ByteOrder` уже импортированы в файле.)
|
||||
|
||||
НЕ трогать: остальное в WavWriter (write/headerBytes), SttMicStream, охраняемые 4 файла, протокол.
|
||||
|
||||
## Тесты
|
||||
|
||||
В `app-glasses/src/test/.../stt/` (рядом с MicChunkTest) — новый `WavWriterTest`:
|
||||
1. Записать 3200 байт через WavWriter во временный файл, close(), прочитать заголовок:
|
||||
- байты 4..8 (RIFF size) == 36 + 3200 (little-endian, сравнить с ожидаемым ByteBuffer);
|
||||
- байты 40..44 (data size) == 3200 (little-endian);
|
||||
- python-wave-эквивалент: nframes == 1600 (можно проверить в JVM: прочитать заголовок вручную).
|
||||
2. Пустой файл (0 байт данных) — RIFF size == 36, data size == 0.
|
||||
3. Закрытие дважды (close два раза) — размеры не портятся (closed-флаг).
|
||||
|
||||
## Проверка
|
||||
|
||||
1. `./gradlew :app-glasses:testDebugUnitTest` — зелёные (старые + новые).
|
||||
2. `./gradlew :app-glasses:assembleDebug` — собирается.
|
||||
3. Коммит: `stt(dump): WAV-заголовок — размеры little-endian (плееры открывают дампы)`. Push НЕ делать.
|
||||
Reference in New Issue
Block a user