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 * Converts among signed/unsigned and little/big endianness of sampled.
38 *
39 * @author Jan Borgersen
40 */
41 public final class PCMtoPCMCodec extends SunCodec {
42
43
44 private static final AudioFormat.Encoding[] inputEncodings = {
45 AudioFormat.Encoding.PCM_SIGNED,
46 AudioFormat.Encoding.PCM_UNSIGNED,
47 };
48
49 private static final AudioFormat.Encoding[] outputEncodings = {
50 AudioFormat.Encoding.PCM_SIGNED,
51 AudioFormat.Encoding.PCM_UNSIGNED,
52 };
53
54 /**
55 * Constructs a new PCMtoPCM codec object.
56 */
57 public PCMtoPCMCodec() {
58
59 super( inputEncodings, outputEncodings);
60 }
61
62 // NEW CODE
63
64 public AudioFormat.Encoding[] getTargetEncodings(AudioFormat sourceFormat) {
65
66 final int sampleSize = sourceFormat.getSampleSizeInBits();
67 AudioFormat.Encoding encoding = sourceFormat.getEncoding();
68 if (sampleSize == 8) {
69 if (encoding.equals(AudioFormat.Encoding.PCM_SIGNED)) {
70 return new AudioFormat.Encoding[]{
71 AudioFormat.Encoding.PCM_UNSIGNED
72 };
73 }
74 if (encoding.equals(AudioFormat.Encoding.PCM_UNSIGNED)) {
75 return new AudioFormat.Encoding[]{
76 AudioFormat.Encoding.PCM_SIGNED
77 };
78 }
79 } else if (sampleSize == 16) {
80 if (encoding.equals(AudioFormat.Encoding.PCM_SIGNED)
81 || encoding.equals(AudioFormat.Encoding.PCM_UNSIGNED)) {
82 return new AudioFormat.Encoding[]{
83 AudioFormat.Encoding.PCM_UNSIGNED,
84 AudioFormat.Encoding.PCM_SIGNED
85 };
86 }
87 }
88 return new AudioFormat.Encoding[0];
89 }
90
91
92 /**
93 */
94 public AudioFormat[] getTargetFormats(AudioFormat.Encoding targetEncoding, AudioFormat sourceFormat){
95 Objects.requireNonNull(targetEncoding);
96
97 // filter out targetEncoding from the old getOutputFormats( sourceFormat ) method
98
99 AudioFormat[] formats = getOutputFormats( sourceFormat );
100 Vector<AudioFormat> newFormats = new Vector<>();
101 for(int i=0; i<formats.length; i++ ) {
102 if( formats[i].getEncoding().equals( targetEncoding ) ) {
103 newFormats.addElement( formats[i] );
104 }
105 }
106
107 AudioFormat[] formatArray = new AudioFormat[newFormats.size()];
108
109 for (int i = 0; i < formatArray.length; i++) {
110 formatArray[i] = newFormats.elementAt(i);
111 }
112
113 return formatArray;
114 }
115
116
117 /**
118 */
119 public AudioInputStream getAudioInputStream(AudioFormat.Encoding targetEncoding, AudioInputStream sourceStream) {
120
121 if( isConversionSupported(targetEncoding, sourceStream.getFormat()) ) {
122
123 AudioFormat sourceFormat = sourceStream.getFormat();
124 AudioFormat targetFormat = new AudioFormat( targetEncoding,
125 sourceFormat.getSampleRate(),
126 sourceFormat.getSampleSizeInBits(),
127 sourceFormat.getChannels(),
128 sourceFormat.getFrameSize(),
129 sourceFormat.getFrameRate(),
130 sourceFormat.isBigEndian() );
131
132 return getConvertedStream(targetFormat, sourceStream);
133
134 } else {
135 throw new IllegalArgumentException("Unsupported conversion: " + sourceStream.getFormat().toString() + " to " + targetEncoding.toString() );
136 }
137
138 }
139 /**
140 * use old code
141 */
142 public AudioInputStream getAudioInputStream(AudioFormat targetFormat, AudioInputStream sourceStream){
143 if (!isConversionSupported(targetFormat, sourceStream.getFormat()))
144 throw new IllegalArgumentException("Unsupported conversion: "
145 + sourceStream.getFormat().toString() + " to "
146 + targetFormat.toString());
147 return getConvertedStream( targetFormat, sourceStream );
148 }
149
150
151
152
153 // OLD CODE
154
155 /**
156 * Opens the codec with the specified parameters.
157 * @param stream stream from which data to be processed should be read
158 * @param outputFormat desired data format of the stream after processing
159 * @return stream from which processed data may be read
160 * @throws IllegalArgumentException if the format combination supplied is
161 * not supported.
162 */
163 /* public AudioInputStream getConvertedStream(AudioFormat outputFormat, AudioInputStream stream) {*/
164 private AudioInputStream getConvertedStream(AudioFormat outputFormat, AudioInputStream stream) {
165
166 AudioInputStream cs = null;
167
168 AudioFormat inputFormat = stream.getFormat();
169
170 if( inputFormat.matches(outputFormat) ) {
171
172 cs = stream;
173 } else {
174
175 cs = (AudioInputStream) (new PCMtoPCMCodecStream(stream, outputFormat));
176 }
177 return cs;
178 }
179
180
181
182 /**
183 * Obtains the set of output formats supported by the codec
184 * given a particular input format.
185 * If no output formats are supported for this input format,
186 * returns an array of length 0.
187 * @return array of supported output formats.
188 */
189 /* public AudioFormat[] getOutputFormats(AudioFormat inputFormat) { */
190 private AudioFormat[] getOutputFormats(AudioFormat inputFormat) {
191
192 Vector<AudioFormat> formats = new Vector<>();
193 AudioFormat format;
194
195 int sampleSize = inputFormat.getSampleSizeInBits();
196 boolean isBigEndian = inputFormat.isBigEndian();
197
198
199 if ( sampleSize==8 ) {
200 if ( AudioFormat.Encoding.PCM_SIGNED.equals(inputFormat.getEncoding()) ) {
201
202 format = new AudioFormat(AudioFormat.Encoding.PCM_UNSIGNED,
203 inputFormat.getSampleRate(),
204 inputFormat.getSampleSizeInBits(),
205 inputFormat.getChannels(),
206 inputFormat.getFrameSize(),
207 inputFormat.getFrameRate(),
208 false );
209 formats.addElement(format);
333 inputFormat.getFrameRate(),
334 true );
335 formats.addElement(format);
336 }
337 }
338 AudioFormat[] formatArray;
339
340 synchronized(formats) {
341
342 formatArray = new AudioFormat[formats.size()];
343
344 for (int i = 0; i < formatArray.length; i++) {
345
346 formatArray[i] = formats.elementAt(i);
347 }
348 }
349
350 return formatArray;
351 }
352
353
354 class PCMtoPCMCodecStream extends AudioInputStream {
355
356 private final int PCM_SWITCH_SIGNED_8BIT = 1;
357 private final int PCM_SWITCH_ENDIAN = 2;
358 private final int PCM_SWITCH_SIGNED_LE = 3;
359 private final int PCM_SWITCH_SIGNED_BE = 4;
360 private final int PCM_UNSIGNED_LE2SIGNED_BE = 5;
361 private final int PCM_SIGNED_LE2UNSIGNED_BE = 6;
362 private final int PCM_UNSIGNED_BE2SIGNED_LE = 7;
363 private final int PCM_SIGNED_BE2UNSIGNED_LE = 8;
364
365 private final int sampleSizeInBytes;
366 private int conversionType = 0;
367
368
369 PCMtoPCMCodecStream(AudioInputStream stream, AudioFormat outputFormat) {
370
371 super(stream, outputFormat, -1);
372
373 int sampleSizeInBits = 0;
443
444 frameSize = inputFormat.getFrameSize();
445 if( frameSize == AudioSystem.NOT_SPECIFIED ) {
446 frameSize=1;
447 }
448 if( stream instanceof AudioInputStream ) {
449 frameLength = stream.getFrameLength();
450 } else {
451 frameLength = AudioSystem.NOT_SPECIFIED;
452 }
453
454 // set framePos to zero
455 framePos = 0;
456
457 }
458
459 /**
460 * Note that this only works for sign conversions.
461 * Other conversions require a read of at least 2 bytes.
462 */
463
464 public int read() throws IOException {
465
466 // $$jb: do we want to implement this function?
467
468 int temp;
469 byte tempbyte;
470
471 if( frameSize==1 ) {
472 if( conversionType == PCM_SWITCH_SIGNED_8BIT ) {
473 temp = super.read();
474
475 if( temp < 0 ) return temp; // EOF or error
476
477 tempbyte = (byte) (temp & 0xf);
478 tempbyte = (tempbyte >= 0) ? (byte)(0x80 | tempbyte) : (byte)(0x7F & tempbyte);
479 temp = (int) tempbyte & 0xf;
480
481 return temp;
482
483 } else {
484 // $$jb: what to return here?
485 throw new IOException("cannot read a single byte if frame size > 1");
486 }
487 } else {
488 throw new IOException("cannot read a single byte if frame size > 1");
489 }
490 }
491
492
493 public int read(byte[] b) throws IOException {
494
495 return read(b, 0, b.length);
496 }
497
498 public int read(byte[] b, int off, int len) throws IOException {
499
500
501 int i;
502
503 // don't read fractional frames
504 if ( len%frameSize != 0 ) {
505 len -= (len%frameSize);
506 }
507 // don't read past our own set length
508 if( (frameLength!=AudioSystem.NOT_SPECIFIED) && ( (len/frameSize) >(frameLength-framePos)) ) {
509 len = (int)(frameLength-framePos) * frameSize;
510 }
511
512 int readCount = super.read(b, off, len);
513 byte tempByte;
514
515 if(readCount<0) { // EOF or error
516 return readCount;
517 }
572 }
573
574 private void switchSignedLE(byte[] b, int off, int len, int readCount) {
575
576 for(int i=(off+sampleSizeInBytes-1); i < (off+readCount); i+= sampleSizeInBytes ) {
577 b[i] = (b[i] >= 0) ? (byte)(0x80 | b[i]) : (byte)(0x7F & b[i]);
578 }
579 }
580
581 private void switchEndian(byte[] b, int off, int len, int readCount) {
582
583 if(sampleSizeInBytes == 2) {
584 for(int i=off; i < (off+readCount); i += sampleSizeInBytes ) {
585 byte temp;
586 temp = b[i];
587 b[i] = b[i+1];
588 b[i+1] = temp;
589 }
590 }
591 }
592
593
594
595 } // end class PCMtoPCMCodecStream
596
597 } // end class PCMtoPCMCodec
|
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 * Converts among signed/unsigned and little/big endianness of sampled.
38 *
39 * @author Jan Borgersen
40 */
41 public final class PCMtoPCMCodec extends SunCodec {
42
43 private static final AudioFormat.Encoding[] inputEncodings = {
44 AudioFormat.Encoding.PCM_SIGNED,
45 AudioFormat.Encoding.PCM_UNSIGNED,
46 };
47
48 private static final AudioFormat.Encoding[] outputEncodings = {
49 AudioFormat.Encoding.PCM_SIGNED,
50 AudioFormat.Encoding.PCM_UNSIGNED,
51 };
52
53 /**
54 * Constructs a new PCMtoPCM codec object.
55 */
56 public PCMtoPCMCodec() {
57
58 super( inputEncodings, outputEncodings);
59 }
60
61 @Override
62 public AudioFormat.Encoding[] getTargetEncodings(AudioFormat sourceFormat) {
63
64 final int sampleSize = sourceFormat.getSampleSizeInBits();
65 AudioFormat.Encoding encoding = sourceFormat.getEncoding();
66 if (sampleSize == 8) {
67 if (encoding.equals(AudioFormat.Encoding.PCM_SIGNED)) {
68 return new AudioFormat.Encoding[]{
69 AudioFormat.Encoding.PCM_UNSIGNED
70 };
71 }
72 if (encoding.equals(AudioFormat.Encoding.PCM_UNSIGNED)) {
73 return new AudioFormat.Encoding[]{
74 AudioFormat.Encoding.PCM_SIGNED
75 };
76 }
77 } else if (sampleSize == 16) {
78 if (encoding.equals(AudioFormat.Encoding.PCM_SIGNED)
79 || encoding.equals(AudioFormat.Encoding.PCM_UNSIGNED)) {
80 return new AudioFormat.Encoding[]{
81 AudioFormat.Encoding.PCM_UNSIGNED,
82 AudioFormat.Encoding.PCM_SIGNED
83 };
84 }
85 }
86 return new AudioFormat.Encoding[0];
87 }
88
89 @Override
90 public AudioFormat[] getTargetFormats(AudioFormat.Encoding targetEncoding, AudioFormat sourceFormat){
91 Objects.requireNonNull(targetEncoding);
92
93 // filter out targetEncoding from the old getOutputFormats( sourceFormat ) method
94
95 AudioFormat[] formats = getOutputFormats( sourceFormat );
96 Vector<AudioFormat> newFormats = new Vector<>();
97 for(int i=0; i<formats.length; i++ ) {
98 if( formats[i].getEncoding().equals( targetEncoding ) ) {
99 newFormats.addElement( formats[i] );
100 }
101 }
102
103 AudioFormat[] formatArray = new AudioFormat[newFormats.size()];
104
105 for (int i = 0; i < formatArray.length; i++) {
106 formatArray[i] = newFormats.elementAt(i);
107 }
108
109 return formatArray;
110 }
111
112 @Override
113 public AudioInputStream getAudioInputStream(AudioFormat.Encoding targetEncoding, AudioInputStream sourceStream) {
114
115 if( isConversionSupported(targetEncoding, sourceStream.getFormat()) ) {
116
117 AudioFormat sourceFormat = sourceStream.getFormat();
118 AudioFormat targetFormat = new AudioFormat( targetEncoding,
119 sourceFormat.getSampleRate(),
120 sourceFormat.getSampleSizeInBits(),
121 sourceFormat.getChannels(),
122 sourceFormat.getFrameSize(),
123 sourceFormat.getFrameRate(),
124 sourceFormat.isBigEndian() );
125
126 return getConvertedStream(targetFormat, sourceStream);
127
128 } else {
129 throw new IllegalArgumentException("Unsupported conversion: " + sourceStream.getFormat().toString() + " to " + targetEncoding.toString() );
130 }
131
132 }
133
134 @Override
135 public AudioInputStream getAudioInputStream(AudioFormat targetFormat, AudioInputStream sourceStream){
136 if (!isConversionSupported(targetFormat, sourceStream.getFormat()))
137 throw new IllegalArgumentException("Unsupported conversion: "
138 + sourceStream.getFormat().toString() + " to "
139 + targetFormat.toString());
140 return getConvertedStream( targetFormat, sourceStream );
141 }
142
143 /**
144 * Opens the codec with the specified parameters.
145 * @param stream stream from which data to be processed should be read
146 * @param outputFormat desired data format of the stream after processing
147 * @return stream from which processed data may be read
148 * @throws IllegalArgumentException if the format combination supplied is
149 * not supported.
150 */
151 private AudioInputStream getConvertedStream(AudioFormat outputFormat, AudioInputStream stream) {
152
153 AudioInputStream cs = null;
154
155 AudioFormat inputFormat = stream.getFormat();
156
157 if( inputFormat.matches(outputFormat) ) {
158
159 cs = stream;
160 } else {
161
162 cs = new PCMtoPCMCodecStream(stream, outputFormat);
163 }
164 return cs;
165 }
166
167 /**
168 * Obtains the set of output formats supported by the codec
169 * given a particular input format.
170 * If no output formats are supported for this input format,
171 * returns an array of length 0.
172 * @return array of supported output formats.
173 */
174 private AudioFormat[] getOutputFormats(AudioFormat inputFormat) {
175
176 Vector<AudioFormat> formats = new Vector<>();
177 AudioFormat format;
178
179 int sampleSize = inputFormat.getSampleSizeInBits();
180 boolean isBigEndian = inputFormat.isBigEndian();
181
182
183 if ( sampleSize==8 ) {
184 if ( AudioFormat.Encoding.PCM_SIGNED.equals(inputFormat.getEncoding()) ) {
185
186 format = new AudioFormat(AudioFormat.Encoding.PCM_UNSIGNED,
187 inputFormat.getSampleRate(),
188 inputFormat.getSampleSizeInBits(),
189 inputFormat.getChannels(),
190 inputFormat.getFrameSize(),
191 inputFormat.getFrameRate(),
192 false );
193 formats.addElement(format);
317 inputFormat.getFrameRate(),
318 true );
319 formats.addElement(format);
320 }
321 }
322 AudioFormat[] formatArray;
323
324 synchronized(formats) {
325
326 formatArray = new AudioFormat[formats.size()];
327
328 for (int i = 0; i < formatArray.length; i++) {
329
330 formatArray[i] = formats.elementAt(i);
331 }
332 }
333
334 return formatArray;
335 }
336
337 class PCMtoPCMCodecStream extends AudioInputStream {
338
339 private final int PCM_SWITCH_SIGNED_8BIT = 1;
340 private final int PCM_SWITCH_ENDIAN = 2;
341 private final int PCM_SWITCH_SIGNED_LE = 3;
342 private final int PCM_SWITCH_SIGNED_BE = 4;
343 private final int PCM_UNSIGNED_LE2SIGNED_BE = 5;
344 private final int PCM_SIGNED_LE2UNSIGNED_BE = 6;
345 private final int PCM_UNSIGNED_BE2SIGNED_LE = 7;
346 private final int PCM_SIGNED_BE2UNSIGNED_LE = 8;
347
348 private final int sampleSizeInBytes;
349 private int conversionType = 0;
350
351
352 PCMtoPCMCodecStream(AudioInputStream stream, AudioFormat outputFormat) {
353
354 super(stream, outputFormat, -1);
355
356 int sampleSizeInBits = 0;
426
427 frameSize = inputFormat.getFrameSize();
428 if( frameSize == AudioSystem.NOT_SPECIFIED ) {
429 frameSize=1;
430 }
431 if( stream instanceof AudioInputStream ) {
432 frameLength = stream.getFrameLength();
433 } else {
434 frameLength = AudioSystem.NOT_SPECIFIED;
435 }
436
437 // set framePos to zero
438 framePos = 0;
439
440 }
441
442 /**
443 * Note that this only works for sign conversions.
444 * Other conversions require a read of at least 2 bytes.
445 */
446 @Override
447 public int read() throws IOException {
448
449 // $$jb: do we want to implement this function?
450
451 int temp;
452 byte tempbyte;
453
454 if( frameSize==1 ) {
455 if( conversionType == PCM_SWITCH_SIGNED_8BIT ) {
456 temp = super.read();
457
458 if( temp < 0 ) return temp; // EOF or error
459
460 tempbyte = (byte) (temp & 0xf);
461 tempbyte = (tempbyte >= 0) ? (byte)(0x80 | tempbyte) : (byte)(0x7F & tempbyte);
462 temp = (int) tempbyte & 0xf;
463
464 return temp;
465
466 } else {
467 // $$jb: what to return here?
468 throw new IOException("cannot read a single byte if frame size > 1");
469 }
470 } else {
471 throw new IOException("cannot read a single byte if frame size > 1");
472 }
473 }
474
475 @Override
476 public int read(byte[] b) throws IOException {
477
478 return read(b, 0, b.length);
479 }
480
481 @Override
482 public int read(byte[] b, int off, int len) throws IOException {
483
484
485 int i;
486
487 // don't read fractional frames
488 if ( len%frameSize != 0 ) {
489 len -= (len%frameSize);
490 }
491 // don't read past our own set length
492 if( (frameLength!=AudioSystem.NOT_SPECIFIED) && ( (len/frameSize) >(frameLength-framePos)) ) {
493 len = (int)(frameLength-framePos) * frameSize;
494 }
495
496 int readCount = super.read(b, off, len);
497 byte tempByte;
498
499 if(readCount<0) { // EOF or error
500 return readCount;
501 }
556 }
557
558 private void switchSignedLE(byte[] b, int off, int len, int readCount) {
559
560 for(int i=(off+sampleSizeInBytes-1); i < (off+readCount); i+= sampleSizeInBytes ) {
561 b[i] = (b[i] >= 0) ? (byte)(0x80 | b[i]) : (byte)(0x7F & b[i]);
562 }
563 }
564
565 private void switchEndian(byte[] b, int off, int len, int readCount) {
566
567 if(sampleSizeInBytes == 2) {
568 for(int i=off; i < (off+readCount); i += sampleSizeInBytes ) {
569 byte temp;
570 temp = b[i];
571 b[i] = b[i+1];
572 b[i+1] = temp;
573 }
574 }
575 }
576 } // end class PCMtoPCMCodecStream
577 } // end class PCMtoPCMCodec
|