Path: blob/master/test/jdk/javax/sound/sampled/spi/AudioFileReader/RecognizeHugeAuFiles.java
40527 views
/*1* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223import java.io.ByteArrayInputStream;2425import javax.sound.sampled.AudioFileFormat;26import javax.sound.sampled.AudioFormat;27import javax.sound.sampled.AudioInputStream;28import javax.sound.sampled.AudioSystem;2930/**31* @test32* @bug 672983633*/34public final class RecognizeHugeAuFiles {3536/**37* The size of the header's data.38*/39private static final byte AU_HEADER = 44;4041/**42* This value should be used if the size in bytes is unknown.43*/44private static final /* unsigned int */ long MAX_UNSIGNED_INT = 0xffffffffL;4546/**47* The list of supported au formats and sample size in bits per format.48*/49private static final byte[][] auTypeBits = {50{1, 8}, {2, 8}, {3, 16}, {4, 24}, {5, 32}, {6, 32}, {27, 8}51};5253/**54* The list of supported sample rates(stored as unsigned int).55*/56private static final int[] sampleRates = {578000, 11025, 16000, 22050, 32000, 37800, 44056, 44100, 47250, 48000,5850000, 50400, 88200, 96000, 176400, 192000, 352800, 2822400,595644800, Integer.MAX_VALUE60};6162/**63* The list of supported channels (stored as unsigned int).64*/65private static final int[] channels = {661, 2, 3, 4, 5, 6, 7, 8, 9, 1067};6869/**70* The list of supported size of data (stored as unsigned int).71* <p>72* The {@code MAX_UNSIGNED_INT} used if the size in bytes is unknown.73*/74private static final long[] dataSizes = {750, 1, 2, 3, Integer.MAX_VALUE - AU_HEADER, Integer.MAX_VALUE - 1,76Integer.MAX_VALUE, (long) Integer.MAX_VALUE + 1,77(long) Integer.MAX_VALUE + AU_HEADER, MAX_UNSIGNED_INT - AU_HEADER,78MAX_UNSIGNED_INT - 1, MAX_UNSIGNED_INT79};8081public static void main(final String[] args) throws Exception {82for (final byte[] type : auTypeBits) {83for (final int sampleRate : sampleRates) {84for (final int channel : channels) {85for (final long dataSize : dataSizes) {86testAFF(type, sampleRate, channel, dataSize);87testAIS(type, sampleRate, channel, dataSize);88}89}90}91}92}9394/**95* Tests the {@code AudioFileFormat} fetched from the fake header.96* <p>97* Note that the frameLength and byteLength are stored as int which means98* that {@code AudioFileFormat} will store the data above {@code MAX_INT}99* as NOT_SPECIFIED.100*/101private static void testAFF(final byte[] type, final int rate,102final int channel, final long size)103throws Exception {104final byte[] header = createHeader(type, rate, channel, size);105final ByteArrayInputStream fake = new ByteArrayInputStream(header);106final AudioFileFormat aff = AudioSystem.getAudioFileFormat(fake);107final AudioFormat format = aff.getFormat();108109if (aff.getType() != AudioFileFormat.Type.AU) {110throw new RuntimeException("Error");111}112113final long frameLength = size / format.getFrameSize();114if (size != MAX_UNSIGNED_INT && frameLength <= Integer.MAX_VALUE) {115if (aff.getFrameLength() != frameLength) {116System.err.println("Expected: " + frameLength);117System.err.println("Actual: " + aff.getFrameLength());118throw new RuntimeException();119}120} else {121if (aff.getFrameLength() != AudioSystem.NOT_SPECIFIED) {122System.err.println("Expected: " + AudioSystem.NOT_SPECIFIED);123System.err.println("Actual: " + aff.getFrameLength());124throw new RuntimeException();125}126}127128final long byteLength = size + AU_HEADER;129if (byteLength <= Integer.MAX_VALUE) {130if (aff.getByteLength() != byteLength) {131System.err.println("Expected: " + byteLength);132System.err.println("Actual: " + aff.getByteLength());133throw new RuntimeException();134}135} else {136if (aff.getByteLength() != AudioSystem.NOT_SPECIFIED) {137System.err.println("Expected: " + AudioSystem.NOT_SPECIFIED);138System.err.println("Actual: " + aff.getByteLength());139throw new RuntimeException();140}141}142validateFormat(type[1], rate, channel, aff.getFormat());143}144145/**146* Tests the {@code AudioInputStream} fetched from the fake header.147* <p>148* Note that the frameLength is stored as long which means149* that {@code AudioInputStream} must store all possible data from au file.150*/151private static void testAIS(final byte[] type, final int rate,152final int channel, final long size)153throws Exception {154final byte[] header = createHeader(type, rate, channel, size);155final ByteArrayInputStream fake = new ByteArrayInputStream(header);156final AudioInputStream ais = AudioSystem.getAudioInputStream(fake);157final AudioFormat format = ais.getFormat();158final long frameLength = size / format.getFrameSize();159if (size != MAX_UNSIGNED_INT) {160if (frameLength != ais.getFrameLength()) {161System.err.println("Expected: " + frameLength);162System.err.println("Actual: " + ais.getFrameLength());163throw new RuntimeException();164}165} else {166if (ais.getFrameLength() != AudioSystem.NOT_SPECIFIED) {167System.err.println("Expected: " + AudioSystem.NOT_SPECIFIED);168System.err.println("Actual: " + ais.getFrameLength());169throw new RuntimeException();170}171}172if (ais.available() < 0) {173System.err.println("available should be >=0: " + ais.available());174throw new RuntimeException();175}176validateFormat(type[1], rate, channel, format);177}178179/**180* Tests that format contains the same data as were provided to the fake181* stream.182*/183private static void validateFormat(final byte bits, final int rate,184final int channel,185final AudioFormat format) {186187if (Float.compare(format.getSampleRate(), rate) != 0) {188System.out.println("Expected: " + rate);189System.out.println("Actual: " + format.getSampleRate());190throw new RuntimeException();191}192if (format.getChannels() != channel) {193System.out.println("Expected: " + channel);194System.out.println("Actual: " + format.getChannels());195throw new RuntimeException();196}197int frameSize = ((bits + 7) / 8) * channel;198if (format.getFrameSize() != frameSize) {199System.out.println("Expected: " + frameSize);200System.out.println("Actual: " + format.getFrameSize());201throw new RuntimeException();202}203}204205/**206* Creates the custom header of the AU file. It is expected that all passed207* data are supported.208*/209private static byte[] createHeader(final byte[] type, final int rate,210final int channel, final long size) {211return new byte[]{212// AU_SUN_MAGIC2130x2e, 0x73, 0x6e, 0x64,214// headerSize2150, 0, 0, AU_HEADER,216// dataSize217(byte) (size >> 24), (byte) (size >> 16), (byte) (size >> 8),218(byte) size,219// encoding2200, 0, 0, type[0],221// sampleRate222(byte) (rate >> 24), (byte) (rate >> 16), (byte) (rate >> 8),223(byte) (rate),224// channels225(byte) (channel >> 24), (byte) (channel >> 16),226(byte) (channel >> 8), (byte) (channel),227// data2280, 0, 0, 0, 0, 0229};230}231}232233234