1 /*
2 * Copyright (c) 1999, 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. 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
30 import java.util.Vector;
31
32 import javax.sound.sampled.AudioFormat;
33 import javax.sound.sampled.AudioFormat.Encoding;
34 import javax.sound.sampled.AudioInputStream;
35 import javax.sound.sampled.AudioSystem;
36 import javax.sound.sampled.spi.FormatConversionProvider;
37
38 /**
39 * A-law encodes linear data, and decodes a-law data to linear data.
40 *
41 * @author Kara Kytle
42 */
43 public final class AlawCodec extends FormatConversionProvider {
44
45 /* Tables used for A-law decoding */
46
47 private static final byte[] ALAW_TABH = new byte[256];
48 private static final byte[] ALAW_TABL = new byte[256];
49
50 private static final short seg_end[] = {
51 0xFF, 0x1FF, 0x3FF, 0x7FF, 0xFFF, 0x1FFF, 0x3FFF, 0x7FFF
52 };
53
54 /**
55 * Initializes the decode tables.
56 */
57 static {
58 for (int i=0;i<256;i++) {
59 int input = i ^ 0x55;
60 int mantissa = (input & 0xf ) << 4;
61 int segment = (input & 0x70) >> 4;
62 int value = mantissa+8;
63
64 if(segment>=1)
65 value+=0x100;
66 if(segment>1)
67 value <<= (segment -1);
68
69 if( (input & 0x80)==0 )
70 value = -value;
74 }
75 }
76
77 @Override
78 public AudioFormat.Encoding[] getSourceEncodings() {
79 return new Encoding[]{Encoding.ALAW, Encoding.PCM_SIGNED};
80 }
81
82 @Override
83 public AudioFormat.Encoding[] getTargetEncodings() {
84 return getSourceEncodings();
85 }
86
87 @Override
88 public AudioFormat.Encoding[] getTargetEncodings(AudioFormat sourceFormat){
89
90 if( sourceFormat.getEncoding().equals( AudioFormat.Encoding.PCM_SIGNED )) {
91
92 if( sourceFormat.getSampleSizeInBits() == 16 ) {
93
94 AudioFormat.Encoding enc[] = new AudioFormat.Encoding[1];
95 enc[0] = AudioFormat.Encoding.ALAW;
96 return enc;
97
98 } else {
99 return new AudioFormat.Encoding[0];
100 }
101 } else if( sourceFormat.getEncoding().equals( AudioFormat.Encoding.ALAW ) ) {
102
103 if( sourceFormat.getSampleSizeInBits() == 8 ) {
104
105 AudioFormat.Encoding enc[] = new AudioFormat.Encoding[1];
106 enc[0] = AudioFormat.Encoding.PCM_SIGNED;
107 return enc;
108
109 } else {
110 return new AudioFormat.Encoding[0];
111 }
112
113 } else {
114 return new AudioFormat.Encoding[0];
115 }
116 }
117
118 @Override
119 public AudioFormat[] getTargetFormats(AudioFormat.Encoding targetEncoding, AudioFormat sourceFormat){
120 Objects.requireNonNull(sourceFormat);
121 if( (targetEncoding.equals( AudioFormat.Encoding.PCM_SIGNED ) && sourceFormat.getEncoding().equals( AudioFormat.Encoding.ALAW)) ||
122 (targetEncoding.equals( AudioFormat.Encoding.ALAW) && sourceFormat.getEncoding().equals( AudioFormat.Encoding.PCM_SIGNED)) ) {
123 return getOutputFormats( sourceFormat );
124 } else {
125 return new AudioFormat[0];
229 format = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED,
230 inputFormat.getSampleRate(), 16,
231 inputFormat.getChannels(),
232 inputFormat.getChannels() * 2,
233 inputFormat.getSampleRate(), true);
234 formats.addElement(format);
235 }
236
237 AudioFormat[] formatArray = new AudioFormat[formats.size()];
238 for (int i = 0; i < formatArray.length; i++) {
239 formatArray[i] = formats.elementAt(i);
240 }
241 return formatArray;
242 }
243
244
245 private final class AlawCodecStream extends AudioInputStream {
246
247 // tempBuffer required only for encoding (when encode is true)
248 private static final int tempBufferSize = 64;
249 private byte tempBuffer [] = null;
250
251 /**
252 * True to encode to a-law, false to decode to linear
253 */
254 boolean encode = false;
255
256 AudioFormat encodeFormat;
257 AudioFormat decodeFormat;
258
259 byte tabByte1[] = null;
260 byte tabByte2[] = null;
261 int highByte = 0;
262 int lowByte = 1;
263
264 AlawCodecStream(AudioInputStream stream, AudioFormat outputFormat) {
265
266 super(stream, outputFormat, -1);
267
268 AudioFormat inputFormat = stream.getFormat();
269
270 // throw an IllegalArgumentException if not ok
271 if ( ! (isConversionSupported(outputFormat, inputFormat)) ) {
272
273 throw new IllegalArgumentException("Unsupported conversion: " + inputFormat.toString() + " to " + outputFormat.toString());
274 }
275
276 //$$fb 2002-07-18: fix for 4714846: JavaSound ULAW (8-bit) encoder erroneously depends on endian-ness
277 boolean PCMIsBigEndian;
278
279 // determine whether we are encoding or decoding
280 if (AudioFormat.Encoding.ALAW.equals(inputFormat.getEncoding())) {
303 }
304
305 // set the AudioInputStream length in frames if we know it
306 if (stream instanceof AudioInputStream) {
307 frameLength = stream.getFrameLength();
308 }
309
310 // set framePos to zero
311 framePos = 0;
312 frameSize = inputFormat.getFrameSize();
313 if( frameSize==AudioSystem.NOT_SPECIFIED ) {
314 frameSize=1;
315 }
316 }
317
318
319 /*
320 * $$jb 2/23/99
321 * Used to determine segment number in aLaw encoding
322 */
323 private short search(short val, short table[], short size) {
324 for(short i = 0; i < size; i++) {
325 if (val <= table[i]) { return i; }
326 }
327 return size;
328 }
329
330 /**
331 * Note that this won't actually read anything; must read in
332 * two-byte units.
333 */
334 @Override
335 public int read() throws IOException {
336
337 byte[] b = new byte[1];
338 return read(b, 0, b.length);
339 }
340
341 @Override
342 public int read(byte[] b) throws IOException {
343
|
1 /*
2 * Copyright (c) 1999, 2018, 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
30 import java.util.Vector;
31
32 import javax.sound.sampled.AudioFormat;
33 import javax.sound.sampled.AudioFormat.Encoding;
34 import javax.sound.sampled.AudioInputStream;
35 import javax.sound.sampled.AudioSystem;
36 import javax.sound.sampled.spi.FormatConversionProvider;
37
38 /**
39 * A-law encodes linear data, and decodes a-law data to linear data.
40 *
41 * @author Kara Kytle
42 */
43 public final class AlawCodec extends FormatConversionProvider {
44
45 /* Tables used for A-law decoding */
46
47 private static final byte[] ALAW_TABH = new byte[256];
48 private static final byte[] ALAW_TABL = new byte[256];
49
50 private static final short[] seg_end = {
51 0xFF, 0x1FF, 0x3FF, 0x7FF, 0xFFF, 0x1FFF, 0x3FFF, 0x7FFF
52 };
53
54 /**
55 * Initializes the decode tables.
56 */
57 static {
58 for (int i=0;i<256;i++) {
59 int input = i ^ 0x55;
60 int mantissa = (input & 0xf ) << 4;
61 int segment = (input & 0x70) >> 4;
62 int value = mantissa+8;
63
64 if(segment>=1)
65 value+=0x100;
66 if(segment>1)
67 value <<= (segment -1);
68
69 if( (input & 0x80)==0 )
70 value = -value;
74 }
75 }
76
77 @Override
78 public AudioFormat.Encoding[] getSourceEncodings() {
79 return new Encoding[]{Encoding.ALAW, Encoding.PCM_SIGNED};
80 }
81
82 @Override
83 public AudioFormat.Encoding[] getTargetEncodings() {
84 return getSourceEncodings();
85 }
86
87 @Override
88 public AudioFormat.Encoding[] getTargetEncodings(AudioFormat sourceFormat){
89
90 if( sourceFormat.getEncoding().equals( AudioFormat.Encoding.PCM_SIGNED )) {
91
92 if( sourceFormat.getSampleSizeInBits() == 16 ) {
93
94 AudioFormat.Encoding[] enc = new AudioFormat.Encoding[1];
95 enc[0] = AudioFormat.Encoding.ALAW;
96 return enc;
97
98 } else {
99 return new AudioFormat.Encoding[0];
100 }
101 } else if( sourceFormat.getEncoding().equals( AudioFormat.Encoding.ALAW ) ) {
102
103 if( sourceFormat.getSampleSizeInBits() == 8 ) {
104
105 AudioFormat.Encoding[] enc = new AudioFormat.Encoding[1];
106 enc[0] = AudioFormat.Encoding.PCM_SIGNED;
107 return enc;
108
109 } else {
110 return new AudioFormat.Encoding[0];
111 }
112
113 } else {
114 return new AudioFormat.Encoding[0];
115 }
116 }
117
118 @Override
119 public AudioFormat[] getTargetFormats(AudioFormat.Encoding targetEncoding, AudioFormat sourceFormat){
120 Objects.requireNonNull(sourceFormat);
121 if( (targetEncoding.equals( AudioFormat.Encoding.PCM_SIGNED ) && sourceFormat.getEncoding().equals( AudioFormat.Encoding.ALAW)) ||
122 (targetEncoding.equals( AudioFormat.Encoding.ALAW) && sourceFormat.getEncoding().equals( AudioFormat.Encoding.PCM_SIGNED)) ) {
123 return getOutputFormats( sourceFormat );
124 } else {
125 return new AudioFormat[0];
229 format = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED,
230 inputFormat.getSampleRate(), 16,
231 inputFormat.getChannels(),
232 inputFormat.getChannels() * 2,
233 inputFormat.getSampleRate(), true);
234 formats.addElement(format);
235 }
236
237 AudioFormat[] formatArray = new AudioFormat[formats.size()];
238 for (int i = 0; i < formatArray.length; i++) {
239 formatArray[i] = formats.elementAt(i);
240 }
241 return formatArray;
242 }
243
244
245 private final class AlawCodecStream extends AudioInputStream {
246
247 // tempBuffer required only for encoding (when encode is true)
248 private static final int tempBufferSize = 64;
249 private byte[] tempBuffer = null;
250
251 /**
252 * True to encode to a-law, false to decode to linear
253 */
254 boolean encode = false;
255
256 AudioFormat encodeFormat;
257 AudioFormat decodeFormat;
258
259 byte[] tabByte1 = null;
260 byte[] tabByte2 = null;
261 int highByte = 0;
262 int lowByte = 1;
263
264 AlawCodecStream(AudioInputStream stream, AudioFormat outputFormat) {
265
266 super(stream, outputFormat, -1);
267
268 AudioFormat inputFormat = stream.getFormat();
269
270 // throw an IllegalArgumentException if not ok
271 if ( ! (isConversionSupported(outputFormat, inputFormat)) ) {
272
273 throw new IllegalArgumentException("Unsupported conversion: " + inputFormat.toString() + " to " + outputFormat.toString());
274 }
275
276 //$$fb 2002-07-18: fix for 4714846: JavaSound ULAW (8-bit) encoder erroneously depends on endian-ness
277 boolean PCMIsBigEndian;
278
279 // determine whether we are encoding or decoding
280 if (AudioFormat.Encoding.ALAW.equals(inputFormat.getEncoding())) {
303 }
304
305 // set the AudioInputStream length in frames if we know it
306 if (stream instanceof AudioInputStream) {
307 frameLength = stream.getFrameLength();
308 }
309
310 // set framePos to zero
311 framePos = 0;
312 frameSize = inputFormat.getFrameSize();
313 if( frameSize==AudioSystem.NOT_SPECIFIED ) {
314 frameSize=1;
315 }
316 }
317
318
319 /*
320 * $$jb 2/23/99
321 * Used to determine segment number in aLaw encoding
322 */
323 private short search(short val, short[] table, short size) {
324 for(short i = 0; i < size; i++) {
325 if (val <= table[i]) { return i; }
326 }
327 return size;
328 }
329
330 /**
331 * Note that this won't actually read anything; must read in
332 * two-byte units.
333 */
334 @Override
335 public int read() throws IOException {
336
337 byte[] b = new byte[1];
338 return read(b, 0, b.length);
339 }
340
341 @Override
342 public int read(byte[] b) throws IOException {
343
|