Skip to content

Instantly share code, notes, and snippets.

@Slooowpoke
Last active January 25, 2024 20:26
Show Gist options
  • Save Slooowpoke/cf7c799398ee6645c0be16d3f3b23ab2 to your computer and use it in GitHub Desktop.
Save Slooowpoke/cf7c799398ee6645c0be16d3f3b23ab2 to your computer and use it in GitHub Desktop.
Convert .wav to .pcm (a little class to remove a .wav header from a file an create a .pcm)
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
/**
* Creates a PCM file from a Wave (.wav) file
*/
public class WaveToPulseCodeModulation {
private File inputFile, outputFile;
private final int FAILED_SEARCH_INDEX = -99;
public WaveToPulseCodeModulation(String inputFile, String outputFile) throws IOException {
this.inputFile = new File(inputFile + ".wav");
this.outputFile = new File(outputFile + ".pcm");
// Create an empty output file
this.outputFile.createNewFile();
}
/**
* Converts a PCM to a WAVE by removing the Wave header
* First it needs to search for the start of the PCM
* The byte sequence marking the start of a PCM in a WAVE file is:
* (64 61 74 61) = "data"
*
* We search for the sequence and then create a file by skipping file reading in the input file
*
* @return boolean
* @throws IOException
*/
public boolean convert() throws IOException {
// Stream in a byte array and look for a specific sequence
// Convert byte to int results in 64 = 100, 61 = 97, 74 = 116, 61= 97
int[] sequence = new int[]{100, 97, 116, 97};
// Generate an input stream
FileInputStream is = new FileInputStream(inputFile);
// Generate an output stream
FileOutputStream outputStream = new FileOutputStream(outputFile.getPath());
byte buffer[] = new byte[1024];
int read = 0;
int totalMatched = 0;
int indexToSkipHeader = 0;
while ((read = is.read(buffer)) > 0) {
indexToSkipHeader = findIndexOfSequenceInByteArray(sequence, buffer);
// If the index fails, keep searching
if(indexToSkipHeader == FAILED_SEARCH_INDEX){
continue;
}else{
break;
}
}
// Close the input stream and re-open it
is.close();
is = new FileInputStream(inputFile);
// Reset out reading variables
read = 0;
// Now use the indexToSkipHeader to skip a certain amount of bytes when reading it back out
is.skip(indexToSkipHeader);
while ((read = is.read(buffer)) > 0) {
outputStream.write(buffer);
}
System.out.println("Finished writing file");
return false;
}
/**
* Searches for the index of our sequence
* Returns the index of the sequence (total bytes to skip) or returns the failed index
*
* @param int[] sequence
* @param byte[] buffer
* @return int indexToSkip
*/
private int findIndexOfSequenceInByteArray(int[] sequence, byte[] buffer){
int totalMatched = 0, indexToSkipHeader = 0;
// Search for first
for(byte value:buffer){
indexToSkipHeader++;
// Convert byte to an integer
int signed = value & 0xFF;
// Increase total matches if signed integer matches integer sequence
if(signed == sequence[totalMatched]){
totalMatched++;
}else{
totalMatched = 0;
}
// If the total matched is equal to the sequence length, we have found the index
if(totalMatched == sequence.length){
return indexToSkipHeader;
}
}
return FAILED_SEARCH_INDEX;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment