1

I'm trying to downsample a .wav audio from 22050 to 8000 using AudioInputStream but the conversion returns me 0 data bytes. Here is the code:

AudioInputStream ais;
AudioInputStream eightKhzInputStream = null;
ais = AudioSystem.getAudioInputStream(file);
if (ais.getFormat().getSampleRate() == 22050f) {
    AudioFileFormat sourceFileFormat = AudioSystem.getAudioFileFormat(file);
    AudioFileFormat.Type targetFileType = sourceFileFormat.getType();
    AudioFormat sourceFormat = ais.getFormat();
    AudioFormat targetFormat = new AudioFormat(
        sourceFormat.getEncoding(),
        8000f,
        sourceFormat.getSampleSizeInBits(),
        sourceFormat.getChannels(),
        sourceFormat.getFrameSize(),
        8000f,
        sourceFormat.isBigEndian());
    eightKhzInputStream = AudioSystem.getAudioInputStream(targetFormat, ais);
    int nWrittenBytes = 0;
    nWrittenBytes = AudioSystem.write(eightKhzInputStream, targetFileType, file);

I already checked AudioSystem.isConversionSupported(targetFormat, sourceFormat) and it returns true. Any idea?

Claudio Mezzasalma
  • 646
  • 1
  • 5
  • 23

1 Answers1

1

I have just tested your code with different audio files and everything seems to work just fine. I can only guess, that you are either testing your code with an empty audio file (bytes == 0) or, that the file you try to convert is not supported by the Java Audio System.

Try using another input file and/or convert your input file to a compatible file, and it should work.

Here is the main method, that worked for me:

public static void main(String[] args) throws InterruptedException, UnsupportedAudioFileException, IOException {
    File file = ...;
    File output = ...;

    AudioInputStream ais;
    AudioInputStream eightKhzInputStream = null;
    ais = AudioSystem.getAudioInputStream(file);
    AudioFormat sourceFormat = ais.getFormat();
    if (ais.getFormat().getSampleRate() == 22050f) {
        AudioFileFormat sourceFileFormat = AudioSystem.getAudioFileFormat(file);
        AudioFileFormat.Type targetFileType = sourceFileFormat.getType();

        AudioFormat targetFormat = new AudioFormat(
                sourceFormat.getEncoding(),
                8000f,
                sourceFormat.getSampleSizeInBits(),
                sourceFormat.getChannels(),
                sourceFormat.getFrameSize(),
                8000f,
                sourceFormat.isBigEndian());
        if (!AudioSystem.isFileTypeSupported(targetFileType) || ! AudioSystem.isConversionSupported(targetFormat, sourceFormat)) {
              throw new IllegalStateException("Conversion not supported!");
        }
        eightKhzInputStream = AudioSystem.getAudioInputStream(targetFormat, ais);
        int nWrittenBytes = 0;

        nWrittenBytes = AudioSystem.write(eightKhzInputStream, targetFileType, output);
        System.out.println("nWrittenBytes: " + nWrittenBytes);
    }
}
Balder
  • 8,623
  • 4
  • 39
  • 61
  • ais points to a real file: ais.available() returns 26000 or so, and it's a standard WAV file. After all, if the format would have been unknown to Java Audio System, I would have get and exception when requesting the AudioInputStream, wouldn't I? – Claudio Mezzasalma Feb 12 '14 at 16:30
  • Yes, you should get an exception actually... anyway, your code works on my computer, I'll post the working main method in a second – Balder Feb 12 '14 at 16:32
  • I have added a check if the conversion is actually supported to the code. Try it out and see, if the IllegalStateException is thrown or not. – Balder Feb 12 '14 at 16:47
  • No exception is thrown, both tests inside the if returns true. – Claudio Mezzasalma Feb 12 '14 at 17:05
  • Very strange... try downloading this audio file: http://www-mmsp.ece.mcgill.ca/Documents/AudioFormats/WAVE/Samples/SoundCardAttrition/stereol.wav. The conversion of this file definitely works on my computer. – Balder Feb 12 '14 at 17:14
  • No way... there must be something with the codecs, I can't think about another reason... – Claudio Mezzasalma Feb 12 '14 at 20:20
  • 1
    I can't believe it, but I got it working. Basically I was doing to mistakes: - Relying on `eightKhzInputStream.available` to say that the conversion failed - Writing the converted wave on the same file it was read from. That caused the original file to be deleted, and so nothing would be written because nothing could be read from. Comparing your code line by line with mine was the key to understand my mistakes. Thanks! – Claudio Mezzasalma Feb 12 '14 at 23:18