6944033: RFE: add PCM_FLOAT support

Reviewed-by: dav
This commit is contained in:
Alex Menkov 2010-09-14 12:38:49 +04:00
parent 65b5c68b97
commit 4cf465320c
9 changed files with 126 additions and 35 deletions

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -40,8 +40,6 @@ import javax.sound.sampled.AudioFormat.Encoding;
*/ */
public abstract class AudioFloatConverter { public abstract class AudioFloatConverter {
public static final Encoding PCM_FLOAT = new Encoding("PCM_FLOAT");
/*************************************************************************** /***************************************************************************
* *
* LSB Filter, used filter least significant byte in samples arrays. * LSB Filter, used filter least significant byte in samples arrays.
@ -982,7 +980,7 @@ public abstract class AudioFloatConverter {
format.getSampleSizeInBits() + 7) / 8) - 4); format.getSampleSizeInBits() + 7) / 8) - 4);
} }
} }
} else if (format.getEncoding().equals(PCM_FLOAT)) { } else if (format.getEncoding().equals(Encoding.PCM_FLOAT)) {
if (format.getSampleSizeInBits() == 32) { if (format.getSampleSizeInBits() == 32) {
if (format.isBigEndian()) if (format.isBigEndian())
conv = new AudioFloatConversion32B(); conv = new AudioFloatConversion32B();

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -469,7 +469,7 @@ public class AudioFloatFormatConverter extends FormatConversionProvider {
} }
private Encoding[] formats = { Encoding.PCM_SIGNED, Encoding.PCM_UNSIGNED, private Encoding[] formats = { Encoding.PCM_SIGNED, Encoding.PCM_UNSIGNED,
AudioFloatConverter.PCM_FLOAT }; Encoding.PCM_FLOAT };
public AudioInputStream getAudioInputStream(Encoding targetEncoding, public AudioInputStream getAudioInputStream(Encoding targetEncoding,
AudioInputStream sourceStream) { AudioInputStream sourceStream) {
@ -481,7 +481,7 @@ public class AudioFloatFormatConverter extends FormatConversionProvider {
float samplerate = format.getSampleRate(); float samplerate = format.getSampleRate();
int bits = format.getSampleSizeInBits(); int bits = format.getSampleSizeInBits();
boolean bigendian = format.isBigEndian(); boolean bigendian = format.isBigEndian();
if (targetEncoding.equals(AudioFloatConverter.PCM_FLOAT)) if (targetEncoding.equals(Encoding.PCM_FLOAT))
bits = 32; bits = 32;
AudioFormat targetFormat = new AudioFormat(encoding, samplerate, bits, AudioFormat targetFormat = new AudioFormat(encoding, samplerate, bits,
channels, channels * bits / 8, samplerate, bigendian); channels, channels * bits / 8, samplerate, bigendian);
@ -520,19 +520,19 @@ public class AudioFloatFormatConverter extends FormatConversionProvider {
public Encoding[] getSourceEncodings() { public Encoding[] getSourceEncodings() {
return new Encoding[] { Encoding.PCM_SIGNED, Encoding.PCM_UNSIGNED, return new Encoding[] { Encoding.PCM_SIGNED, Encoding.PCM_UNSIGNED,
AudioFloatConverter.PCM_FLOAT }; Encoding.PCM_FLOAT };
} }
public Encoding[] getTargetEncodings() { public Encoding[] getTargetEncodings() {
return new Encoding[] { Encoding.PCM_SIGNED, Encoding.PCM_UNSIGNED, return new Encoding[] { Encoding.PCM_SIGNED, Encoding.PCM_UNSIGNED,
AudioFloatConverter.PCM_FLOAT }; Encoding.PCM_FLOAT };
} }
public Encoding[] getTargetEncodings(AudioFormat sourceFormat) { public Encoding[] getTargetEncodings(AudioFormat sourceFormat) {
if (AudioFloatConverter.getConverter(sourceFormat) == null) if (AudioFloatConverter.getConverter(sourceFormat) == null)
return new Encoding[0]; return new Encoding[0];
return new Encoding[] { Encoding.PCM_SIGNED, Encoding.PCM_UNSIGNED, return new Encoding[] { Encoding.PCM_SIGNED, Encoding.PCM_UNSIGNED,
AudioFloatConverter.PCM_FLOAT }; Encoding.PCM_FLOAT };
} }
public AudioFormat[] getTargetFormats(Encoding targetEncoding, public AudioFormat[] getTargetFormats(Encoding targetEncoding,
@ -571,17 +571,17 @@ public class AudioFloatFormatConverter extends FormatConversionProvider {
} }
} }
if (targetEncoding.equals(AudioFloatConverter.PCM_FLOAT)) { if (targetEncoding.equals(Encoding.PCM_FLOAT)) {
formats.add(new AudioFormat(AudioFloatConverter.PCM_FLOAT, formats.add(new AudioFormat(Encoding.PCM_FLOAT,
AudioSystem.NOT_SPECIFIED, 32, channels, channels * 4, AudioSystem.NOT_SPECIFIED, 32, channels, channels * 4,
AudioSystem.NOT_SPECIFIED, false)); AudioSystem.NOT_SPECIFIED, false));
formats.add(new AudioFormat(AudioFloatConverter.PCM_FLOAT, formats.add(new AudioFormat(Encoding.PCM_FLOAT,
AudioSystem.NOT_SPECIFIED, 32, channels, channels * 4, AudioSystem.NOT_SPECIFIED, 32, channels, channels * 4,
AudioSystem.NOT_SPECIFIED, true)); AudioSystem.NOT_SPECIFIED, true));
formats.add(new AudioFormat(AudioFloatConverter.PCM_FLOAT, formats.add(new AudioFormat(Encoding.PCM_FLOAT,
AudioSystem.NOT_SPECIFIED, 64, channels, channels * 8, AudioSystem.NOT_SPECIFIED, 64, channels, channels * 8,
AudioSystem.NOT_SPECIFIED, false)); AudioSystem.NOT_SPECIFIED, false));
formats.add(new AudioFormat(AudioFloatConverter.PCM_FLOAT, formats.add(new AudioFormat(Encoding.PCM_FLOAT,
AudioSystem.NOT_SPECIFIED, 64, channels, channels * 8, AudioSystem.NOT_SPECIFIED, 64, channels, channels * 8,
AudioSystem.NOT_SPECIFIED, true)); AudioSystem.NOT_SPECIFIED, true));
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -781,7 +781,7 @@ public class DLSSoundbank implements Soundbank {
} }
if (sampleformat == 3) { if (sampleformat == 3) {
audioformat = new AudioFormat( audioformat = new AudioFormat(
AudioFloatConverter.PCM_FLOAT, samplerate, bits, Encoding.PCM_FLOAT, samplerate, bits,
channels, framesize, samplerate, false); channels, framesize, samplerate, false);
} }
@ -965,7 +965,7 @@ public class DLSSoundbank implements Soundbank {
sampleformat = 1; sampleformat = 1;
else if (audioformat.getEncoding().equals(Encoding.PCM_SIGNED)) else if (audioformat.getEncoding().equals(Encoding.PCM_SIGNED))
sampleformat = 1; sampleformat = 1;
else if (audioformat.getEncoding().equals(AudioFloatConverter.PCM_FLOAT)) else if (audioformat.getEncoding().equals(Encoding.PCM_FLOAT))
sampleformat = 3; sampleformat = 3;
fmt_chunk.writeUnsignedShort(sampleformat); fmt_chunk.writeUnsignedShort(sampleformat);

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -118,16 +118,16 @@ public class SoftMixingMixer implements Mixer {
AudioSystem.NOT_SPECIFIED, bits, channels, channels AudioSystem.NOT_SPECIFIED, bits, channels, channels
* bits / 8, AudioSystem.NOT_SPECIFIED, true)); * bits / 8, AudioSystem.NOT_SPECIFIED, true));
} }
formats.add(new AudioFormat(AudioFloatConverter.PCM_FLOAT, formats.add(new AudioFormat(Encoding.PCM_FLOAT,
AudioSystem.NOT_SPECIFIED, 32, channels, channels * 4, AudioSystem.NOT_SPECIFIED, 32, channels, channels * 4,
AudioSystem.NOT_SPECIFIED, false)); AudioSystem.NOT_SPECIFIED, false));
formats.add(new AudioFormat(AudioFloatConverter.PCM_FLOAT, formats.add(new AudioFormat(Encoding.PCM_FLOAT,
AudioSystem.NOT_SPECIFIED, 32, channels, channels * 4, AudioSystem.NOT_SPECIFIED, 32, channels, channels * 4,
AudioSystem.NOT_SPECIFIED, true)); AudioSystem.NOT_SPECIFIED, true));
formats.add(new AudioFormat(AudioFloatConverter.PCM_FLOAT, formats.add(new AudioFormat(Encoding.PCM_FLOAT,
AudioSystem.NOT_SPECIFIED, 64, channels, channels * 8, AudioSystem.NOT_SPECIFIED, 64, channels, channels * 8,
AudioSystem.NOT_SPECIFIED, false)); AudioSystem.NOT_SPECIFIED, false));
formats.add(new AudioFormat(AudioFloatConverter.PCM_FLOAT, formats.add(new AudioFormat(Encoding.PCM_FLOAT,
AudioSystem.NOT_SPECIFIED, 64, channels, channels * 8, AudioSystem.NOT_SPECIFIED, 64, channels, channels * 8,
AudioSystem.NOT_SPECIFIED, true)); AudioSystem.NOT_SPECIFIED, true));
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -271,7 +271,7 @@ public class WaveExtensibleFileReader extends AudioFileReader {
bits, channels, framesize, samplerate, false, p); bits, channels, framesize, samplerate, false, p);
} }
} else if (subFormat.equals(SUBTYPE_IEEE_FLOAT)) { } else if (subFormat.equals(SUBTYPE_IEEE_FLOAT)) {
audioformat = new AudioFormat(AudioFloatConverter.PCM_FLOAT, audioformat = new AudioFormat(Encoding.PCM_FLOAT,
samplerate, bits, channels, framesize, samplerate, false, p); samplerate, bits, channels, framesize, samplerate, false, p);
} else } else
throw new UnsupportedAudioFileException(); throw new UnsupportedAudioFileException();

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -33,6 +33,7 @@ import java.net.URL;
import javax.sound.sampled.AudioFileFormat; import javax.sound.sampled.AudioFileFormat;
import javax.sound.sampled.AudioFormat; import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioFormat.Encoding;
import javax.sound.sampled.AudioInputStream; import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem; import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.UnsupportedAudioFileException; import javax.sound.sampled.UnsupportedAudioFileException;
@ -102,7 +103,7 @@ public class WaveFloatFileReader extends AudioFileReader {
throw new UnsupportedAudioFileException(); throw new UnsupportedAudioFileException();
AudioFormat audioformat = new AudioFormat( AudioFormat audioformat = new AudioFormat(
AudioFloatConverter.PCM_FLOAT, samplerate, bits, channels, Encoding.PCM_FLOAT, samplerate, bits, channels,
framesize, samplerate, false); framesize, samplerate, false);
AudioFileFormat fileformat = new AudioFileFormat( AudioFileFormat fileformat = new AudioFileFormat(
AudioFileFormat.Type.WAVE, audioformat, AudioFileFormat.Type.WAVE, audioformat,

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -30,6 +30,7 @@ import java.io.OutputStream;
import javax.sound.sampled.AudioFileFormat; import javax.sound.sampled.AudioFileFormat;
import javax.sound.sampled.AudioFormat; import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioFormat.Encoding;
import javax.sound.sampled.AudioInputStream; import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem; import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.AudioFileFormat.Type; import javax.sound.sampled.AudioFileFormat.Type;
@ -48,8 +49,7 @@ public class WaveFloatFileWriter extends AudioFileWriter {
public Type[] getAudioFileTypes(AudioInputStream stream) { public Type[] getAudioFileTypes(AudioInputStream stream) {
if (!stream.getFormat().getEncoding().equals( if (!stream.getFormat().getEncoding().equals(Encoding.PCM_FLOAT))
AudioFloatConverter.PCM_FLOAT))
return new Type[0]; return new Type[0];
return new Type[] { Type.WAVE }; return new Type[] { Type.WAVE };
} }
@ -58,8 +58,7 @@ public class WaveFloatFileWriter extends AudioFileWriter {
if (!Type.WAVE.equals(type)) if (!Type.WAVE.equals(type))
throw new IllegalArgumentException("File type " + type throw new IllegalArgumentException("File type " + type
+ " not supported."); + " not supported.");
if (!stream.getFormat().getEncoding().equals( if (!stream.getFormat().getEncoding().equals(Encoding.PCM_FLOAT))
AudioFloatConverter.PCM_FLOAT))
throw new IllegalArgumentException("File format " throw new IllegalArgumentException("File format "
+ stream.getFormat() + " not supported."); + stream.getFormat() + " not supported.");
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1999, 2007, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -552,14 +552,14 @@ public class AudioFormat {
* which is simply a linear (proportional) representation of the sound * which is simply a linear (proportional) representation of the sound
* waveform. With PCM, the number stored in each sample is proportional * waveform. With PCM, the number stored in each sample is proportional
* to the instantaneous amplitude of the sound pressure at that point in * to the instantaneous amplitude of the sound pressure at that point in
* time. The numbers are frequently signed or unsigned integers. * time. The numbers may be signed or unsigned integers or floats.
* Besides PCM, other encodings include mu-law and a-law, which are nonlinear * Besides PCM, other encodings include mu-law and a-law, which are nonlinear
* mappings of the sound amplitude that are often used for recording speech. * mappings of the sound amplitude that are often used for recording speech.
* <p> * <p>
* You can use a predefined encoding by referring to one of the static * You can use a predefined encoding by referring to one of the static
* objects created by this class, such as PCM_SIGNED or * objects created by this class, such as PCM_SIGNED or
* PCM_UNSIGNED. Service providers can create new encodings, such as * PCM_UNSIGNED. Service providers can create new encodings, such as
* compressed audio formats or floating-point PCM samples, and make * compressed audio formats, and make
* these available through the <code>{@link AudioSystem}</code> class. * these available through the <code>{@link AudioSystem}</code> class.
* <p> * <p>
* The <code>Encoding</code> class is static, so that all * The <code>Encoding</code> class is static, so that all
@ -589,6 +589,13 @@ public class AudioFormat {
*/ */
public static final Encoding PCM_UNSIGNED = new Encoding("PCM_UNSIGNED"); public static final Encoding PCM_UNSIGNED = new Encoding("PCM_UNSIGNED");
/**
* Specifies floating-point PCM data.
*
* @since 1.7
*/
public static final Encoding PCM_FLOAT = new Encoding("PCM_FLOAT");
/** /**
* Specifies u-law encoded data. * Specifies u-law encoded data.
*/ */

View File

@ -0,0 +1,86 @@
/*
* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* @test
* @bug 6944033
* @summary Tests that PCM_FLOAT encoding is supported
* @compile -source 1.7 PCM_FLOAT_support.java
* @run main PCM_FLOAT_support
* @author Alex Menkov
*
*/
import javax.sound.sampled.AudioFormat.Encoding;
import javax.sound.sampled.AudioSystem;
public class PCM_FLOAT_support {
static Encoding pcmFloatEnc;
static boolean testFailed = false;
public static void main(String[] args) throws Exception {
// 1st checks Encoding.PCM_FLOAT is available
pcmFloatEnc = Encoding.PCM_FLOAT;
Encoding[] encodings = AudioSystem.getTargetEncodings(pcmFloatEnc);
out("conversion from PCM_FLOAT to " + encodings.length + " encodings:");
for (Encoding e: encodings) {
out(" - " + e);
}
if (encodings.length == 0) {
testFailed = true;
}
test(Encoding.PCM_SIGNED);
test(Encoding.PCM_UNSIGNED);
if (testFailed) {
throw new Exception("test failed");
}
out("test passed.");
}
static void out(String s) {
System.out.println(s);
}
static boolean test(Encoding enc) {
out("conversion " + enc + " -> PCM_FLOAT:");
Encoding[] encodings = AudioSystem.getTargetEncodings(enc);
for (Encoding e: encodings) {
if (e.equals(pcmFloatEnc)) {
out(" - OK");
return true;
}
}
out(" - FAILED (not supported)");
testFailed = true;
return false;
}
}