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.

Revisions

  1. Slooowpoke revised this gist Dec 18, 2018. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion WaveToPulseCodeModulation.java
    Original file line number Diff line number Diff line change
    @@ -26,7 +26,7 @@ public WaveToPulseCodeModulation(String inputFile, String outputFile) throws IOE
    * 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 skipping the index
    * We search for the sequence and then create a file by skipping file reading in the input file
    *
    * @return boolean
    * @throws IOException
  2. Slooowpoke created this gist Dec 18, 2018.
    112 changes: 112 additions & 0 deletions WaveToPulseCodeModulation.java
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,112 @@
    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 skipping the index
    *
    * @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;
    }
    }