package io.github.dstrekelj.toolkit.audio;

import java.io.ByteArrayOutputStream;
import java.io.IOException;

/**
 * TODO: Comment.
 */
public class PcmToWav {
    // http://soundfile.sapp.org/doc/WaveFormat/
    public static byte[] write(byte[] pcmData, byte numberOfChannels, int sampleRate, byte bitsPerSample) {
        byte[] chunkId = "RIFF".getBytes();
        // 36 because of subChunk1 (format) data
        long chunkSize = 36 + pcmData.length;
        byte[] format = "WAVE".getBytes();
        byte[] subChunk1Id = "fmt ".getBytes();
        byte[] subChunk1Size = {16, 0, 0, 0};
        byte[] audioFormat = {1, 0};
        byte[] numChannels = {numberOfChannels, 0};
        int bytesPerChannel = numberOfChannels * (bitsPerSample / 8);
        byte[] subChunk2Id = "data".getBytes();
        int subChunk2Size = pcmData.length;

        ByteArrayOutputStream wav = null;
        try {
            wav = new ByteArrayOutputStream();
            // "RIFF" header
            wav.write(chunkId);                         // 4 B  Chunk ID
            wav.write((int) chunkSize);                 // 4 B  Chunk size
            wav.write(format);                          // 4 B  Format
            // "fmt " sub-chunk
            wav.write(subChunk1Id);                     // 4 B  Sub-chunk 1 ID
            wav.write(subChunk1Size);                   // 4 B  Sub-chunk 1 size
            wav.write(audioFormat);                     // 2 B  Audio format
            wav.write(numChannels);                     // 2 B  Number of channels
            wav.write(sampleRate);                      // 4 B  Sample rate
            wav.write(sampleRate * bytesPerChannel);    // 4 B  Byte rate
            wav.write(bytesPerChannel);                 // 2 B  Block align
            wav.write(bitsPerSample);                   // 2 B  Bits per sample
            // "data" sub-chunk
            wav.write(subChunk2Id);                     // 4 B  Sub-chunk 2 ID
            wav.write(subChunk2Size);                   // 4 B  Sub-chunk 2 size
            wav.write(pcmData);                         // * B  Sound data
            wav.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return wav.toByteArray();
    }
}

@@ -1019,32 +1019,36 @@
                 
+    
 // 4 B  Chunk ID
@@ -1061,25 +1061,29 @@
        w
-av.write(
+riteInt(wav, 
 (int) ch
@@ -1175,32 +1175,36 @@
                 
+    
 // 4 B  Format%0A 
@@ -1265,24 +1265,28 @@
 ubChunk1Id);
+    
             
@@ -1365,32 +1365,36 @@
                 
+    
 // 4 B  Sub-chun
@@ -1433,24 +1433,28 @@
 udioFormat);
+    
             
@@ -1531,32 +1531,36 @@
                 
+    
 // 2 B  Number o
@@ -1579,33 +1579,37 @@
            w
-av.write(
+riteInt(wav, 
 sampleRate);
@@ -1663,25 +1663,29 @@
        w
-av.write(
+riteInt(wav, 
 sampleRa
@@ -1741,25 +1741,38 @@
        w
-av.write(
+riteShort(wav, (short)
 bytesPer
@@ -1780,18 +1780,16 @@
 hannel);
-  
         
@@ -1828,25 +1828,31 @@
        w
-av.write(
+riteShort(wav, 
 bitsPerS
@@ -1858,18 +1858,16 @@
 Sample);
-  
         
@@ -1979,32 +1979,36 @@
                 
+    
 // 4 B  Sub-chun
@@ -2023,33 +2023,37 @@
            w
-av.write(
+riteInt(wav, 
 subChunk2Siz
@@ -2130,16 +2130,20 @@
 cmData);
+    
         
@@ -2320,11 +2320,391 @@
 );%0A    %7D
+%0A%0A    private static void writeInt(ByteArrayOutputStream out, int value) throws IOException %7B%0A        out.write(value);%0A        out.write(value %3E%3E 8);%0A        out.write(value %3E%3E 16);%0A        out.write(value %3E%3E 24);%0A    %7D%0A%0A    private static void writeShort(ByteArrayOutputStream out, short value) throws IOException %7B%0A        out.write(value);%0A        out.write(value %3E%3E 8);%0A    %7D
 %0A%7D%0A

Fix WAV header data