Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/test/jdk/javax/sound/sampled/spi/AudioFileReader/RecognizeHugeAiffFiles.java
40527 views
1
/*
2
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
*
5
* This code is free software; you can redistribute it and/or modify it
6
* under the terms of the GNU General Public License version 2 only, as
7
* published by the Free Software Foundation.
8
*
9
* This code is distributed in the hope that it will be useful, but WITHOUT
10
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12
* version 2 for more details (a copy is included in the LICENSE file that
13
* accompanied this code).
14
*
15
* You should have received a copy of the GNU General Public License version
16
* 2 along with this work; if not, write to the Free Software Foundation,
17
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18
*
19
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20
* or visit www.oracle.com if you need additional information or have any
21
* questions.
22
*/
23
24
import java.io.ByteArrayInputStream;
25
26
import javax.sound.sampled.AudioFileFormat;
27
import javax.sound.sampled.AudioFormat;
28
import javax.sound.sampled.AudioInputStream;
29
import javax.sound.sampled.AudioSystem;
30
31
/**
32
* @test
33
* @bug 6729836
34
*/
35
public final class RecognizeHugeAiffFiles {
36
37
/**
38
* The maximum number of sample frames per AIFF specification.
39
*/
40
private static final /* unsigned int */ long MAX_UNSIGNED_INT = 0xffffffffL;
41
42
/**
43
* The supported aiff sample size in bits.
44
*/
45
private static final byte[] aiffBits = {
46
1, 2, 4, 8, 11, 16, 20, 24, 27, 32
47
};
48
49
/**
50
* The list of supported sample rates.
51
*/
52
private static final int[] sampleRates = {
53
8000, 11025, 16000, 22050, 32000, 37800, 44056, 44100, 47250, 48000,
54
50000, 50400, 88200, 96000, 176400, 192000, 352800, 2822400,
55
5644800, Integer.MAX_VALUE
56
};
57
58
/**
59
* The list of supported channels.
60
*/
61
private static final int[] channels = {
62
1, 2, 3, 4, 5, 6, 7, 8, 9, 10
63
};
64
65
/**
66
* The list of supported number of frames.
67
* <p>
68
* The {@code MAX_UNSIGNED_INT} is a maximum.
69
*/
70
private static final long[] numberOfFrames = {
71
0, 1, 2, 3, Integer.MAX_VALUE - 1, Integer.MAX_VALUE,
72
(long) Integer.MAX_VALUE + 1, MAX_UNSIGNED_INT - 1, MAX_UNSIGNED_INT
73
};
74
75
public static void main(final String[] args) throws Exception {
76
for (final byte bits : aiffBits) {
77
for (final int sampleRate : sampleRates) {
78
for (final int channel : channels) {
79
for (final long dataSize : numberOfFrames) {
80
testAFF(bits, sampleRate, channel, dataSize);
81
testAIS(bits, sampleRate, channel, dataSize);
82
}
83
}
84
}
85
}
86
}
87
88
/**
89
* Tests the {@code AudioFileFormat} fetched from the fake header.
90
* <p>
91
* Note that the frameLength and byteLength are stored as int which means
92
* that {@code AudioFileFormat} will store the data above {@code MAX_INT} as
93
* NOT_SPECIFIED.
94
*/
95
private static void testAFF(final byte bits, final int rate,
96
final int channel, final long frameLength)
97
throws Exception {
98
final byte[] header = createHeader(bits, rate, channel, frameLength);
99
final ByteArrayInputStream fake = new ByteArrayInputStream(header);
100
final AudioFileFormat aff = AudioSystem.getAudioFileFormat(fake);
101
102
if (aff.getType() != AudioFileFormat.Type.AIFF) {
103
throw new RuntimeException("Error");
104
}
105
106
if (frameLength <= Integer.MAX_VALUE) {
107
if (aff.getFrameLength() != frameLength) {
108
System.err.println("Expected: " + frameLength);
109
System.err.println("Actual: " + aff.getFrameLength());
110
throw new RuntimeException();
111
}
112
} else {
113
if (aff.getFrameLength() != AudioSystem.NOT_SPECIFIED) {
114
System.err.println("Expected: " + AudioSystem.NOT_SPECIFIED);
115
System.err.println("Actual: " + aff.getFrameLength());
116
throw new RuntimeException();
117
}
118
}
119
validateFormat(bits, rate, channel, aff.getFormat());
120
}
121
122
/**
123
* Tests the {@code AudioInputStream} fetched from the fake header.
124
* <p>
125
* Note that the frameLength is stored as long which means that {@code
126
* AudioInputStream} must store all possible data from aiff file.
127
*/
128
private static void testAIS(final byte bits, final int rate,
129
final int channel, final long frameLength)
130
throws Exception {
131
final byte[] header = createHeader(bits, rate, channel, frameLength);
132
final ByteArrayInputStream fake = new ByteArrayInputStream(header);
133
final AudioInputStream ais = AudioSystem.getAudioInputStream(fake);
134
final AudioFormat format = ais.getFormat();
135
136
if (frameLength != ais.getFrameLength()) {
137
System.err.println("Expected: " + frameLength);
138
System.err.println("Actual: " + ais.getFrameLength());
139
throw new RuntimeException();
140
}
141
if (ais.available() < 0) {
142
System.err.println("available should be >=0: " + ais.available());
143
throw new RuntimeException();
144
}
145
146
validateFormat(bits, rate, channel, format);
147
}
148
149
/**
150
* Tests that format contains the same data as were provided to the fake
151
* stream.
152
*/
153
private static void validateFormat(final byte bits, final int rate,
154
final int channel,
155
final AudioFormat format) {
156
157
if (Float.compare(format.getSampleRate(), rate) != 0) {
158
System.err.println("Expected: " + rate);
159
System.err.println("Actual: " + format.getSampleRate());
160
throw new RuntimeException();
161
}
162
if (format.getChannels() != channel) {
163
System.err.println("Expected: " + channel);
164
System.err.println("Actual: " + format.getChannels());
165
throw new RuntimeException();
166
}
167
int frameSize = ((bits + 7) / 8) * channel;
168
if (format.getFrameSize() != frameSize) {
169
System.out.println("Expected: " + frameSize);
170
System.err.println("Actual: " + format.getFrameSize());
171
throw new RuntimeException();
172
}
173
}
174
175
private static final int DOUBLE_MANTISSA_LENGTH = 52;
176
private static final int DOUBLE_EXPONENT_LENGTH = 11;
177
private static final long DOUBLE_SIGN_MASK = 0x8000000000000000L;
178
private static final long DOUBLE_EXPONENT_MASK = 0x7FF0000000000000L;
179
private static final long DOUBLE_MANTISSA_MASK = 0x000FFFFFFFFFFFFFL;
180
private static final int DOUBLE_EXPONENT_OFFSET = 1023;
181
182
private static final int EXTENDED_EXPONENT_OFFSET = 16383;
183
private static final int EXTENDED_MANTISSA_LENGTH = 63;
184
private static final int EXTENDED_EXPONENT_LENGTH = 15;
185
private static final long EXTENDED_INTEGER_MASK = 0x8000000000000000L;
186
187
/**
188
* Creates the custom header of the AIFF file. It is expected that all
189
* passed data are supported.
190
*/
191
private static byte[] createHeader(final byte bits, final int rate,
192
final int channel, final long frameLength) {
193
long doubleBits = Double.doubleToLongBits(rate);
194
195
long sign = (doubleBits & DOUBLE_SIGN_MASK)
196
>> (DOUBLE_EXPONENT_LENGTH + DOUBLE_MANTISSA_LENGTH);
197
long doubleExponent = (doubleBits & DOUBLE_EXPONENT_MASK)
198
>> DOUBLE_MANTISSA_LENGTH;
199
long doubleMantissa = doubleBits & DOUBLE_MANTISSA_MASK;
200
201
long extendedExponent = doubleExponent - DOUBLE_EXPONENT_OFFSET
202
+ EXTENDED_EXPONENT_OFFSET;
203
long extendedMantissa = doubleMantissa
204
<< (EXTENDED_MANTISSA_LENGTH - DOUBLE_MANTISSA_LENGTH);
205
long extendedSign = sign << EXTENDED_EXPONENT_LENGTH;
206
short extendedBits79To64 = (short) (extendedSign | extendedExponent);
207
long extendedBits63To0 = EXTENDED_INTEGER_MASK | extendedMantissa;
208
209
return new byte[]{
210
// AIFF_MAGIC
211
0x46, 0x4f, 0x52, 0x4d,
212
// fileLength (will use the number of frames for testing)
213
(byte) (frameLength >> 24), (byte) (frameLength >> 16),
214
(byte) (frameLength >> 8), (byte) frameLength,
215
// form aiff
216
0x41, 0x49, 0x46, 0x46,
217
// COMM_MAGIC
218
0x43, 0x4f, 0x4d, 0x4d,
219
// comm chunk size
220
0, 0, 0, 18,
221
// channels
222
(byte) (channel >> 8),(byte) channel,
223
// numSampleFrames
224
(byte) (frameLength >> 24), (byte) (frameLength >> 16),
225
(byte) (frameLength >> 8), (byte) (frameLength),
226
// samplesize
227
(byte) (bits >> 8),(byte) (bits),
228
// samplerate
229
(byte) (extendedBits79To64 >> 8),
230
(byte) extendedBits79To64,
231
(byte) (extendedBits63To0 >> 56),
232
(byte) (extendedBits63To0 >> 48),
233
(byte) (extendedBits63To0 >> 40),
234
(byte) (extendedBits63To0 >> 32), (byte) (extendedBits63To0 >> 24),
235
(byte) (extendedBits63To0 >> 16), (byte) (extendedBits63To0 >> 8),
236
(byte) extendedBits63To0,
237
// SND_MAGIC
238
0x53, 0x53, 0x4e, 0x44,
239
// data chunk size
240
0, 0, 0, 0,
241
// dataOffset
242
0, 0, 0, 0,
243
// blocksize
244
0, 0, 0, 0,
245
};
246
}
247
}
248
249