diff --git a/jdk/src/java.desktop/share/classes/com/sun/media/sound/AlawCodec.java b/jdk/src/java.desktop/share/classes/com/sun/media/sound/AlawCodec.java index fcc0e709f2b..f71ee0500f2 100644 --- a/jdk/src/java.desktop/share/classes/com/sun/media/sound/AlawCodec.java +++ b/jdk/src/java.desktop/share/classes/com/sun/media/sound/AlawCodec.java @@ -135,45 +135,48 @@ public final class AlawCodec extends SunCodec { AudioFormat sourceFormat = sourceStream.getFormat(); AudioFormat.Encoding sourceEncoding = sourceFormat.getEncoding(); + if( !isConversionSupported(targetEncoding,sourceStream.getFormat()) ) { + throw new IllegalArgumentException("Unsupported conversion: " + sourceStream.getFormat().toString() + " to " + targetEncoding.toString()); + } if( sourceEncoding.equals( targetEncoding ) ) { return sourceStream; - } else { - AudioFormat targetFormat = null; - if( !isConversionSupported(targetEncoding,sourceStream.getFormat()) ) { - throw new IllegalArgumentException("Unsupported conversion: " + sourceStream.getFormat().toString() + " to " + targetEncoding.toString()); - } - if( sourceEncoding.equals( AudioFormat.Encoding.ALAW ) && - targetEncoding.equals( AudioFormat.Encoding.PCM_SIGNED ) ) { - - targetFormat = new AudioFormat( targetEncoding, - sourceFormat.getSampleRate(), - 16, - sourceFormat.getChannels(), - 2*sourceFormat.getChannels(), - sourceFormat.getSampleRate(), - sourceFormat.isBigEndian()); - - } else if( sourceEncoding.equals( AudioFormat.Encoding.PCM_SIGNED ) && - targetEncoding.equals( AudioFormat.Encoding.ALAW ) ) { - - targetFormat = new AudioFormat( targetEncoding, - sourceFormat.getSampleRate(), - 8, - sourceFormat.getChannels(), - sourceFormat.getChannels(), - sourceFormat.getSampleRate(), - false); - } else { - throw new IllegalArgumentException("Unsupported conversion: " + sourceStream.getFormat().toString() + " to " + targetEncoding.toString()); - } - return getAudioInputStream( targetFormat, sourceStream ); } + AudioFormat targetFormat = null; + if( sourceEncoding.equals( AudioFormat.Encoding.ALAW ) && + targetEncoding.equals( AudioFormat.Encoding.PCM_SIGNED ) ) { + + targetFormat = new AudioFormat( targetEncoding, + sourceFormat.getSampleRate(), + 16, + sourceFormat.getChannels(), + 2*sourceFormat.getChannels(), + sourceFormat.getSampleRate(), + sourceFormat.isBigEndian()); + + } else if( sourceEncoding.equals( AudioFormat.Encoding.PCM_SIGNED ) && + targetEncoding.equals( AudioFormat.Encoding.ALAW ) ) { + + targetFormat = new AudioFormat( targetEncoding, + sourceFormat.getSampleRate(), + 8, + sourceFormat.getChannels(), + sourceFormat.getChannels(), + sourceFormat.getSampleRate(), + false); + } else { + throw new IllegalArgumentException("Unsupported conversion: " + sourceStream.getFormat().toString() + " to " + targetEncoding.toString()); + } + return getConvertedStream(targetFormat, sourceStream); } /** * use old code... */ public AudioInputStream getAudioInputStream(AudioFormat targetFormat, AudioInputStream sourceStream){ + if (!isConversionSupported(targetFormat, sourceStream.getFormat())) + throw new IllegalArgumentException("Unsupported conversion: " + + sourceStream.getFormat().toString() + " to " + + targetFormat.toString()); return getConvertedStream( targetFormat, sourceStream ); } @@ -218,33 +221,28 @@ public final class AlawCodec extends SunCodec { Vector formats = new Vector<>(); AudioFormat format; - if ( AudioFormat.Encoding.PCM_SIGNED.equals(inputFormat.getEncoding())) { + if (inputFormat.getSampleSizeInBits() == 16 + && AudioFormat.Encoding.PCM_SIGNED.equals(inputFormat.getEncoding())) { format = new AudioFormat(AudioFormat.Encoding.ALAW, - inputFormat.getSampleRate(), - 8, + inputFormat.getSampleRate(), 8, inputFormat.getChannels(), inputFormat.getChannels(), - inputFormat.getSampleRate(), - false ); + inputFormat.getSampleRate(), false); formats.addElement(format); } - - if (AudioFormat.Encoding.ALAW.equals(inputFormat.getEncoding())) { + if (inputFormat.getSampleSizeInBits() == 8 + && AudioFormat.Encoding.ALAW.equals(inputFormat.getEncoding())) { format = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, - inputFormat.getSampleRate(), - 16, + inputFormat.getSampleRate(), 16, inputFormat.getChannels(), - inputFormat.getChannels()*2, - inputFormat.getSampleRate(), - false ); + inputFormat.getChannels() * 2, + inputFormat.getSampleRate(), false); formats.addElement(format); format = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, - inputFormat.getSampleRate(), - 16, + inputFormat.getSampleRate(), 16, inputFormat.getChannels(), - inputFormat.getChannels()*2, - inputFormat.getSampleRate(), - true ); + inputFormat.getChannels() * 2, + inputFormat.getSampleRate(), true); formats.addElement(format); } diff --git a/jdk/src/java.desktop/share/classes/com/sun/media/sound/AudioFloatFormatConverter.java b/jdk/src/java.desktop/share/classes/com/sun/media/sound/AudioFloatFormatConverter.java index a1e522afb40..21ee186cb71 100644 --- a/jdk/src/java.desktop/share/classes/com/sun/media/sound/AudioFloatFormatConverter.java +++ b/jdk/src/java.desktop/share/classes/com/sun/media/sound/AudioFloatFormatConverter.java @@ -22,6 +22,7 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ + package com.sun.media.sound; import java.io.IOException; @@ -475,6 +476,11 @@ public final class AudioFloatFormatConverter extends FormatConversionProvider { public AudioInputStream getAudioInputStream(Encoding targetEncoding, AudioInputStream sourceStream) { + if (!isConversionSupported(targetEncoding, sourceStream.getFormat())) { + throw new IllegalArgumentException( + "Unsupported conversion: " + sourceStream.getFormat() + .toString() + " to " + targetEncoding.toString()); + } if (sourceStream.getFormat().getEncoding().equals(targetEncoding)) return sourceStream; AudioFormat format = sourceStream.getFormat(); diff --git a/jdk/src/java.desktop/share/classes/com/sun/media/sound/PCMtoPCMCodec.java b/jdk/src/java.desktop/share/classes/com/sun/media/sound/PCMtoPCMCodec.java index 6ef8268f34c..5ba0558099d 100644 --- a/jdk/src/java.desktop/share/classes/com/sun/media/sound/PCMtoPCMCodec.java +++ b/jdk/src/java.desktop/share/classes/com/sun/media/sound/PCMtoPCMCodec.java @@ -33,7 +33,6 @@ import javax.sound.sampled.AudioFormat; import javax.sound.sampled.AudioInputStream; import javax.sound.sampled.AudioSystem; - /** * Converts among signed/unsigned and little/big endianness of sampled. * @@ -52,11 +51,6 @@ public final class PCMtoPCMCodec extends SunCodec { AudioFormat.Encoding.PCM_UNSIGNED, }; - - - private static final int tempBufferSize = 64; - private byte tempBuffer [] = null; - /** * Constructs a new PCMtoPCM codec object. */ @@ -67,21 +61,31 @@ public final class PCMtoPCMCodec extends SunCodec { // NEW CODE + public AudioFormat.Encoding[] getTargetEncodings(AudioFormat sourceFormat) { - /** - */ - public AudioFormat.Encoding[] getTargetEncodings(AudioFormat sourceFormat){ - - if( sourceFormat.getEncoding().equals( AudioFormat.Encoding.PCM_SIGNED ) || - sourceFormat.getEncoding().equals( AudioFormat.Encoding.PCM_UNSIGNED ) ) { - - AudioFormat.Encoding encs[] = new AudioFormat.Encoding[2]; - encs[0] = AudioFormat.Encoding.PCM_SIGNED; - encs[1] = AudioFormat.Encoding.PCM_UNSIGNED; - return encs; - } else { - return new AudioFormat.Encoding[0]; + final int sampleSize = sourceFormat.getSampleSizeInBits(); + AudioFormat.Encoding encoding = sourceFormat.getEncoding(); + if (sampleSize == 8) { + if (encoding.equals(AudioFormat.Encoding.PCM_SIGNED)) { + return new AudioFormat.Encoding[]{ + AudioFormat.Encoding.PCM_UNSIGNED + }; } + if (encoding.equals(AudioFormat.Encoding.PCM_UNSIGNED)) { + return new AudioFormat.Encoding[]{ + AudioFormat.Encoding.PCM_SIGNED + }; + } + } else if (sampleSize == 16) { + if (encoding.equals(AudioFormat.Encoding.PCM_SIGNED) + || encoding.equals(AudioFormat.Encoding.PCM_UNSIGNED)) { + return new AudioFormat.Encoding[]{ + AudioFormat.Encoding.PCM_UNSIGNED, + AudioFormat.Encoding.PCM_SIGNED + }; + } + } + return new AudioFormat.Encoding[0]; } @@ -125,7 +129,7 @@ public final class PCMtoPCMCodec extends SunCodec { sourceFormat.getFrameRate(), sourceFormat.isBigEndian() ); - return getAudioInputStream( targetFormat, sourceStream ); + return getConvertedStream(targetFormat, sourceStream); } else { throw new IllegalArgumentException("Unsupported conversion: " + sourceStream.getFormat().toString() + " to " + targetEncoding.toString() ); @@ -136,7 +140,10 @@ public final class PCMtoPCMCodec extends SunCodec { * use old code */ public AudioInputStream getAudioInputStream(AudioFormat targetFormat, AudioInputStream sourceStream){ - + if (!isConversionSupported(targetFormat, sourceStream.getFormat())) + throw new IllegalArgumentException("Unsupported conversion: " + + sourceStream.getFormat().toString() + " to " + + targetFormat.toString()); return getConvertedStream( targetFormat, sourceStream ); } @@ -166,7 +173,6 @@ public final class PCMtoPCMCodec extends SunCodec { } else { cs = (AudioInputStream) (new PCMtoPCMCodecStream(stream, outputFormat)); - tempBuffer = new byte[tempBufferSize]; } return cs; } diff --git a/jdk/src/java.desktop/share/classes/com/sun/media/sound/SunCodec.java b/jdk/src/java.desktop/share/classes/com/sun/media/sound/SunCodec.java index 232789352c5..773fea0e515 100644 --- a/jdk/src/java.desktop/share/classes/com/sun/media/sound/SunCodec.java +++ b/jdk/src/java.desktop/share/classes/com/sun/media/sound/SunCodec.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2015, 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 @@ -26,11 +26,8 @@ package com.sun.media.sound; import javax.sound.sampled.AudioFormat; -import javax.sound.sampled.AudioInputStream; - import javax.sound.sampled.spi.FormatConversionProvider; - /** * A codec can encode and/or decode audio data. It provides an * AudioInputStream from which processed data may be read. @@ -73,23 +70,4 @@ abstract class SunCodec extends FormatConversionProvider { System.arraycopy(outputEncodings, 0, encodings, 0, outputEncodings.length); return encodings; } - - /** - */ - public abstract AudioFormat.Encoding[] getTargetEncodings(AudioFormat sourceFormat); - - - /** - */ - public abstract AudioFormat[] getTargetFormats(AudioFormat.Encoding targetEncoding, AudioFormat sourceFormat); - - - /** - */ - public abstract AudioInputStream getAudioInputStream(AudioFormat.Encoding targetEncoding, AudioInputStream sourceStream); - /** - */ - public abstract AudioInputStream getAudioInputStream(AudioFormat targetFormat, AudioInputStream sourceStream); - - } diff --git a/jdk/src/java.desktop/share/classes/com/sun/media/sound/UlawCodec.java b/jdk/src/java.desktop/share/classes/com/sun/media/sound/UlawCodec.java index dc088ee459c..761b4404ebe 100644 --- a/jdk/src/java.desktop/share/classes/com/sun/media/sound/UlawCodec.java +++ b/jdk/src/java.desktop/share/classes/com/sun/media/sound/UlawCodec.java @@ -26,13 +26,12 @@ package com.sun.media.sound; import java.io.IOException; - import java.util.Objects; import java.util.Vector; import javax.sound.sampled.AudioFormat; -import javax.sound.sampled.AudioSystem; import javax.sound.sampled.AudioInputStream; +import javax.sound.sampled.AudioSystem; /** @@ -126,43 +125,46 @@ public final class UlawCodec extends SunCodec { AudioFormat sourceFormat = sourceStream.getFormat(); AudioFormat.Encoding sourceEncoding = sourceFormat.getEncoding(); + if (!isConversionSupported(targetEncoding,sourceStream.getFormat())) { + throw new IllegalArgumentException("Unsupported conversion: " + sourceStream.getFormat().toString() + " to " + targetEncoding.toString()); + } if (sourceEncoding.equals(targetEncoding)) { return sourceStream; - } else { - AudioFormat targetFormat = null; - if (!isConversionSupported(targetEncoding,sourceStream.getFormat())) { - throw new IllegalArgumentException("Unsupported conversion: " + sourceStream.getFormat().toString() + " to " + targetEncoding.toString()); - } - if (AudioFormat.Encoding.ULAW.equals(sourceEncoding) && - AudioFormat.Encoding.PCM_SIGNED.equals(targetEncoding) ) { - targetFormat = new AudioFormat( targetEncoding, - sourceFormat.getSampleRate(), - 16, - sourceFormat.getChannels(), - 2*sourceFormat.getChannels(), - sourceFormat.getSampleRate(), - sourceFormat.isBigEndian()); - } else if (AudioFormat.Encoding.PCM_SIGNED.equals(sourceEncoding) && - AudioFormat.Encoding.ULAW.equals(targetEncoding)) { - targetFormat = new AudioFormat( targetEncoding, - sourceFormat.getSampleRate(), - 8, - sourceFormat.getChannels(), - sourceFormat.getChannels(), - sourceFormat.getSampleRate(), - false); - } else { - throw new IllegalArgumentException("Unsupported conversion: " + sourceStream.getFormat().toString() + " to " + targetEncoding.toString()); - } - - return getAudioInputStream( targetFormat, sourceStream ); } + AudioFormat targetFormat = null; + if (AudioFormat.Encoding.ULAW.equals(sourceEncoding) && + AudioFormat.Encoding.PCM_SIGNED.equals(targetEncoding) ) { + targetFormat = new AudioFormat( targetEncoding, + sourceFormat.getSampleRate(), + 16, + sourceFormat.getChannels(), + 2*sourceFormat.getChannels(), + sourceFormat.getSampleRate(), + sourceFormat.isBigEndian()); + } else if (AudioFormat.Encoding.PCM_SIGNED.equals(sourceEncoding) && + AudioFormat.Encoding.ULAW.equals(targetEncoding)) { + targetFormat = new AudioFormat( targetEncoding, + sourceFormat.getSampleRate(), + 8, + sourceFormat.getChannels(), + sourceFormat.getChannels(), + sourceFormat.getSampleRate(), + false); + } else { + throw new IllegalArgumentException("Unsupported conversion: " + sourceStream.getFormat().toString() + " to " + targetEncoding.toString()); + } + + return getConvertedStream(targetFormat, sourceStream); } /** * use old code... */ public AudioInputStream getAudioInputStream(AudioFormat targetFormat, AudioInputStream sourceStream){ + if (!isConversionSupported(targetFormat, sourceStream.getFormat())) + throw new IllegalArgumentException("Unsupported conversion: " + + sourceStream.getFormat().toString() + " to " + + targetFormat.toString()); return getConvertedStream(targetFormat, sourceStream); } @@ -215,24 +217,20 @@ public final class UlawCodec extends SunCodec { false ); formats.addElement(format); } - - if (AudioFormat.Encoding.ULAW.equals(inputFormat.getEncoding())) { + if (inputFormat.getSampleSizeInBits() == 8 + && AudioFormat.Encoding.ULAW.equals(inputFormat.getEncoding())) { format = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, - inputFormat.getSampleRate(), - 16, + inputFormat.getSampleRate(), 16, inputFormat.getChannels(), - inputFormat.getChannels()*2, - inputFormat.getSampleRate(), - false ); + inputFormat.getChannels() * 2, + inputFormat.getSampleRate(), false); formats.addElement(format); format = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, - inputFormat.getSampleRate(), - 16, + inputFormat.getSampleRate(), 16, inputFormat.getChannels(), - inputFormat.getChannels()*2, - inputFormat.getSampleRate(), - true ); + inputFormat.getChannels() * 2, + inputFormat.getSampleRate(), true); formats.addElement(format); } diff --git a/jdk/src/java.desktop/share/classes/javax/sound/sampled/AudioSystem.java b/jdk/src/java.desktop/share/classes/javax/sound/sampled/AudioSystem.java index 4476bb4ba42..3f1610f763a 100644 --- a/jdk/src/java.desktop/share/classes/javax/sound/sampled/AudioSystem.java +++ b/jdk/src/java.desktop/share/classes/javax/sound/sampled/AudioSystem.java @@ -32,6 +32,7 @@ import java.io.InputStream; import java.io.OutputStream; import java.net.URL; import java.util.ArrayList; +import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Objects; @@ -689,8 +690,11 @@ public class AudioSystem { } } } - AudioFormat.Encoding encs2[] = encodings.toArray(new AudioFormat.Encoding[0]); - return encs2; + if (!encodings.contains(sourceEncoding)) { + encodings.addElement(sourceEncoding); + } + + return encodings.toArray(new AudioFormat.Encoding[encodings.size()]); } // $$fb 2002-04-12: fix for 4662082: behavior of AudioSystem.getTargetEncodings() methods doesn't match the spec @@ -711,30 +715,18 @@ public class AudioSystem { Objects.requireNonNull(sourceFormat); List codecs = getFormatConversionProviders(); - Vector encodings = new Vector<>(); - - int size = 0; - int index = 0; - AudioFormat.Encoding encs[] = null; + List encs = new ArrayList<>(); // gather from all the codecs - - for(int i=0; i codecs = getFormatConversionProviders(); @@ -782,6 +777,9 @@ public class AudioSystem { AudioInputStream sourceStream) { Objects.requireNonNull(targetEncoding); Objects.requireNonNull(sourceStream); + if (sourceStream.getFormat().getEncoding().equals(targetEncoding)) { + return sourceStream; + } List codecs = getFormatConversionProviders(); @@ -812,31 +810,27 @@ public class AudioSystem { Objects.requireNonNull(sourceFormat); List codecs = getFormatConversionProviders(); - Vector formats = new Vector<>(); - - int size = 0; - int index = 0; - AudioFormat fmts[] = null; + List formats = new ArrayList<>(); + boolean matchFound = false; // gather from all the codecs - - for(int i=0; i codecs = getFormatConversionProviders(); diff --git a/jdk/test/javax/sound/sampled/spi/FormatConversionProvider/GetAudioStreamConversionSupported.java b/jdk/test/javax/sound/sampled/spi/FormatConversionProvider/GetAudioStreamConversionSupported.java new file mode 100644 index 00000000000..c12e13f9b71 --- /dev/null +++ b/jdk/test/javax/sound/sampled/spi/FormatConversionProvider/GetAudioStreamConversionSupported.java @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2015, 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. + * + * 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. + */ + +import java.io.ByteArrayInputStream; +import java.io.InputStream; + +import javax.sound.sampled.AudioFormat; +import javax.sound.sampled.AudioInputStream; +import javax.sound.sampled.AudioSystem; +import javax.sound.sampled.spi.FormatConversionProvider; + +import static java.util.ServiceLoader.load; + +/** + * @test + * @bug 8146144 + */ +public final class GetAudioStreamConversionSupported { + + static final AudioFormat.Encoding[] encodings = { + AudioFormat.Encoding.ALAW, AudioFormat.Encoding.ULAW, + AudioFormat.Encoding.PCM_SIGNED, AudioFormat.Encoding.PCM_UNSIGNED, + AudioFormat.Encoding.PCM_FLOAT, new AudioFormat.Encoding("Test") + }; + + public static void main(final String[] args) { + for (final int sampleSize : new int[]{4, 8, 16, 24, 32}) { + for (final AudioFormat.Encoding enc : encodings) { + for (final Boolean endian : new boolean[]{false, true}) { + testAS(enc, endian, sampleSize); + for (final FormatConversionProvider fcp : load + (FormatConversionProvider.class)) { + testFCP(fcp, enc, endian, sampleSize); + } + } + } + } + } + + /** + * Tests the part of AudioSystem API, which implemented via + * FormatConversionProvider. + *

+ * AudioSystem always support conversion to the same encoding/format. + */ + private static void testAS(final AudioFormat.Encoding enc, + final Boolean endian, final int sampleSize) { + final AudioInputStream ais = getStream(enc, endian, sampleSize); + final AudioFormat format = ais.getFormat(); + if (!AudioSystem.isConversionSupported(enc, format)) { + throw new RuntimeException("Format: " + format); + } + if (!AudioSystem.isConversionSupported(format, format)) { + throw new RuntimeException("Format: " + format); + } + AudioSystem.getAudioInputStream(enc, ais); + AudioSystem.getAudioInputStream(format, ais); + } + + /** + * Tests the FormatConversionProvider API directly. + */ + private static void testFCP(final FormatConversionProvider fcp, + final AudioFormat.Encoding enc, + final Boolean endian, final int sampleSize) { + System.out.println("fcp = " + fcp); + final AudioInputStream ais = getStream(enc, endian, sampleSize); + final AudioFormat frmt = ais.getFormat(); + if (fcp.isConversionSupported(enc, frmt)) { + try { + fcp.getAudioInputStream(enc, ais); + } catch (final IllegalArgumentException ex) { + throw new RuntimeException("Format: " + frmt, ex); + } + } else { + try { + fcp.getAudioInputStream(enc, ais); + throw new RuntimeException("Format: " + frmt); + } catch (final IllegalArgumentException ignored) { + } + try { + fcp.getAudioInputStream(frmt, ais); + throw new RuntimeException("Format: " + frmt); + } catch (final IllegalArgumentException ignored) { + } + } + if (fcp.isConversionSupported(frmt, frmt)) { + try { + fcp.getAudioInputStream(enc, ais); + fcp.getAudioInputStream(frmt, ais); + } catch (final IllegalArgumentException ex) { + throw new RuntimeException("Format: " + frmt, ex); + } + } else { + try { + fcp.getAudioInputStream(frmt, ais); + throw new RuntimeException("Format: " + frmt); + } catch (final IllegalArgumentException ignored) { + } + } + } + + private static AudioInputStream getStream(final AudioFormat.Encoding enc, + final Boolean end, + final int sampleSize) { + final AudioFormat ftmt + = new AudioFormat(enc, 8000, sampleSize, 1, 1, 8000, end); + final byte[] fakedata = new byte[100]; + final InputStream in = new ByteArrayInputStream(fakedata); + return new AudioInputStream(in, ftmt, fakedata.length); + } +} diff --git a/jdk/test/javax/sound/sampled/spi/FormatConversionProvider/GetTargetIsSupported.java b/jdk/test/javax/sound/sampled/spi/FormatConversionProvider/GetTargetIsSupported.java new file mode 100644 index 00000000000..2a44b89ff19 --- /dev/null +++ b/jdk/test/javax/sound/sampled/spi/FormatConversionProvider/GetTargetIsSupported.java @@ -0,0 +1,294 @@ +/* + * Copyright (c) 2015, 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. + * + * 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. + */ + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import javax.sound.sampled.AudioFormat; +import javax.sound.sampled.AudioFormat.Encoding; +import javax.sound.sampled.AudioSystem; +import javax.sound.sampled.spi.FormatConversionProvider; + +import static java.util.ServiceLoader.load; + +/** + * @test + * @bug 8146144 + */ +public final class GetTargetIsSupported { + + /** + * We will try to use all formats, in this case all our providers will be + * covered by supported/unsupported formats. + */ + private static final List formats = new ArrayList<>(23000); + + private static final Encoding[] encodings = { + Encoding.ALAW, Encoding.ULAW, Encoding.PCM_SIGNED, + Encoding.PCM_UNSIGNED, Encoding.PCM_FLOAT, new Encoding("Test") + }; + + private static final int[] sampleRates = { + AudioSystem.NOT_SPECIFIED, 8000, 11025, 16000, 22050, 32000, 37800, + 44056, 44100, 47250, 48000, 50000, 50400, 88200, 96000, 176400, + 192000, 352800, 2822400, 5644800 + }; + + private static final int[] sampleBits = { + AudioSystem.NOT_SPECIFIED, 4, 8, 11, 16, 20, 24, 32, 48, 64, 128 + }; + + private static final int[] channels = { + AudioSystem.NOT_SPECIFIED, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 + }; + + static { + for (final Boolean end : new boolean[]{false, true}) { + for (final int sampleSize : sampleBits) { + for (final int sampleRate : sampleRates) { + for (final int channel : channels) { + for (final Encoding enc : encodings) { + formats.add(new AudioFormat(enc, sampleRate, + sampleSize, channel, + 1, sampleRate, end)); + } + } + } + } + } + } + + public static void main(final String[] args) { + for (final AudioFormat format : formats) { + testAS(format); + for (final FormatConversionProvider fcp : load + (FormatConversionProvider.class)) { + testFCP(fcp, format); + } + } + } + + /** + * Tests the part of AudioSystem API, which implemented via + * FormatConversionProvider. + * + * @see AudioSystem#getTargetEncodings(Encoding) + * @see AudioSystem#getTargetEncodings(AudioFormat) + * @see AudioSystem#getTargetFormats(Encoding, AudioFormat) + * @see AudioSystem#isConversionSupported(AudioFormat, AudioFormat) + * @see AudioSystem#isConversionSupported(Encoding, AudioFormat) + */ + private static void testAS(final AudioFormat source) { + Encoding[] all = AudioSystem.getTargetEncodings(source.getEncoding()); + Encoding[] part = AudioSystem.getTargetEncodings(source); + + // Check encodings which are reported as supported + for (final Encoding enc : part) { + // If encoding is reported for the source format means that + // the list of target formats should not be empty + AudioFormat[] targets = AudioSystem.getTargetFormats(enc, source); + // all reported formats should be supported + for (final AudioFormat target : targets) { + if (!AudioSystem.isConversionSupported(target, source)) { + throw new RuntimeException("Error:" + enc); + } + if (!enc.equals(target.getEncoding())) { + throw new RuntimeException("Error:" + enc); + } + } + // If encoding is reported for the source format means that + // conversion source -> encoding is supported + if (!AudioSystem.isConversionSupported(enc, source)) { + throw new RuntimeException("Error:" + enc); + } + // encoding for a particular source should be included in the + // list of all encodings for the source's encoding + if (!Arrays.asList(all).contains(enc)) { + throw new RuntimeException("Error:" + enc); + } + // If conversion source -> encoding is supported then an + // array of target formats should not be empty + if (source.getEncoding().equals(enc)) { + // this is unspecified but we works this way + if (!isContains(source, targets)) { + throw new RuntimeException("Error:" + enc); + } + } else { + if (targets.length == 0) { + throw new RuntimeException("Error:" + enc); + } + } + } + + // Check all encodings + for (final Encoding enc : encodings) { + AudioFormat[] targets = AudioSystem.getTargetFormats(enc, source); + // If target format is reported for the source format means that + // conversion source -> target is supported + for (final AudioFormat target : targets) { + if (!AudioSystem.isConversionSupported(target, source)) { + throw new RuntimeException("Error:" + enc); + } + if (!enc.equals(target.getEncoding())) { + throw new RuntimeException("Error:" + enc); + } + } + if (AudioSystem.isConversionSupported(enc, source)) { + // encoding for a particular source should be included in the + // list of all encodings for the source's encoding + if (!Arrays.asList(all).contains(enc)) { + throw new RuntimeException("Error:" + enc); + } + if (!Arrays.asList(part).contains(enc)) { + System.out.println("enc = " + enc); + System.out.println("part = " + Arrays.toString(part)); + System.out.println("source = " + source); + throw new RuntimeException("Error:" + enc); + } + // If conversion source -> encoding is supported then an + // array of target formats should not be empty + if (source.getEncoding().equals(enc)) { + // this is unspecified but we works this way + if (!isContains(source, targets)) { + throw new RuntimeException("Error:" + enc); + } + } else { + if (targets.length == 0) { + throw new RuntimeException("Error:" + enc); + } + } + } else { + // If conversion source -> encoding is not supported then an + // array of target formats should be empty + if (targets.length != 0) { + throw new RuntimeException("Error:" + enc); + } + if (Arrays.asList(part).contains(enc)) { + throw new RuntimeException("Error:" + enc); + } + } + } + } + + /** + * Tests the FormatConversionProvider API directly. + * + * @see FormatConversionProvider#getTargetEncodings() + * @see FormatConversionProvider#getTargetEncodings(AudioFormat) + * @see FormatConversionProvider#getTargetFormats(Encoding, AudioFormat) + * @see FormatConversionProvider#isTargetEncodingSupported(Encoding) + * @see FormatConversionProvider#isConversionSupported(Encoding, + * AudioFormat) + * @see FormatConversionProvider#isConversionSupported(AudioFormat, + * AudioFormat) + */ + private static void testFCP(final FormatConversionProvider fcp, + final AudioFormat source) { + final Encoding[] all = fcp.getTargetEncodings(); + for (final Encoding enc : all) { + if (!fcp.isTargetEncodingSupported(enc)) { + throw new RuntimeException("Error:" + enc); + } + } + + // Check encodings which are reported as supported + final Encoding[] part = fcp.getTargetEncodings(source); + for (final Encoding enc : part) { + // If encoding is reported for the source format means that + // the list of target formats should not be empty for this encoding + AudioFormat[] targets = fcp.getTargetFormats(enc, source); + // all reported formats should be supported + for (final AudioFormat target : targets) { + if (!fcp.isConversionSupported(target, source)) { + throw new RuntimeException("Error:" + enc); + } + if (!enc.equals(target.getEncoding())) { + throw new RuntimeException("Error:" + enc); + } + } + // If encoding is reported for the source format means that + // conversion source -> encoding is supported + if (!fcp.isConversionSupported(enc, source)) { + throw new RuntimeException("Error:" + enc); + } + // If conversion source -> encoding is supported then an + // array of target formats should not be empty + if (targets.length == 0) { + throw new RuntimeException("Error:" + enc); + } + // encoding for a particular source should be included in the + // list of all encodings for the source's encoding + if (!Arrays.asList(all).contains(enc)) { + throw new RuntimeException("Error:" + enc); + } + } + // Check all encodings + for (final Encoding enc : encodings) { + AudioFormat[] targets = fcp.getTargetFormats(enc, source); + // If target format is reported for the source format means that + // conversion source -> target is supported + for (final AudioFormat target : targets) { + if (!fcp.isConversionSupported(target, source)) { + throw new RuntimeException("Error:" + enc); + } + if (!enc.equals(target.getEncoding())) { + throw new RuntimeException("Error:" + enc); + } + } + if (fcp.isConversionSupported(enc, source)) { + // If conversion source -> encoding is supported then an + // array of target formats should not be empty + if (targets.length == 0) { + throw new RuntimeException("Error:" + enc); + } + // encoding for a particular source should be included in the + // list of all encodings for the source's encoding + if (!Arrays.asList(all).contains(enc)) { + throw new RuntimeException("Error:" + enc); + } + if (!Arrays.asList(part).contains(enc)) { + throw new RuntimeException("Error:" + enc); + } + } else { + // If conversion source -> encoding is not supported then an + // array of target formats should be empty + if (targets.length != 0) { + throw new RuntimeException("Error:" + enc); + } + if (Arrays.asList(part).contains(enc)) { + throw new RuntimeException("Error:" + enc); + } + } + } + } + + private static boolean isContains(AudioFormat obj, AudioFormat[] array) { + for (final AudioFormat format : array) { + if (obj.matches(format)) { + return true; + } + } + return false; + } +}