-
Bug
-
Resolution: Fixed
-
P4
-
5.0, 8, 9
-
b105
-
x86
-
generic
FULL PRODUCT VERSION :
java version "1.5.0_07"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_07-b03)
Java HotSpot(TM) Client VM (build 1.5.0_07-b03, mixed mode, sharing)
ADDITIONAL OS VERSION INFORMATION :
Windows Xp,Linux
A DESCRIPTION OF THE PROBLEM :
The AudioInputStream objects returned by the A-Law encoding converters do not implement the skip() method correctly. The skip() method is not iemplemented and so calls to the skip method of the decoded PCM stream skip the underlying original A-law stream. This results in skipping the double amount of bytes as intended.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Run AudioSkipTest with an A-Law encoded file as argument:
java AudioSkipTest alaw_coded.wav
The program prints the frame length read from the file header, by reading the whole file, and by skipping through the whole file. The skip ends at the half of the file length. Running the program with an PCM coded file prints correct results.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
All calculated frame length should be equal if skip() works correctly.
ACTUAL -
The frame length calculated by using skip() returns the half amount of frames.
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import java.io.File;
import java.io.IOException;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.UnsupportedAudioFileException;
public class AudioSkipTest {
private static final int FRAME_STEP = 1024;
private static final int MAX_ZERO_SKIP_TRIALS = 10;
private File audioFile=null;
public AudioSkipTest(File audioFile) throws UnsupportedAudioFileException,
IOException {
this.audioFile=audioFile;
}
public AudioFormat getAudioFormat() throws IOException, UnsupportedAudioFileException{
AudioInputStream ais = AudioSystem.getAudioInputStream(audioFile);
AudioFormat audioFormat=ais.getFormat();
ais.close();
return audioFormat;
}
private AudioInputStream getPCMSignedStream() throws UnsupportedAudioFileException, IOException{
AudioInputStream ais = AudioSystem.getAudioInputStream(audioFile);
return AudioSystem.getAudioInputStream(
AudioFormat.Encoding.PCM_SIGNED,ais);
}
public long getFrameLengthByHeader() throws UnsupportedAudioFileException, IOException{
AudioInputStream ais=getPCMSignedStream();
long frameLength=ais.getFrameLength();
ais.close();
return frameLength;
}
public long getFrameLengthBySkip() throws UnsupportedAudioFileException, IOException{
AudioInputStream ais=getPCMSignedStream();
int frameSize = ais.getFormat().getFrameSize();
long totalSkipped=0;
int zeroSkipTrials = 0;
while (zeroSkipTrials < MAX_ZERO_SKIP_TRIALS) {
long step = FRAME_STEP * frameSize;
long skipped = ais.skip(step);
totalSkipped += skipped;
if (skipped == 0) {
zeroSkipTrials++;
} else {
zeroSkipTrials = 0;
}
}
// Check if EOF is reached
int read = ais.read(new byte[frameSize]);
if (read != -1) {
System.err.println("NOT at end of audio file. (read " + read
+ " bytes)");
throw new IOException("Could not skip to end of file");
}
ais.close();
return totalSkipped/frameSize;
}
public long getFrameLengthByRead() throws UnsupportedAudioFileException, IOException{
AudioInputStream ais = getPCMSignedStream();
int frameSize = ais.getFormat().getFrameSize();
long readBytes=0;
byte[] dummyBuf=new byte[FRAME_STEP*frameSize];
int read;
while((read=ais.read(dummyBuf))!=-1){
readBytes+=read;
}
ais.close();
return readBytes/frameSize;
}
public static void main(String[] args) {
if (args.length ==0) {
System.err.println("Usage: java AudioSkipTest audiofile1 audiofile2 ...");
System.exit(-1);
}
for(int i=0;i<args.length;i++){
try {
File audioFile=new File(args[i]);
AudioSkipTest test=new AudioSkipTest(audioFile);
System.out.println("Processing file: "+audioFile.getName());
System.out.println("Audio format: "+test.getAudioFormat());
System.out.println("Frame length by header: "+test.getFrameLengthByHeader());
System.out.println("Frame length by read: "+test.getFrameLengthByRead());
System.out.println("Frame length by skip: "+test.getFrameLengthBySkip());
System.out.println();
} catch (UnsupportedAudioFileException e) {
System.err.println("Audio file not supported: "+e.getMessage());
e.printStackTrace();
} catch (IOException e) {
System.err.println("I/O error: "+e.getMessage());
e.printStackTrace();
}
}
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
Avoid using skip() method or implement your own FormatConversionProvider.
Copied from http://bugs.openjdk.java.net/show_bug.cgi?id=100083#c0
Description From ###@###.### 2009-07-06 07:22:37 PDT
Created an attachment (id=97) [details]
A-law/U-law codec patches
The AudioInputStream objects returned by the A-Law and U-Law encoders do not
implement the skip() method correctly. The skip() method is not implemented and
so calls to the skip method of the decoded PCM stream skip the underlying
original A-law/U-law stream. This results in skipping the double amount of
bytes as intended.
The attached patches implement the skip() methods for the codecs correctly.
java version "1.5.0_07"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_07-b03)
Java HotSpot(TM) Client VM (build 1.5.0_07-b03, mixed mode, sharing)
ADDITIONAL OS VERSION INFORMATION :
Windows Xp,Linux
A DESCRIPTION OF THE PROBLEM :
The AudioInputStream objects returned by the A-Law encoding converters do not implement the skip() method correctly. The skip() method is not iemplemented and so calls to the skip method of the decoded PCM stream skip the underlying original A-law stream. This results in skipping the double amount of bytes as intended.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Run AudioSkipTest with an A-Law encoded file as argument:
java AudioSkipTest alaw_coded.wav
The program prints the frame length read from the file header, by reading the whole file, and by skipping through the whole file. The skip ends at the half of the file length. Running the program with an PCM coded file prints correct results.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
All calculated frame length should be equal if skip() works correctly.
ACTUAL -
The frame length calculated by using skip() returns the half amount of frames.
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import java.io.File;
import java.io.IOException;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.UnsupportedAudioFileException;
public class AudioSkipTest {
private static final int FRAME_STEP = 1024;
private static final int MAX_ZERO_SKIP_TRIALS = 10;
private File audioFile=null;
public AudioSkipTest(File audioFile) throws UnsupportedAudioFileException,
IOException {
this.audioFile=audioFile;
}
public AudioFormat getAudioFormat() throws IOException, UnsupportedAudioFileException{
AudioInputStream ais = AudioSystem.getAudioInputStream(audioFile);
AudioFormat audioFormat=ais.getFormat();
ais.close();
return audioFormat;
}
private AudioInputStream getPCMSignedStream() throws UnsupportedAudioFileException, IOException{
AudioInputStream ais = AudioSystem.getAudioInputStream(audioFile);
return AudioSystem.getAudioInputStream(
AudioFormat.Encoding.PCM_SIGNED,ais);
}
public long getFrameLengthByHeader() throws UnsupportedAudioFileException, IOException{
AudioInputStream ais=getPCMSignedStream();
long frameLength=ais.getFrameLength();
ais.close();
return frameLength;
}
public long getFrameLengthBySkip() throws UnsupportedAudioFileException, IOException{
AudioInputStream ais=getPCMSignedStream();
int frameSize = ais.getFormat().getFrameSize();
long totalSkipped=0;
int zeroSkipTrials = 0;
while (zeroSkipTrials < MAX_ZERO_SKIP_TRIALS) {
long step = FRAME_STEP * frameSize;
long skipped = ais.skip(step);
totalSkipped += skipped;
if (skipped == 0) {
zeroSkipTrials++;
} else {
zeroSkipTrials = 0;
}
}
// Check if EOF is reached
int read = ais.read(new byte[frameSize]);
if (read != -1) {
System.err.println("NOT at end of audio file. (read " + read
+ " bytes)");
throw new IOException("Could not skip to end of file");
}
ais.close();
return totalSkipped/frameSize;
}
public long getFrameLengthByRead() throws UnsupportedAudioFileException, IOException{
AudioInputStream ais = getPCMSignedStream();
int frameSize = ais.getFormat().getFrameSize();
long readBytes=0;
byte[] dummyBuf=new byte[FRAME_STEP*frameSize];
int read;
while((read=ais.read(dummyBuf))!=-1){
readBytes+=read;
}
ais.close();
return readBytes/frameSize;
}
public static void main(String[] args) {
if (args.length ==0) {
System.err.println("Usage: java AudioSkipTest audiofile1 audiofile2 ...");
System.exit(-1);
}
for(int i=0;i<args.length;i++){
try {
File audioFile=new File(args[i]);
AudioSkipTest test=new AudioSkipTest(audioFile);
System.out.println("Processing file: "+audioFile.getName());
System.out.println("Audio format: "+test.getAudioFormat());
System.out.println("Frame length by header: "+test.getFrameLengthByHeader());
System.out.println("Frame length by read: "+test.getFrameLengthByRead());
System.out.println("Frame length by skip: "+test.getFrameLengthBySkip());
System.out.println();
} catch (UnsupportedAudioFileException e) {
System.err.println("Audio file not supported: "+e.getMessage());
e.printStackTrace();
} catch (IOException e) {
System.err.println("I/O error: "+e.getMessage());
e.printStackTrace();
}
}
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
Avoid using skip() method or implement your own FormatConversionProvider.
Copied from http://bugs.openjdk.java.net/show_bug.cgi?id=100083#c0
Description From ###@###.### 2009-07-06 07:22:37 PDT
Created an attachment (id=97) [details]
A-law/U-law codec patches
The AudioInputStream objects returned by the A-Law and U-Law encoders do not
implement the skip() method correctly. The skip() method is not implemented and
so calls to the skip method of the decoded PCM stream skip the underlying
original A-law/U-law stream. This results in skipping the double amount of
bytes as intended.
The attached patches implement the skip() methods for the codecs correctly.