/** * Numbers used here are verbatim from Javazoom * * @param baseFormat * @return */ private AudioFormat getDecodedFormat(AudioFormat baseFormat) { // Do we need to "decode" the base format? if (AudioFormat.Encoding.PCM_SIGNED.equals(baseFormat.getEncoding()) || AudioFormat.Encoding.PCM_UNSIGNED.equals(baseFormat.getEncoding())) { return baseFormat; } return new AudioFormat( AudioFormat.Encoding.PCM_SIGNED, baseFormat.getSampleRate(), 16, baseFormat.getChannels(), baseFormat.getChannels() * 2, baseFormat.getSampleRate(), false); }
@Override public AudioFileFormat.Type[] getAudioFileTypes(AudioInputStream stream) { AudioFileFormat.Type[] filetypes = new AudioFileFormat.Type[types.length]; System.arraycopy(types, 0, filetypes, 0, types.length); // make sure we can write this stream AudioFormat format = stream.getFormat(); AudioFormat.Encoding encoding = format.getEncoding(); if (AudioFormat.Encoding.ALAW.equals(encoding) || AudioFormat.Encoding.ULAW.equals(encoding) || AudioFormat.Encoding.PCM_SIGNED.equals(encoding) || AudioFormat.Encoding.PCM_UNSIGNED.equals(encoding)) { return filetypes; } return new AudioFileFormat.Type[0]; }
private InputStream getFileStream(WaveFileFormat waveFileFormat, InputStream audioStream) throws IOException { // private method ... assumes audioFileFormat is a supported file type // WAVE header fields AudioFormat audioFormat = waveFileFormat.getFormat(); int headerLength = waveFileFormat.getHeaderSize(); int riffMagic = WaveFileFormat.RIFF_MAGIC; int waveMagic = WaveFileFormat.WAVE_MAGIC; int fmtMagic = WaveFileFormat.FMT_MAGIC; int fmtLength = WaveFileFormat.getFmtChunkSize(waveFileFormat.getWaveType()); short wav_type = (short) waveFileFormat.getWaveType(); short channels = (short) audioFormat.getChannels(); short sampleSizeInBits = (short) audioFormat.getSampleSizeInBits(); int sampleRate = (int) audioFormat.getSampleRate(); int frameSizeInBytes = audioFormat.getFrameSize(); int frameRate = (int) audioFormat.getFrameRate(); int avgBytesPerSec = channels * sampleSizeInBits * sampleRate / 8; short blockAlign = (short) ((sampleSizeInBits / 8) * channels); int dataMagic = WaveFileFormat.DATA_MAGIC; int dataLength = waveFileFormat.getFrameLength() * frameSizeInBytes; int length = waveFileFormat.getByteLength(); int riffLength = dataLength + headerLength - 8; byte header[] = null; ByteArrayInputStream headerStream = null; ByteArrayOutputStream baos = null; DataOutputStream dos = null; SequenceInputStream waveStream = null; AudioFormat audioStreamFormat = null; AudioFormat.Encoding encoding = null; InputStream codedAudioStream = audioStream; // if audioStream is an AudioInputStream and we need to convert, do it here... if (audioStream instanceof AudioInputStream) { audioStreamFormat = ((AudioInputStream) audioStream).getFormat(); encoding = audioStreamFormat.getEncoding(); if (AudioFormat.Encoding.PCM_SIGNED.equals(encoding)) { if (sampleSizeInBits == 8) { wav_type = WaveFileFormat.WAVE_FORMAT_PCM; // plug in the transcoder to convert from PCM_SIGNED to PCM_UNSIGNED codedAudioStream = AudioSystem.getAudioInputStream( new AudioFormat( AudioFormat.Encoding.PCM_UNSIGNED, audioStreamFormat.getSampleRate(), audioStreamFormat.getSampleSizeInBits(), audioStreamFormat.getChannels(), audioStreamFormat.getFrameSize(), audioStreamFormat.getFrameRate(), false), (AudioInputStream) audioStream); } } if ((AudioFormat.Encoding.PCM_SIGNED.equals(encoding) && audioStreamFormat.isBigEndian()) || (AudioFormat.Encoding.PCM_UNSIGNED.equals(encoding) && !audioStreamFormat.isBigEndian()) || (AudioFormat.Encoding.PCM_UNSIGNED.equals(encoding) && audioStreamFormat.isBigEndian())) { if (sampleSizeInBits != 8) { wav_type = WaveFileFormat.WAVE_FORMAT_PCM; // plug in the transcoder to convert to PCM_SIGNED_LITTLE_ENDIAN codedAudioStream = AudioSystem.getAudioInputStream( new AudioFormat( AudioFormat.Encoding.PCM_SIGNED, audioStreamFormat.getSampleRate(), audioStreamFormat.getSampleSizeInBits(), audioStreamFormat.getChannels(), audioStreamFormat.getFrameSize(), audioStreamFormat.getFrameRate(), false), (AudioInputStream) audioStream); } } } // Now push the header into a stream, concat, and return the new SequenceInputStream baos = new ByteArrayOutputStream(); dos = new DataOutputStream(baos); // we write in littleendian... dos.writeInt(riffMagic); dos.writeInt(big2little(riffLength)); dos.writeInt(waveMagic); dos.writeInt(fmtMagic); dos.writeInt(big2little(fmtLength)); dos.writeShort(big2littleShort(wav_type)); dos.writeShort(big2littleShort(channels)); dos.writeInt(big2little(sampleRate)); dos.writeInt(big2little(avgBytesPerSec)); dos.writeShort(big2littleShort(blockAlign)); dos.writeShort(big2littleShort(sampleSizeInBits)); // $$fb 2002-04-16: Fix for 4636355: RIFF audio headers could be _more_ spec compliant if (wav_type != WaveFileFormat.WAVE_FORMAT_PCM) { // add length 0 for "codec specific data length" dos.writeShort(0); } dos.writeInt(dataMagic); dos.writeInt(big2little(dataLength)); dos.close(); header = baos.toByteArray(); headerStream = new ByteArrayInputStream(header); waveStream = new SequenceInputStream(headerStream, new NoCloseInputStream(codedAudioStream)); return waveStream; }