Создание файла WAV с помощью Okio

Моя система должна создать один файл WAV, используя байты массива файлов WAV. В настоящее время он использует Okio для чтения и записи данных в буферы, а затем записывает данные в окончательный файл.

Я следую этому документу и этому вопросу о переполнении стека:

и...

  • Окио: 1.10.0
  • Котлин: 1.0.2-1
  • Ява: 1.7

Я создал этот код:

fun mixAudios() {

    try {

        //Create the file used to storage the mixed audio file.
        val file = File(directory, finalFileName)

        //Open the buffer for this file.
        val bufferedSink = Okio.buffer(Okio.appendingSink(file))

        //Data header of the file.
        val header = Buffer()

        //Data of the file.
        val data = Buffer()

        //Do a action for every audio.
        audios.forEach {

            //Try to read the file, if success, return the file.
            Okio.buffer(Okio.source(File(it.address)))?.let { file ->

                //Create a new buffer for every audio address.
                val buffer = Buffer()

                //Read every byte on the buffer.
                file.readAll(buffer)

                //Remove the first 44 items of the buffer.
                buffer.readByteArray(44)

                //Get the buffer and write every byte on the sink.
                data.writeAll(buffer)

                //Close the sink.
                buffer.close()
                file.close()
            }
        }

        //Count of bytes on the data buffer.
        val fileSize = data.size().toInt()

        //The data is ready to be written on the sink.
        data.close()

        val totalFileSize = fileSize + 36
        val byteRate = (SAMPLE_RATE * CHANNELS * BYTES_PER_SAMPLE) / 8

        //Write the header of the final file.
        header.writeUtf8("RIFF")

            //Write the total file size (with the header)
            .writeByte(totalFileSize and 0xff)
            .writeByte((totalFileSize shr 8) and 0xff)
            .writeByte((totalFileSize shr 16) and 0xff)
            .writeByte((totalFileSize shr 24) and 0xff)
    //      .writeIntLe(fileSize) //Inform the size of the chunk, including the header.

            .writeUtf8("WAVE") //Inform the type of file.
            .writeUtf8("fmt ") //Add the "fmt" letters
            .writeIntLe(samplingRate) //fmt chunk

            .writeByte(AUDIO_FORMAT_PCM) //This byte represents the audio format (PCM).
            .writeByte(0)

            .writeByte(CHANNELS) //This byte represents the channels of the audio.
            .writeByte(0)

            //Write the sample rate
            .writeByte(SAMPLE_RATE and 0xff)
            .writeByte((SAMPLE_RATE shr 8) and 0xff)
            .writeByte((SAMPLE_RATE shr 16) and 0xff)
            .writeByte((SAMPLE_RATE shr 24) and 0xff)
    //      .writeIntLe(SAMPLE_RATE) //The sample rate of the audio

            //Write the byte rate
            .writeByte(byteRate and 0xff)
            .writeByte((byteRate shr 8) and 0xff)
            .writeByte((byteRate shr 16) and 0xff)
            .writeByte((byteRate shr 24) and 0xff)
    //      .writeIntLe((SAMPLE_RATE * CHANNELS * BYTES_PER_SAMPLE) / 8) //Byte rate

            .writeByte(CHANNELS * BYTES_PER_SAMPLE / 8) //Block align
            .writeByte(0)

            .writeByte(BYTES_PER_SAMPLE) //Bytes per sample
            .writeByte(0)

            .writeUtf8("data") //File content size

            .writeByte(fileSize and 0xff)
            .writeByte((fileSize shr 8) and 0xff)
            .writeByte((fileSize shr 16) and 0xff)
            .writeByte((fileSize shr 24) and 0xff)
    //      .writeIntLe(fileSize)

            .close()

        with (bufferedSink) {
            writeAll(header)
            writeAll(data)
            close() //Close and write the file on the memory.
        }

        //Do the rest...

        } catch (e: Exception) {
        if (debugEnabled) {
            e.printStackTrace()
        }
      }
    }

Файл создается успешно, но когда я пытаюсь открыть этот звук на любом медиаплеере, он кажется поврежденным.

Когда я пытаюсь исследовать байты этого сгенерированного аудиофайла, результат примерно такой:

байты

Не знаю правильно ли пишу заголовок, можете помочь решить эту проблему?

Спасибо!


person Pedro Paulo Amorim    schedule 30.08.2016    source источник


Ответы (1)


Откуда вы получаете значение для sampleRate? Вы пишете 80 3E 00 00 (т.е. 16000), но на самом деле должно быть 10 00 00 00 (т.е. 16 для необработанного формата PCM).

В этот момент в заголовке вы должны указать размер чанка fmt.

Я надеюсь, что это решит вашу проблему

person sparber    schedule 31.08.2016
comment
Я получаю от другой переменной, этот класс не имеет никакого отношения к родителю. Но стоимость 16000р. - person Pedro Paulo Amorim; 31.08.2016
comment
Чтобы запросить информацию, предпочитайте комментировать вопрос, а не публиковать ответ, и отвечайте только тогда, когда вы уверены в этом! - person Ashish Patil; 31.08.2016