1

i get data from a wav file and want to write byte back to wav .

i have already got the byte from wav.here is my code

i know 0-43 bytes are header and 44- are data

byte[] soundBytes;
        try {
            InputStream inputStream = new FileInputStream(getRealPathFromURI(this,uri));
            soundBytes = toByteArray(inputStream);
            for (int i = 0; i != -1 ; i++) {

                if(soundBytes[i]<0) {
                    k =soundBytes[i] + 256;
                } else {k = soundBytes[i];}
                System.out.println("byte " + i + ": " + k );
            }
        } catch(Exception e) {
            e.printStackTrace();
        }


    }
}

public byte[] toByteArray(InputStream in) throws IOException {
    ByteArrayOutputStream out = new ByteArrayOutputStream();
    int read = 0;
    byte[] buffer = new byte[1024];
    while (read != -1) {
        read = in.read(buffer);
        if (read != -1)
            out.write(buffer,0,read);
    }
    out.close();
    return out.toByteArray();
}
陳韋綱
  • 11
  • 1
  • 2
  • I am confused as to whether Android implements the Java class TargetDataLine. IF YES, this class will handle all the .wav header/formatting, all you have to do is provide the PCM converted to bytes as per the format. But I'm not clear how much of Java audio Android uses. – Phil Freihofner Apr 24 '17 at 00:28

1 Answers1

2

The below code is converting raw pcm file into raw file. As you said you got the raw bytes you either follow creating a raw file with these bytes you got and send that file into following rawToWave() method or manipulate rawToWave() method to make require convert bytes[] into raw file directly.

public void rawToWave(final File rawFile) throws IOException {

    File waveFile = DirectoryOperations.createDirAndAudioFile("vocal.wav");// creating the empty wav file.

    byte[] rawData = new byte[(int) rawFile.length()];
    DataInputStream input = null;
    try {
        input = new DataInputStream(new FileInputStream(rawFile));
        input.read(rawData);
    } finally {
        if (input != null) {
            input.close();
        }
    }

    DataOutputStream output = null;//following block is converting raw to wav.
    try {
        output = new DataOutputStream(new FileOutputStream(waveFile));
        // WAVE header
        // see http://ccrma.stanford.edu/courses/422/projects/WaveFormat/
        writeString(output, "RIFF"); // chunk id
        writeInt(output, 36 + rawData.length); // chunk size
        writeString(output, "WAVE"); // format
        writeString(output, "fmt "); // subchunk 1 id
        writeInt(output, 16); // subchunk 1 size
        writeShort(output, (short) 1); // audio format (1 = PCM)
        writeShort(output, (short) 1); // number of channels
        writeInt(output, RECORDER_SAMPLERATE); // sample rate
        writeInt(output, RECORDER_SAMPLERATE * 2); // byte rate
        writeShort(output, (short) 2); // block align
        writeShort(output, (short) 16); // bits per sample
        writeString(output, "data"); // subchunk 2 id
        writeInt(output, rawData.length); // subchunk 2 size
        output.write(fullyReadFileToBytes(rawFile));

    } finally {
        if (output != null) {
            output.close();
        }
    }
}

private byte[] fullyReadFileToBytes(File f) throws IOException {
    int size = (int) f.length();
    byte bytes[] = new byte[size];
    byte tmpBuff[] = new byte[size];
    try (FileInputStream fis = new FileInputStream(f)) {
        int read = fis.read(bytes, 0, size);
        if (read < size) {
            int remain = size - read;
            while (remain > 0) {
                read = fis.read(tmpBuff, 0, remain);
                System.arraycopy(tmpBuff, 0, bytes, size - remain, read);
                remain -= read;
            }
        }
    }

    return bytes;
}

private void writeInt(final DataOutputStream output, final int value) throws IOException {
    output.write(value);
    output.write(value >> 8);
    output.write(value >> 16);
    output.write(value >> 24);
}

private void writeShort(final DataOutputStream output, final short value) throws IOException {
    output.write(value);
    output.write(value >> 8);
}

private void writeString(final DataOutputStream output, final String value) throws IOException {
    for (int i = 0; i < value.length(); i++) {
        output.write(value.charAt(i));
    }
}
ACAkgul
  • 188
  • 2
  • 11
  • whats recorder sample rate and RECORDER_SAMPLERATE * 2 mean? – 陳韋綱 Apr 24 '17 at 12:36
  • i have 0-43 byte and they are header , isnt it? so i dont really need write like RIFF WAVE things ? – 陳韋綱 Apr 24 '17 at 12:37
  • @陳韋綱 RECORDER_SAMPLERATE is Sample Rate of the audio file (like 44100 Hz). In Java, byte is 8 bit and short is 16 bit so you need to multiple by 2 to prevent from overload. Your file is Wav file therefore the first 44 byte is header. The upper method is for raw file so you need to get rid of first 44 byte to use this method or as you said you dont need to do riff wave things. – ACAkgul Apr 24 '17 at 15:28