63 lines
3.0 KiB
Markdown
63 lines
3.0 KiB
Markdown
# 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 НЕ делать.
|