Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/com/sun/media/sound/AlawCodec.java
38924 views
1
/*
2
* Copyright (c) 1999, 2013, 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. Oracle designates this
8
* particular file as subject to the "Classpath" exception as provided
9
* by Oracle in the LICENSE file that accompanied this code.
10
*
11
* This code is distributed in the hope that it will be useful, but WITHOUT
12
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14
* version 2 for more details (a copy is included in the LICENSE file that
15
* accompanied this code).
16
*
17
* You should have received a copy of the GNU General Public License version
18
* 2 along with this work; if not, write to the Free Software Foundation,
19
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20
*
21
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22
* or visit www.oracle.com if you need additional information or have any
23
* questions.
24
*/
25
26
package com.sun.media.sound;
27
28
import java.io.IOException;
29
import java.util.Vector;
30
31
import javax.sound.sampled.AudioFormat;
32
import javax.sound.sampled.AudioInputStream;
33
import javax.sound.sampled.AudioSystem;
34
35
36
/**
37
* A-law encodes linear data, and decodes a-law data to linear data.
38
*
39
* @author Kara Kytle
40
*/
41
public final class AlawCodec extends SunCodec {
42
43
/* Tables used for A-law decoding */
44
45
private static final byte[] ALAW_TABH = new byte[256];
46
private static final byte[] ALAW_TABL = new byte[256];
47
48
private static final AudioFormat.Encoding[] alawEncodings = { AudioFormat.Encoding.ALAW, AudioFormat.Encoding.PCM_SIGNED };
49
50
private static final short seg_end [] = {0xFF, 0x1FF, 0x3FF,
51
0x7FF, 0xFFF, 0x1FFF, 0x3FFF, 0x7FFF};
52
53
/**
54
* Initializes the decode tables
55
*/
56
static {
57
for (int i=0;i<256;i++) {
58
int input = i ^ 0x55;
59
int mantissa = (input & 0xf ) << 4;
60
int segment = (input & 0x70) >> 4;
61
int value = mantissa+8;
62
63
if(segment>=1)
64
value+=0x100;
65
if(segment>1)
66
value <<= (segment -1);
67
68
if( (input & 0x80)==0 )
69
value = -value;
70
71
ALAW_TABL[i] = (byte)value;
72
ALAW_TABH[i] = (byte)(value>>8);
73
}
74
}
75
76
77
/**
78
* Constructs a new ALAW codec object.
79
*/
80
public AlawCodec() {
81
82
super(alawEncodings, alawEncodings);
83
}
84
85
// NEW CODE
86
87
/**
88
*/
89
public AudioFormat.Encoding[] getTargetEncodings(AudioFormat sourceFormat){
90
91
if( sourceFormat.getEncoding().equals( AudioFormat.Encoding.PCM_SIGNED )) {
92
93
if( sourceFormat.getSampleSizeInBits() == 16 ) {
94
95
AudioFormat.Encoding enc[] = new AudioFormat.Encoding[1];
96
enc[0] = AudioFormat.Encoding.ALAW;
97
return enc;
98
99
} else {
100
return new AudioFormat.Encoding[0];
101
}
102
} else if( sourceFormat.getEncoding().equals( AudioFormat.Encoding.ALAW ) ) {
103
104
if( sourceFormat.getSampleSizeInBits() == 8 ) {
105
106
AudioFormat.Encoding enc[] = new AudioFormat.Encoding[1];
107
enc[0] = AudioFormat.Encoding.PCM_SIGNED;
108
return enc;
109
110
} else {
111
return new AudioFormat.Encoding[0];
112
}
113
114
} else {
115
return new AudioFormat.Encoding[0];
116
}
117
}
118
119
/**
120
*/
121
public AudioFormat[] getTargetFormats(AudioFormat.Encoding targetEncoding, AudioFormat sourceFormat){
122
if( (targetEncoding.equals( AudioFormat.Encoding.PCM_SIGNED ) && sourceFormat.getEncoding().equals( AudioFormat.Encoding.ALAW)) ||
123
(targetEncoding.equals( AudioFormat.Encoding.ALAW) && sourceFormat.getEncoding().equals( AudioFormat.Encoding.PCM_SIGNED)) ) {
124
return getOutputFormats( sourceFormat );
125
} else {
126
return new AudioFormat[0];
127
}
128
}
129
130
/**
131
*/
132
public AudioInputStream getAudioInputStream(AudioFormat.Encoding targetEncoding, AudioInputStream sourceStream){
133
AudioFormat sourceFormat = sourceStream.getFormat();
134
AudioFormat.Encoding sourceEncoding = sourceFormat.getEncoding();
135
136
if( sourceEncoding.equals( targetEncoding ) ) {
137
return sourceStream;
138
} else {
139
AudioFormat targetFormat = null;
140
if( !isConversionSupported(targetEncoding,sourceStream.getFormat()) ) {
141
throw new IllegalArgumentException("Unsupported conversion: " + sourceStream.getFormat().toString() + " to " + targetEncoding.toString());
142
}
143
if( sourceEncoding.equals( AudioFormat.Encoding.ALAW ) &&
144
targetEncoding.equals( AudioFormat.Encoding.PCM_SIGNED ) ) {
145
146
targetFormat = new AudioFormat( targetEncoding,
147
sourceFormat.getSampleRate(),
148
16,
149
sourceFormat.getChannels(),
150
2*sourceFormat.getChannels(),
151
sourceFormat.getSampleRate(),
152
sourceFormat.isBigEndian());
153
154
} else if( sourceEncoding.equals( AudioFormat.Encoding.PCM_SIGNED ) &&
155
targetEncoding.equals( AudioFormat.Encoding.ALAW ) ) {
156
157
targetFormat = new AudioFormat( targetEncoding,
158
sourceFormat.getSampleRate(),
159
8,
160
sourceFormat.getChannels(),
161
sourceFormat.getChannels(),
162
sourceFormat.getSampleRate(),
163
false);
164
} else {
165
throw new IllegalArgumentException("Unsupported conversion: " + sourceStream.getFormat().toString() + " to " + targetEncoding.toString());
166
}
167
return getAudioInputStream( targetFormat, sourceStream );
168
}
169
}
170
171
/**
172
* use old code...
173
*/
174
public AudioInputStream getAudioInputStream(AudioFormat targetFormat, AudioInputStream sourceStream){
175
return getConvertedStream( targetFormat, sourceStream );
176
}
177
178
179
// OLD CODE
180
181
182
/**
183
* Opens the codec with the specified parameters.
184
* @param stream stream from which data to be processed should be read
185
* @param outputFormat desired data format of the stream after processing
186
* @return stream from which processed data may be read
187
* @throws IllegalArgumentException if the format combination supplied is
188
* not supported.
189
*/
190
/* public AudioInputStream getConvertedStream(AudioFormat outputFormat, AudioInputStream stream) { */
191
private AudioInputStream getConvertedStream(AudioFormat outputFormat, AudioInputStream stream) {
192
193
AudioInputStream cs = null;
194
AudioFormat inputFormat = stream.getFormat();
195
196
if( inputFormat.matches(outputFormat) ) {
197
cs = stream;
198
} else {
199
cs = (AudioInputStream) (new AlawCodecStream(stream, outputFormat));
200
}
201
202
return cs;
203
}
204
205
/**
206
* Obtains the set of output formats supported by the codec
207
* given a particular input format.
208
* If no output formats are supported for this input format,
209
* returns an array of length 0.
210
* @return array of supported output formats.
211
*/
212
/* public AudioFormat[] getOutputFormats(AudioFormat inputFormat) { */
213
private AudioFormat[] getOutputFormats(AudioFormat inputFormat) {
214
215
216
Vector formats = new Vector();
217
AudioFormat format;
218
219
if ( AudioFormat.Encoding.PCM_SIGNED.equals(inputFormat.getEncoding())) {
220
format = new AudioFormat(AudioFormat.Encoding.ALAW,
221
inputFormat.getSampleRate(),
222
8,
223
inputFormat.getChannels(),
224
inputFormat.getChannels(),
225
inputFormat.getSampleRate(),
226
false );
227
formats.addElement(format);
228
}
229
230
if (AudioFormat.Encoding.ALAW.equals(inputFormat.getEncoding())) {
231
format = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED,
232
inputFormat.getSampleRate(),
233
16,
234
inputFormat.getChannels(),
235
inputFormat.getChannels()*2,
236
inputFormat.getSampleRate(),
237
false );
238
formats.addElement(format);
239
format = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED,
240
inputFormat.getSampleRate(),
241
16,
242
inputFormat.getChannels(),
243
inputFormat.getChannels()*2,
244
inputFormat.getSampleRate(),
245
true );
246
formats.addElement(format);
247
}
248
249
AudioFormat[] formatArray = new AudioFormat[formats.size()];
250
for (int i = 0; i < formatArray.length; i++) {
251
formatArray[i] = (AudioFormat)(formats.elementAt(i));
252
}
253
return formatArray;
254
}
255
256
257
final class AlawCodecStream extends AudioInputStream {
258
259
// tempBuffer required only for encoding (when encode is true)
260
private static final int tempBufferSize = 64;
261
private byte tempBuffer [] = null;
262
263
/**
264
* True to encode to a-law, false to decode to linear
265
*/
266
boolean encode = false;
267
268
AudioFormat encodeFormat;
269
AudioFormat decodeFormat;
270
271
byte tabByte1[] = null;
272
byte tabByte2[] = null;
273
int highByte = 0;
274
int lowByte = 1;
275
276
AlawCodecStream(AudioInputStream stream, AudioFormat outputFormat) {
277
278
super(stream, outputFormat, -1);
279
280
AudioFormat inputFormat = stream.getFormat();
281
282
// throw an IllegalArgumentException if not ok
283
if ( ! (isConversionSupported(outputFormat, inputFormat)) ) {
284
285
throw new IllegalArgumentException("Unsupported conversion: " + inputFormat.toString() + " to " + outputFormat.toString());
286
}
287
288
//$$fb 2002-07-18: fix for 4714846: JavaSound ULAW (8-bit) encoder erroneously depends on endian-ness
289
boolean PCMIsBigEndian;
290
291
// determine whether we are encoding or decoding
292
if (AudioFormat.Encoding.ALAW.equals(inputFormat.getEncoding())) {
293
encode = false;
294
encodeFormat = inputFormat;
295
decodeFormat = outputFormat;
296
PCMIsBigEndian = outputFormat.isBigEndian();
297
} else {
298
encode = true;
299
encodeFormat = outputFormat;
300
decodeFormat = inputFormat;
301
PCMIsBigEndian = inputFormat.isBigEndian();
302
tempBuffer = new byte[tempBufferSize];
303
}
304
305
if (PCMIsBigEndian) {
306
tabByte1 = ALAW_TABH;
307
tabByte2 = ALAW_TABL;
308
highByte = 0;
309
lowByte = 1;
310
} else {
311
tabByte1 = ALAW_TABL;
312
tabByte2 = ALAW_TABH;
313
highByte = 1;
314
lowByte = 0;
315
}
316
317
// set the AudioInputStream length in frames if we know it
318
if (stream instanceof AudioInputStream) {
319
frameLength = ((AudioInputStream)stream).getFrameLength();
320
}
321
322
// set framePos to zero
323
framePos = 0;
324
frameSize = inputFormat.getFrameSize();
325
if( frameSize==AudioSystem.NOT_SPECIFIED ) {
326
frameSize=1;
327
}
328
}
329
330
331
/*
332
* $$jb 2/23/99
333
* Used to determine segment number in aLaw encoding
334
*/
335
private short search(short val, short table[], short size) {
336
for(short i = 0; i < size; i++) {
337
if (val <= table[i]) { return i; }
338
}
339
return size;
340
}
341
342
/**
343
* Note that this won't actually read anything; must read in
344
* two-byte units.
345
*/
346
public int read() throws IOException {
347
348
byte[] b = new byte[1];
349
return (int)read(b, 0, b.length);
350
}
351
352
353
public int read(byte[] b) throws IOException {
354
355
return read(b, 0, b.length);
356
}
357
358
public int read(byte[] b, int off, int len) throws IOException {
359
360
// don't read fractional frames
361
if( len%frameSize != 0 ) {
362
len -= (len%frameSize);
363
}
364
365
if (encode) {
366
367
short QUANT_MASK = 0xF;
368
short SEG_SHIFT = 4;
369
short mask;
370
short seg;
371
int adj;
372
int i;
373
374
short sample;
375
byte enc;
376
377
int readCount = 0;
378
int currentPos = off;
379
int readLeft = len*2;
380
int readLen = ( (readLeft>tempBufferSize) ? tempBufferSize : readLeft );
381
382
while ((readCount = super.read(tempBuffer,0,readLen))>0) {
383
384
for (i = 0; i < readCount; i+=2) {
385
386
/* Get the sample from the tempBuffer */
387
sample = (short)(( (tempBuffer[i + highByte]) << 8) & 0xFF00);
388
sample |= (short)( (tempBuffer[i + lowByte]) & 0xFF);
389
390
if(sample >= 0) {
391
mask = 0xD5;
392
} else {
393
mask = 0x55;
394
sample = (short)(-sample - 8);
395
}
396
/* Convert the scaled magnitude to segment number. */
397
seg = search(sample, seg_end, (short) 8);
398
/*
399
* Combine the sign, segment, quantization bits
400
*/
401
if (seg >= 8) { /* out of range, return maximum value. */
402
enc = (byte) (0x7F ^ mask);
403
} else {
404
enc = (byte) (seg << SEG_SHIFT);
405
if(seg < 2) {
406
enc |= (byte) ( (sample >> 4) & QUANT_MASK);
407
} else {
408
enc |= (byte) ( (sample >> (seg + 3)) & QUANT_MASK );
409
}
410
enc ^= mask;
411
}
412
/* Now put the encoded sample where it belongs */
413
b[currentPos] = enc;
414
currentPos++;
415
}
416
/* And update pointers and counters for next iteration */
417
readLeft -= readCount;
418
readLen = ( (readLeft>tempBufferSize) ? tempBufferSize : readLeft );
419
}
420
421
if( currentPos==off && readCount<0 ) { // EOF or error
422
return readCount;
423
}
424
425
return (currentPos - off); /* Number of bytes written to new buffer */
426
427
} else {
428
429
int i;
430
int readLen = len/2;
431
int readOffset = off + len/2;
432
int readCount = super.read(b, readOffset, readLen);
433
434
for (i = off; i < (off + (readCount*2)); i+=2) {
435
b[i] = (byte)tabByte1[b[readOffset] & 0xFF];
436
b[i+1] = (byte)tabByte2[b[readOffset] & 0xFF];
437
readOffset++;
438
}
439
440
if( readCount<0 ) { // EOF or error
441
return readCount;
442
}
443
444
return (i - off);
445
}
446
}
447
} // end class AlawCodecStream
448
} // end class ALAW
449
450