Files
view-mate/TASK-wav-header.md
T

3.0 KiB
Raw Blame History

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():

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. Минимальная правка без новых зависимостей:

runCatching {
    RandomAccessFile(path, "rw").use { raf ->
        raf.seek(4)
        raf.write(leInt(36 + dataBytes))
        raf.seek(40)
        raf.write(leInt(dataBytes))
    }
}

с helper рядом:

/** 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 НЕ делать.