📄 taudiofilewriter.java
字号:
if (TDebug.TraceAudioFileWriter) { TDebug.out("input format: " + inputFormat); } AudioFormat outputFormat = null; boolean bNeedsConversion = false; if (isAudioFormatSupportedImpl(inputFormat, fileType)) { if (TDebug.TraceAudioFileWriter) { TDebug.out("input format is supported directely"); } outputFormat = inputFormat; bNeedsConversion = false; } else { if (TDebug.TraceAudioFileWriter) { TDebug.out("input format is not supported directely; trying to find a convertable format"); } outputFormat = findConvertableFormat(inputFormat, fileType); if (outputFormat != null) { bNeedsConversion = true; // $$fb 2000-08-16 made consistent with new conversion trials // if 8 bit and only endianness changed, don't convert ! if (outputFormat.getSampleSizeInBits()==8 && outputFormat.getEncoding().equals(inputFormat.getEncoding())) { bNeedsConversion = false; } } else { if (TDebug.TraceAudioFileWriter) { TDebug.out("< format is not supported"); } throw new IllegalArgumentException("format not supported and not convertable"); } } long lLengthInBytes = AudioUtils.getLengthInBytes(audioInputStream); TDataOutputStream dataOutputStream = new TNonSeekableDataOutputStream(outputStream); AudioOutputStream audioOutputStream = getAudioOutputStream( outputFormat, lLengthInBytes, fileType, dataOutputStream); int written=writeImpl(audioInputStream, audioOutputStream, bNeedsConversion); if (TDebug.TraceAudioFileWriter) { TDebug.out("< wrote "+written+" bytes."); } return written; } protected int writeImpl( AudioInputStream audioInputStream, AudioOutputStream audioOutputStream, boolean bNeedsConversion) throws IOException { if (TDebug.TraceAudioFileWriter) { TDebug.out(">TAudioFileWriter.writeImpl(): called"); TDebug.out("class: "+getClass().getName()); } int nTotalWritten = 0; AudioFormat inputFormat = audioInputStream.getFormat(); AudioFormat outputFormat = audioOutputStream.getFormat(); // TODO: handle case when frame size is unknown ? int nBytesPerSample = outputFormat.getFrameSize() / outputFormat.getChannels(); //$$fb 2000-07-18: BUFFER_LENGTH must be a multiple of frame size... int nBufferSize=((int)BUFFER_LENGTH/outputFormat.getFrameSize())*outputFormat.getFrameSize(); byte[] abBuffer = new byte[nBufferSize]; while (true) { if (TDebug.TraceAudioFileWriter) { TDebug.out("trying to read (bytes): " + abBuffer.length); } int nBytesRead = audioInputStream.read(abBuffer); if (TDebug.TraceAudioFileWriter) { TDebug.out("read (bytes): " + nBytesRead); } if (nBytesRead == -1) { break; } if (bNeedsConversion) { TConversionTool.changeOrderOrSign(abBuffer, 0, nBytesRead, nBytesPerSample); } int nWritten = audioOutputStream.write(abBuffer, 0, nBytesRead); nTotalWritten += nWritten; } if (TDebug.TraceAudioFileWriter) { TDebug.out("<TAudioFileWriter.writeImpl(): after main loop. Wrote "+nTotalWritten+" bytes"); } audioOutputStream.close(); // TODO: get bytes written for header etc. from AudioOutputStrem and add to nTotalWrittenBytes return nTotalWritten; } /** Returns the AudioFormat that can be handled for the given file type. * In this simple implementation, all handled AudioFormats are * returned (i.e. the fileType argument is ignored). If the * handled AudioFormats depend on the file type, this method * has to be overwritten by subclasses. */ protected Iterator getSupportedAudioFormats(AudioFileFormat.Type fileType) { return m_audioFormats.iterator(); } /** Checks whether the passed <b>AudioFormat</b> can be handled. * In this simple implementation, it is only checked if the * passed AudioFormat matches one of the generally handled * formats (i.e. the fileType argument is ignored). If the * handled AudioFormats depend on the file type, this method * or getSupportedAudioFormats() (on which this method relies) * has to be overwritten by subclasses. * <p> * This is the central method for checking if a FORMAT is supported. * Inheriting classes can overwrite this for performance * or to exclude/include special type/format combinations. * <p> * This method is only called when the <code>fileType</code> * is in the list of supported file types ! Overriding * classes <b>need not</b> check this. */ //$$fb 2000-08-16 changed name, changed documentation. Semantics ! protected boolean isAudioFormatSupportedImpl( AudioFormat audioFormat, AudioFileFormat.Type fileType) { if (TDebug.TraceAudioFileWriter) { TDebug.out("> TAudioFileWriter.isAudioFormatSupportedImpl(): format to test: " + audioFormat); TDebug.out("class: "+getClass().getName()); } Iterator audioFormats = getSupportedAudioFormats(fileType); while (audioFormats.hasNext()) { AudioFormat handledFormat = (AudioFormat) audioFormats.next(); if (TDebug.TraceAudioFileWriter) { TDebug.out("matching against format : " + handledFormat); } if (AudioFormats.matches(handledFormat, audioFormat)) { if (TDebug.TraceAudioFileWriter) { TDebug.out("<...succeeded."); } return true; } } if (TDebug.TraceAudioFileWriter) { TDebug.out("< ... failed"); } return false; } protected abstract AudioOutputStream getAudioOutputStream( AudioFormat audioFormat, long lLengthInBytes, AudioFileFormat.Type fileType, TDataOutputStream dataOutputStream) throws IOException; private AudioFormat findConvertableFormat( AudioFormat inputFormat, AudioFileFormat.Type fileType) { if (TDebug.TraceAudioFileWriter) { TDebug.out("TAudioFileWriter.findConvertableFormat(): input format: " + inputFormat); } if (!isFileTypeSupported(fileType)) { if (TDebug.TraceAudioFileWriter) { TDebug.out("< input file type is not supported."); } return null; } AudioFormat.Encoding inputEncoding = inputFormat.getEncoding(); if ((inputEncoding.equals(PCM_SIGNED) || inputEncoding.equals(PCM_UNSIGNED)) && inputFormat.getSampleSizeInBits() == 8) { AudioFormat outputFormat = convertFormat(inputFormat, true, false); if (TDebug.TraceAudioFileWriter) { TDebug.out("trying output format: " + outputFormat); } if (isAudioFormatSupportedImpl(outputFormat, fileType)) { if (TDebug.TraceAudioFileWriter) { TDebug.out("< ... succeeded"); } return outputFormat; } //$$fb 2000-08-16: added trial of other endianness for 8bit. We try harder ! outputFormat = convertFormat(inputFormat, false, true); if (TDebug.TraceAudioFileWriter) { TDebug.out("trying output format: " + outputFormat); } if (isAudioFormatSupportedImpl(outputFormat, fileType)) { if (TDebug.TraceAudioFileWriter) { TDebug.out("< ... succeeded"); } return outputFormat; } outputFormat = convertFormat(inputFormat, true, true); if (TDebug.TraceAudioFileWriter) { TDebug.out("trying output format: " + outputFormat); } if (isAudioFormatSupportedImpl(outputFormat, fileType)) { if (TDebug.TraceAudioFileWriter) { TDebug.out("< ... succeeded"); } return outputFormat; } if (TDebug.TraceAudioFileWriter) { TDebug.out("< ... failed"); } return null; } else if (inputEncoding.equals(PCM_SIGNED) && (inputFormat.getSampleSizeInBits() == 16 || inputFormat.getSampleSizeInBits() == 24 || inputFormat.getSampleSizeInBits() == 32) ) { // TODO: possible to allow all sample sized > 8 bit? // $$ fb: don't think that this is necessary. Well, let's talk about that in 5 years :) AudioFormat outputFormat = convertFormat(inputFormat, false, true); if (TDebug.TraceAudioFileWriter) { TDebug.out("trying output format: " + outputFormat); } if (isAudioFormatSupportedImpl(outputFormat, fileType)) { if (TDebug.TraceAudioFileWriter) { TDebug.out("< ... succeeded"); } return outputFormat; } else { if (TDebug.TraceAudioFileWriter) { TDebug.out("< ... failed"); } return null; } } else { if (TDebug.TraceAudioFileWriter) { TDebug.out("< ... failed"); } return null; } } // $$fb 2000-08-16: added convenience method private AudioFormat convertFormat(AudioFormat format, boolean changeSign, boolean changeEndian) { AudioFormat.Encoding enc=PCM_SIGNED; if (format.getEncoding().equals(PCM_UNSIGNED)!=changeSign) { enc=PCM_UNSIGNED; } return new AudioFormat( enc, format.getSampleRate(), format.getSampleSizeInBits(), format.getChannels(), format.getFrameSize(), format.getFrameRate(), format.isBigEndian() ^ changeEndian); }}/*** TAudioFileWriter.java ***/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -