Skip to Main Content

Java SE (Java Platform, Standard Edition)

Announcement

For appeals, questions and feedback about Oracle Forums, please email oracle-forums-moderators_us@oracle.com. Technical questions should be asked in the appropriate category. Thank you!

Cutting a wav file: possibly wrong datalength header in result

843802Apr 12 2010 — edited Apr 13 2010
Hi there,

I am currently developing a cue sheet based wav splitter.
The resulting wave files are encoded to mp3 using an external encoder named lame afterwards.

Just when I thought I was done, I noticed a strange behaviour of lame during encoding:
It's progress indicator shows completely implausible values.

Taking a closer look at it, I found out that the progress display is correct at the first track of a cue sheet. And the higher the track number gets (i.e. the later the original position in the complete wav file was), the more the progress display differs from what it should be.

I have a suspecion about the cause: The split results could contain a wrong "data length" info.

This is the code that does the split:
final String inputFileName = "/temp/input.wav";
final String outputFileName = "/tmp/output.wav";
long startSampleNo = 0; // Has been calculated from the cue sheet ...
long endSampleNo = 0; // Has been calculated from the cue sheet ...

// Need to open the input file twice to get the format first 
AudioInputStream inputStream = AudioSystem.getAudioInputStream(
                              new FileInputStream(inputFileName));
final AudioFormat format = inputStream.getFormat();
int channels = format.getChannels();
int sampleSizeInBytes = (format.getSampleSizeInBits() + 7) / 8;
inputStream.close();

// Now open the input file again, this time limited to endSampleNo. This is what we need the format for.
inputStream = new AudioInputStream(new FileInputStream(inputFileName),
                               format, endSampleNo);
final long bytsToSkip = startSampleNo * channels * sampleSizeInBytes;
if (bytsToSkip > 0) {
  inputStream.skip(bytsToSkip);
}
final FileOutputStream fileOutputStream = new FileOutputStream(outputFileName);
try {
  AudioSystem.write(inputStream, AudioFileFormat.Type.WAVE, fileOutputStream);
  tempFileOutputStream.flush();
} finally {
  inputStream.close();
  tempFileOutputStream.close();
}
This is the only way I found to copy a part of a wav file with a specified start and end point, since there is no AudioOutputStream class...
BTW: why do I have to specify the amount to skip in bytes while I need to specify the limit in samples ?

I assume that the AudioSystem.write() method writes a WAV header that contains a "data length" info based on the length that was used for constructing the FileInputStream, regardless of the part that was alrady skipped.

Any ideas ?

Thanks and Regards,
Markus
Comments
Locked Post
New comments cannot be posted to this locked post.
Post Details
Locked on May 11 2010
Added on Apr 12 2010
5 comments
508 views