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.Objects;
30 import java.util.Vector;
31
32 import javax.sound.sampled.AudioFormat;
33 import javax.sound.sampled.AudioInputStream;
34 import javax.sound.sampled.AudioSystem;
35
36
37 /**
38 * U-law encodes linear data, and decodes u-law data to linear data.
39 *
40 * @author Kara Kytle
41 */
42 public final class UlawCodec extends SunCodec {
43
44 /* Tables used for U-law decoding */
45
46 private static final byte[] ULAW_TABH = new byte[256];
47 private static final byte[] ULAW_TABL = new byte[256];
48
49 private static final AudioFormat.Encoding[] ulawEncodings = {AudioFormat.Encoding.ULAW,
50 AudioFormat.Encoding.PCM_SIGNED};
51
52 private static final short seg_end [] = {0xFF, 0x1FF, 0x3FF,
53 0x7FF, 0xFFF, 0x1FFF, 0x3FFF, 0x7FFF};
54
55 /**
56 * Initializes the decode tables
57 */
58 static {
59 for (int i=0;i<256;i++) {
60 int ulaw = ~i;
61 int t;
62
63 ulaw &= 0xFF;
64 t = ((ulaw & 0xf)<<3) + 132;
65 t <<= ((ulaw & 0x70) >> 4);
66 t = ( (ulaw&0x80) != 0 ) ? (132-t) : (t-132);
67
68 ULAW_TABL[i] = (byte) (t&0xff);
69 ULAW_TABH[i] = (byte) ((t>>8) & 0xff);
70 }
71 }
72
73
74 /**
75 * Constructs a new ULAW codec object.
76 */
77 public UlawCodec() {
78 super(ulawEncodings, ulawEncodings);
79 }
80
81 /**
82 */
83 public AudioFormat.Encoding[] getTargetEncodings(AudioFormat sourceFormat){
84 if( AudioFormat.Encoding.PCM_SIGNED.equals(sourceFormat.getEncoding()) ) {
85 if( sourceFormat.getSampleSizeInBits() == 16 ) {
86 AudioFormat.Encoding enc[] = new AudioFormat.Encoding[1];
87 enc[0] = AudioFormat.Encoding.ULAW;
88 return enc;
89 } else {
90 return new AudioFormat.Encoding[0];
91 }
92 } else if (AudioFormat.Encoding.ULAW.equals(sourceFormat.getEncoding())) {
93 if (sourceFormat.getSampleSizeInBits() == 8) {
94 AudioFormat.Encoding enc[] = new AudioFormat.Encoding[1];
95 enc[0] = AudioFormat.Encoding.PCM_SIGNED;
96 return enc;
97 } else {
98 return new AudioFormat.Encoding[0];
99 }
100 } else {
101 return new AudioFormat.Encoding[0];
102 }
103 }
104
105
106 /**
107 */
108 public AudioFormat[] getTargetFormats(AudioFormat.Encoding targetEncoding, AudioFormat sourceFormat){
109 Objects.requireNonNull(targetEncoding);
110 Objects.requireNonNull(sourceFormat);
111 if( (AudioFormat.Encoding.PCM_SIGNED.equals(targetEncoding)
112 && AudioFormat.Encoding.ULAW.equals(sourceFormat.getEncoding()))
113 ||
114 (AudioFormat.Encoding.ULAW.equals(targetEncoding)
115 && AudioFormat.Encoding.PCM_SIGNED.equals(sourceFormat.getEncoding()))) {
116 return getOutputFormats(sourceFormat);
117 } else {
118 return new AudioFormat[0];
119 }
120 }
121
122 /**
123 */
124 public AudioInputStream getAudioInputStream(AudioFormat.Encoding targetEncoding, AudioInputStream sourceStream){
125 AudioFormat sourceFormat = sourceStream.getFormat();
126 AudioFormat.Encoding sourceEncoding = sourceFormat.getEncoding();
127
128 if (!isConversionSupported(targetEncoding,sourceStream.getFormat())) {
129 throw new IllegalArgumentException("Unsupported conversion: " + sourceStream.getFormat().toString() + " to " + targetEncoding.toString());
130 }
131 if (sourceEncoding.equals(targetEncoding)) {
132 return sourceStream;
133 }
134 AudioFormat targetFormat = null;
135 if (AudioFormat.Encoding.ULAW.equals(sourceEncoding) &&
136 AudioFormat.Encoding.PCM_SIGNED.equals(targetEncoding) ) {
137 targetFormat = new AudioFormat( targetEncoding,
138 sourceFormat.getSampleRate(),
139 16,
140 sourceFormat.getChannels(),
141 2*sourceFormat.getChannels(),
142 sourceFormat.getSampleRate(),
143 sourceFormat.isBigEndian());
144 } else if (AudioFormat.Encoding.PCM_SIGNED.equals(sourceEncoding) &&
145 AudioFormat.Encoding.ULAW.equals(targetEncoding)) {
146 targetFormat = new AudioFormat( targetEncoding,
147 sourceFormat.getSampleRate(),
148 8,
149 sourceFormat.getChannels(),
150 sourceFormat.getChannels(),
151 sourceFormat.getSampleRate(),
152 false);
153 } else {
154 throw new IllegalArgumentException("Unsupported conversion: " + sourceStream.getFormat().toString() + " to " + targetEncoding.toString());
155 }
156
157 return getConvertedStream(targetFormat, sourceStream);
158 }
159
160 /**
161 * use old code...
162 */
163 public AudioInputStream getAudioInputStream(AudioFormat targetFormat, AudioInputStream sourceStream){
164 if (!isConversionSupported(targetFormat, sourceStream.getFormat()))
165 throw new IllegalArgumentException("Unsupported conversion: "
166 + sourceStream.getFormat().toString() + " to "
167 + targetFormat.toString());
168 return getConvertedStream(targetFormat, sourceStream);
169 }
170
171
172 // OLD CODE
173
174 /**
175 * Opens the codec with the specified parameters.
176 * @param stream stream from which data to be processed should be read
177 * @param outputFormat desired data format of the stream after processing
178 * @return stream from which processed data may be read
179 * @throws IllegalArgumentException if the format combination supplied is
180 * not supported.
181 */
182 /* public AudioInputStream getConvertedStream(AudioFormat outputFormat, AudioInputStream stream) { */
183 private AudioInputStream getConvertedStream(AudioFormat outputFormat, AudioInputStream stream) {
184 AudioInputStream cs = null;
185
186 AudioFormat inputFormat = stream.getFormat();
187
188 if( inputFormat.matches(outputFormat) ) {
189 cs = stream;
190 } else {
191 cs = (AudioInputStream) (new UlawCodecStream(stream, outputFormat));
192 }
193 return cs;
194 }
195
196 /**
197 * Obtains the set of output formats supported by the codec
198 * given a particular input format.
199 * If no output formats are supported for this input format,
200 * returns an array of length 0.
201 * @return array of supported output formats.
202 */
203 /* public AudioFormat[] getOutputFormats(AudioFormat inputFormat) { */
204 private AudioFormat[] getOutputFormats(AudioFormat inputFormat) {
205
206 Vector<AudioFormat> formats = new Vector<>();
207 AudioFormat format;
208
209 if ((inputFormat.getSampleSizeInBits() == 16)
210 && AudioFormat.Encoding.PCM_SIGNED.equals(inputFormat.getEncoding())) {
211 format = new AudioFormat(AudioFormat.Encoding.ULAW,
212 inputFormat.getSampleRate(),
213 8,
214 inputFormat.getChannels(),
215 inputFormat.getChannels(),
216 inputFormat.getSampleRate(),
217 false );
218 formats.addElement(format);
219 }
220 if (inputFormat.getSampleSizeInBits() == 8
221 && AudioFormat.Encoding.ULAW.equals(inputFormat.getEncoding())) {
222 format = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED,
223 inputFormat.getSampleRate(), 16,
224 inputFormat.getChannels(),
225 inputFormat.getChannels() * 2,
226 inputFormat.getSampleRate(), false);
227 formats.addElement(format);
228
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 UlawCodecStream extends AudioInputStream {
246
247 private static final int tempBufferSize = 64;
248 private byte tempBuffer [] = null;
249
250 /**
251 * True to encode to u-law, false to decode to linear
252 */
253 boolean encode = false;
254
255 AudioFormat encodeFormat;
256 AudioFormat decodeFormat;
257
258 byte tabByte1[] = null;
259 byte tabByte2[] = null;
260 int highByte = 0;
261 int lowByte = 1;
262
263 UlawCodecStream(AudioInputStream stream, AudioFormat outputFormat) {
264 super(stream, outputFormat, AudioSystem.NOT_SPECIFIED);
265
266 AudioFormat inputFormat = stream.getFormat();
267
268 // throw an IllegalArgumentException if not ok
269 if (!(isConversionSupported(outputFormat, inputFormat))) {
270 throw new IllegalArgumentException("Unsupported conversion: " + inputFormat.toString() + " to " + outputFormat.toString());
271 }
295 lowByte = 1;
296 } else {
297 tabByte1 = ULAW_TABL;
298 tabByte2 = ULAW_TABH;
299 highByte = 1;
300 lowByte = 0;
301 }
302
303 // set the AudioInputStream length in frames if we know it
304 if (stream instanceof AudioInputStream) {
305 frameLength = stream.getFrameLength();
306 }
307 // set framePos to zero
308 framePos = 0;
309 frameSize = inputFormat.getFrameSize();
310 if (frameSize == AudioSystem.NOT_SPECIFIED) {
311 frameSize = 1;
312 }
313 }
314
315
316 /*
317 * $$jb 2/23/99
318 * Used to determine segment number in uLaw encoding
319 */
320 private short search(short val, short table[], short size) {
321 for(short i = 0; i < size; i++) {
322 if (val <= table[i]) { return i; }
323 }
324 return size;
325 }
326
327 /**
328 * Note that this won't actually read anything; must read in
329 * two-byte units.
330 */
331 public int read() throws IOException {
332 byte[] b = new byte[1];
333 if (read(b, 0, b.length) == 1) {
334 return b[1] & 0xFF;
335 }
336 return -1;
337 }
338
339 public int read(byte[] b) throws IOException {
340 return read(b, 0, b.length);
341 }
342
343 public int read(byte[] b, int off, int len) throws IOException {
344 // don't read fractional frames
345 if( len%frameSize != 0 ) {
346 len -= (len%frameSize);
347 }
348 if (encode) {
349 short BIAS = 0x84;
350 short mask;
351 short seg;
352 int i;
353
354 short sample;
355 byte enc;
356
357 int readCount = 0;
358 int currentPos = off;
359 int readLeft = len*2;
360 int readLen = ( (readLeft>tempBufferSize) ? tempBufferSize : readLeft );
361
362 while ((readCount = super.read(tempBuffer,0,readLen))>0) {
|
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.Objects;
30 import java.util.Vector;
31
32 import javax.sound.sampled.AudioFormat;
33 import javax.sound.sampled.AudioInputStream;
34 import javax.sound.sampled.AudioSystem;
35
36 /**
37 * U-law encodes linear data, and decodes u-law data to linear data.
38 *
39 * @author Kara Kytle
40 */
41 public final class UlawCodec extends SunCodec {
42
43 /* Tables used for U-law decoding */
44
45 private static final byte[] ULAW_TABH = new byte[256];
46 private static final byte[] ULAW_TABL = new byte[256];
47
48 private static final AudioFormat.Encoding[] ulawEncodings = {AudioFormat.Encoding.ULAW,
49 AudioFormat.Encoding.PCM_SIGNED};
50
51 private static final short seg_end [] = {0xFF, 0x1FF, 0x3FF,
52 0x7FF, 0xFFF, 0x1FFF, 0x3FFF, 0x7FFF};
53
54 /**
55 * Initializes the decode tables.
56 */
57 static {
58 for (int i=0;i<256;i++) {
59 int ulaw = ~i;
60 int t;
61
62 ulaw &= 0xFF;
63 t = ((ulaw & 0xf)<<3) + 132;
64 t <<= ((ulaw & 0x70) >> 4);
65 t = ( (ulaw&0x80) != 0 ) ? (132-t) : (t-132);
66
67 ULAW_TABL[i] = (byte) (t&0xff);
68 ULAW_TABH[i] = (byte) ((t>>8) & 0xff);
69 }
70 }
71
72 /**
73 * Constructs a new ULAW codec object.
74 */
75 public UlawCodec() {
76 super(ulawEncodings, ulawEncodings);
77 }
78
79 @Override
80 public AudioFormat.Encoding[] getTargetEncodings(AudioFormat sourceFormat){
81 if( AudioFormat.Encoding.PCM_SIGNED.equals(sourceFormat.getEncoding()) ) {
82 if( sourceFormat.getSampleSizeInBits() == 16 ) {
83 AudioFormat.Encoding enc[] = new AudioFormat.Encoding[1];
84 enc[0] = AudioFormat.Encoding.ULAW;
85 return enc;
86 } else {
87 return new AudioFormat.Encoding[0];
88 }
89 } else if (AudioFormat.Encoding.ULAW.equals(sourceFormat.getEncoding())) {
90 if (sourceFormat.getSampleSizeInBits() == 8) {
91 AudioFormat.Encoding enc[] = new AudioFormat.Encoding[1];
92 enc[0] = AudioFormat.Encoding.PCM_SIGNED;
93 return enc;
94 } else {
95 return new AudioFormat.Encoding[0];
96 }
97 } else {
98 return new AudioFormat.Encoding[0];
99 }
100 }
101
102 @Override
103 public AudioFormat[] getTargetFormats(AudioFormat.Encoding targetEncoding, AudioFormat sourceFormat){
104 Objects.requireNonNull(targetEncoding);
105 Objects.requireNonNull(sourceFormat);
106 if( (AudioFormat.Encoding.PCM_SIGNED.equals(targetEncoding)
107 && AudioFormat.Encoding.ULAW.equals(sourceFormat.getEncoding()))
108 ||
109 (AudioFormat.Encoding.ULAW.equals(targetEncoding)
110 && AudioFormat.Encoding.PCM_SIGNED.equals(sourceFormat.getEncoding()))) {
111 return getOutputFormats(sourceFormat);
112 } else {
113 return new AudioFormat[0];
114 }
115 }
116
117 @Override
118 public AudioInputStream getAudioInputStream(AudioFormat.Encoding targetEncoding, AudioInputStream sourceStream){
119 AudioFormat sourceFormat = sourceStream.getFormat();
120 AudioFormat.Encoding sourceEncoding = sourceFormat.getEncoding();
121
122 if (!isConversionSupported(targetEncoding,sourceStream.getFormat())) {
123 throw new IllegalArgumentException("Unsupported conversion: " + sourceStream.getFormat().toString() + " to " + targetEncoding.toString());
124 }
125 if (sourceEncoding.equals(targetEncoding)) {
126 return sourceStream;
127 }
128 AudioFormat targetFormat = null;
129 if (AudioFormat.Encoding.ULAW.equals(sourceEncoding) &&
130 AudioFormat.Encoding.PCM_SIGNED.equals(targetEncoding) ) {
131 targetFormat = new AudioFormat( targetEncoding,
132 sourceFormat.getSampleRate(),
133 16,
134 sourceFormat.getChannels(),
135 2*sourceFormat.getChannels(),
136 sourceFormat.getSampleRate(),
137 sourceFormat.isBigEndian());
138 } else if (AudioFormat.Encoding.PCM_SIGNED.equals(sourceEncoding) &&
139 AudioFormat.Encoding.ULAW.equals(targetEncoding)) {
140 targetFormat = new AudioFormat( targetEncoding,
141 sourceFormat.getSampleRate(),
142 8,
143 sourceFormat.getChannels(),
144 sourceFormat.getChannels(),
145 sourceFormat.getSampleRate(),
146 false);
147 } else {
148 throw new IllegalArgumentException("Unsupported conversion: " + sourceStream.getFormat().toString() + " to " + targetEncoding.toString());
149 }
150
151 return getConvertedStream(targetFormat, sourceStream);
152 }
153
154 @Override
155 public AudioInputStream getAudioInputStream(AudioFormat targetFormat, AudioInputStream sourceStream){
156 if (!isConversionSupported(targetFormat, sourceStream.getFormat()))
157 throw new IllegalArgumentException("Unsupported conversion: "
158 + sourceStream.getFormat().toString() + " to "
159 + targetFormat.toString());
160 return getConvertedStream(targetFormat, sourceStream);
161 }
162
163 /**
164 * Opens the codec with the specified parameters.
165 * @param stream stream from which data to be processed should be read
166 * @param outputFormat desired data format of the stream after processing
167 * @return stream from which processed data may be read
168 * @throws IllegalArgumentException if the format combination supplied is
169 * not supported.
170 */
171 private AudioInputStream getConvertedStream(AudioFormat outputFormat, AudioInputStream stream) {
172 AudioInputStream cs = null;
173
174 AudioFormat inputFormat = stream.getFormat();
175
176 if( inputFormat.matches(outputFormat) ) {
177 cs = stream;
178 } else {
179 cs = new UlawCodecStream(stream, outputFormat);
180 }
181 return cs;
182 }
183
184 /**
185 * Obtains the set of output formats supported by the codec
186 * given a particular input format.
187 * If no output formats are supported for this input format,
188 * returns an array of length 0.
189 * @return array of supported output formats.
190 */
191 private AudioFormat[] getOutputFormats(AudioFormat inputFormat) {
192
193 Vector<AudioFormat> formats = new Vector<>();
194 AudioFormat format;
195
196 if ((inputFormat.getSampleSizeInBits() == 16)
197 && AudioFormat.Encoding.PCM_SIGNED.equals(inputFormat.getEncoding())) {
198 format = new AudioFormat(AudioFormat.Encoding.ULAW,
199 inputFormat.getSampleRate(),
200 8,
201 inputFormat.getChannels(),
202 inputFormat.getChannels(),
203 inputFormat.getSampleRate(),
204 false );
205 formats.addElement(format);
206 }
207 if (inputFormat.getSampleSizeInBits() == 8
208 && AudioFormat.Encoding.ULAW.equals(inputFormat.getEncoding())) {
209 format = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED,
210 inputFormat.getSampleRate(), 16,
211 inputFormat.getChannels(),
212 inputFormat.getChannels() * 2,
213 inputFormat.getSampleRate(), false);
214 formats.addElement(format);
215
216 format = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED,
217 inputFormat.getSampleRate(), 16,
218 inputFormat.getChannels(),
219 inputFormat.getChannels() * 2,
220 inputFormat.getSampleRate(), true);
221 formats.addElement(format);
222 }
223
224 AudioFormat[] formatArray = new AudioFormat[formats.size()];
225 for (int i = 0; i < formatArray.length; i++) {
226 formatArray[i] = formats.elementAt(i);
227 }
228 return formatArray;
229 }
230
231 private final class UlawCodecStream extends AudioInputStream {
232
233 private static final int tempBufferSize = 64;
234 private byte tempBuffer [] = null;
235
236 /**
237 * True to encode to u-law, false to decode to linear.
238 */
239 boolean encode = false;
240
241 AudioFormat encodeFormat;
242 AudioFormat decodeFormat;
243
244 byte tabByte1[] = null;
245 byte tabByte2[] = null;
246 int highByte = 0;
247 int lowByte = 1;
248
249 UlawCodecStream(AudioInputStream stream, AudioFormat outputFormat) {
250 super(stream, outputFormat, AudioSystem.NOT_SPECIFIED);
251
252 AudioFormat inputFormat = stream.getFormat();
253
254 // throw an IllegalArgumentException if not ok
255 if (!(isConversionSupported(outputFormat, inputFormat))) {
256 throw new IllegalArgumentException("Unsupported conversion: " + inputFormat.toString() + " to " + outputFormat.toString());
257 }
281 lowByte = 1;
282 } else {
283 tabByte1 = ULAW_TABL;
284 tabByte2 = ULAW_TABH;
285 highByte = 1;
286 lowByte = 0;
287 }
288
289 // set the AudioInputStream length in frames if we know it
290 if (stream instanceof AudioInputStream) {
291 frameLength = stream.getFrameLength();
292 }
293 // set framePos to zero
294 framePos = 0;
295 frameSize = inputFormat.getFrameSize();
296 if (frameSize == AudioSystem.NOT_SPECIFIED) {
297 frameSize = 1;
298 }
299 }
300
301 /*
302 * $$jb 2/23/99
303 * Used to determine segment number in uLaw encoding
304 */
305 private short search(short val, short table[], short size) {
306 for(short i = 0; i < size; i++) {
307 if (val <= table[i]) { return i; }
308 }
309 return size;
310 }
311
312 /**
313 * Note that this won't actually read anything; must read in
314 * two-byte units.
315 */
316 @Override
317 public int read() throws IOException {
318 byte[] b = new byte[1];
319 if (read(b, 0, b.length) == 1) {
320 return b[1] & 0xFF;
321 }
322 return -1;
323 }
324
325 @Override
326 public int read(byte[] b) throws IOException {
327 return read(b, 0, b.length);
328 }
329
330 @Override
331 public int read(byte[] b, int off, int len) throws IOException {
332 // don't read fractional frames
333 if( len%frameSize != 0 ) {
334 len -= (len%frameSize);
335 }
336 if (encode) {
337 short BIAS = 0x84;
338 short mask;
339 short seg;
340 int i;
341
342 short sample;
343 byte enc;
344
345 int readCount = 0;
346 int currentPos = off;
347 int readLeft = len*2;
348 int readLen = ( (readLeft>tempBufferSize) ? tempBufferSize : readLeft );
349
350 while ((readCount = super.read(tempBuffer,0,readLen))>0) {
|