src/java.desktop/share/classes/com/sun/media/sound/WaveFileWriter.java
changeset 48282 4483880d8811
parent 47216 71c04702a3d5
child 52248 2e330da7cbf4
equal deleted inserted replaced
48281:1a6c071312a3 48282:4483880d8811
     1 /*
     1 /*
     2  * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
     2  * Copyright (c) 1999, 2017, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     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
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.  Oracle designates this
     7  * published by the Free Software Foundation.  Oracle designates this
   111 
   111 
   112         // throws IllegalArgumentException if not supported
   112         // throws IllegalArgumentException if not supported
   113         WaveFileFormat waveFileFormat = (WaveFileFormat)getAudioFileFormat(fileType, stream);
   113         WaveFileFormat waveFileFormat = (WaveFileFormat)getAudioFileFormat(fileType, stream);
   114 
   114 
   115         // first write the file without worrying about length fields
   115         // first write the file without worrying about length fields
   116         FileOutputStream fos = new FileOutputStream( out );     // throws IOException
   116         final int bytesWritten;
   117         BufferedOutputStream bos = new BufferedOutputStream( fos, bisBufferSize );
   117         try (final FileOutputStream fos = new FileOutputStream(out);
   118         int bytesWritten = writeWaveFile(stream, waveFileFormat, bos );
   118              final BufferedOutputStream bos = new BufferedOutputStream(fos)) {
   119         bos.close();
   119             bytesWritten = writeWaveFile(stream, waveFileFormat, bos);
       
   120         }
   120 
   121 
   121         // now, if length fields were not specified, calculate them,
   122         // now, if length fields were not specified, calculate them,
   122         // open as a random access file, write the appropriate fields,
   123         // open as a random access file, write the appropriate fields,
   123         // close again....
   124         // close again....
   124         if( waveFileFormat.getByteLength()== AudioSystem.NOT_SPECIFIED ) {
   125         if( waveFileFormat.getByteLength()== AudioSystem.NOT_SPECIFIED ) {
   125 
   126 
   126             int dataLength=bytesWritten-waveFileFormat.getHeaderSize();
   127             int dataLength=bytesWritten-waveFileFormat.getHeaderSize();
   127             int riffLength=dataLength + waveFileFormat.getHeaderSize() - 8;
   128             int riffLength=dataLength + waveFileFormat.getHeaderSize() - 8;
   128 
   129             try (final RandomAccessFile raf = new RandomAccessFile(out, "rw")) {
   129             RandomAccessFile raf=new RandomAccessFile(out, "rw");
   130                 // skip RIFF magic
   130             // skip RIFF magic
   131                 raf.skipBytes(4);
   131             raf.skipBytes(4);
   132                 raf.writeInt(big2little(riffLength));
   132             raf.writeInt(big2little( riffLength ));
   133                 // skip WAVE magic, fmt_ magic, fmt_ length, fmt_ chunk, data magic
   133             // skip WAVE magic, fmt_ magic, fmt_ length, fmt_ chunk, data magic
   134                 raf.skipBytes(4 + 4 + 4 + WaveFileFormat.getFmtChunkSize(
   134             raf.skipBytes(4+4+4+WaveFileFormat.getFmtChunkSize(waveFileFormat.getWaveType())+4);
   135                         waveFileFormat.getWaveType()) + 4);
   135             raf.writeInt(big2little( dataLength ));
   136                 raf.writeInt(big2little(dataLength));
   136             // that's all
   137                 // that's all
   137             raf.close();
   138             }
   138         }
   139         }
   139 
   140 
   140         return bytesWritten;
   141         return bytesWritten;
   141     }
   142     }
   142 
   143 
   260         int dataMagic              = WaveFileFormat.DATA_MAGIC;
   261         int dataMagic              = WaveFileFormat.DATA_MAGIC;
   261         int dataLength             = waveFileFormat.getFrameLength() * frameSizeInBytes;
   262         int dataLength             = waveFileFormat.getFrameLength() * frameSizeInBytes;
   262         int length                         = waveFileFormat.getByteLength();
   263         int length                         = waveFileFormat.getByteLength();
   263         int riffLength = dataLength + headerLength - 8;
   264         int riffLength = dataLength + headerLength - 8;
   264 
   265 
   265         byte header[] = null;
       
   266         ByteArrayInputStream headerStream = null;
       
   267         ByteArrayOutputStream baos = null;
       
   268         DataOutputStream dos = null;
       
   269         SequenceInputStream waveStream = null;
       
   270 
       
   271         AudioFormat audioStreamFormat = null;
   266         AudioFormat audioStreamFormat = null;
   272         AudioFormat.Encoding encoding = null;
   267         AudioFormat.Encoding encoding = null;
   273         InputStream codedAudioStream = audioStream;
   268         InputStream codedAudioStream = audioStream;
   274 
   269 
   275         // if audioStream is an AudioInputStream and we need to convert, do it here...
   270         // if audioStream is an AudioInputStream and we need to convert, do it here...
   312             }
   307             }
   313         }
   308         }
   314 
   309 
   315 
   310 
   316         // Now push the header into a stream, concat, and return the new SequenceInputStream
   311         // Now push the header into a stream, concat, and return the new SequenceInputStream
   317 
   312         final byte[] header;
   318         baos = new ByteArrayOutputStream();
   313         try (final ByteArrayOutputStream baos = new ByteArrayOutputStream();
   319         dos = new DataOutputStream(baos);
   314              final DataOutputStream dos = new DataOutputStream(baos)) {
   320 
   315             // we write in littleendian...
   321         // we write in littleendian...
   316             dos.writeInt(riffMagic);
   322         dos.writeInt(riffMagic);
   317             dos.writeInt(big2little(riffLength));
   323         dos.writeInt(big2little( riffLength ));
   318             dos.writeInt(waveMagic);
   324         dos.writeInt(waveMagic);
   319             dos.writeInt(fmtMagic);
   325         dos.writeInt(fmtMagic);
   320             dos.writeInt(big2little(fmtLength));
   326         dos.writeInt(big2little(fmtLength));
   321             dos.writeShort(big2littleShort(wav_type));
   327         dos.writeShort(big2littleShort(wav_type));
   322             dos.writeShort(big2littleShort(channels));
   328         dos.writeShort(big2littleShort(channels));
   323             dos.writeInt(big2little(sampleRate));
   329         dos.writeInt(big2little(sampleRate));
   324             dos.writeInt(big2little(avgBytesPerSec));
   330         dos.writeInt(big2little(avgBytesPerSec));
   325             dos.writeShort(big2littleShort(blockAlign));
   331         dos.writeShort(big2littleShort(blockAlign));
   326             dos.writeShort(big2littleShort(sampleSizeInBits));
   332         dos.writeShort(big2littleShort(sampleSizeInBits));
   327             //$$fb 2002-04-16: Fix for 4636355: RIFF audio headers could be _more_ spec compliant
   333         //$$fb 2002-04-16: Fix for 4636355: RIFF audio headers could be _more_ spec compliant
   328             if (wav_type != WaveFileFormat.WAVE_FORMAT_PCM) {
   334         if (wav_type != WaveFileFormat.WAVE_FORMAT_PCM) {
   329                 // add length 0 for "codec specific data length"
   335             // add length 0 for "codec specific data length"
   330                 dos.writeShort(0);
   336             dos.writeShort(0);
   331             }
   337         }
   332             dos.writeInt(dataMagic);
   338 
   333             dos.writeInt(big2little(dataLength));
   339         dos.writeInt(dataMagic);
   334             header = baos.toByteArray();
   340         dos.writeInt(big2little(dataLength));
   335         }
   341 
   336         return new SequenceInputStream(new ByteArrayInputStream(header),
   342         dos.close();
   337                                        new NoCloseInputStream(codedAudioStream));
   343         header = baos.toByteArray();
       
   344         headerStream = new ByteArrayInputStream( header );
       
   345         waveStream = new SequenceInputStream(headerStream,
       
   346                             new NoCloseInputStream(codedAudioStream));
       
   347 
       
   348         return waveStream;
       
   349     }
   338     }
   350 }
   339 }