< prev index next >

src/java.desktop/share/classes/com/sun/media/sound/PCMtoPCMCodec.java

Print this page




  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
< prev index next >