/******************************************************************************
* *
* Copyright (c) 1999-2003 Wimba S.A., All Rights Reserved. *
* *
* COPYRIGHT: *
* This software is the property of Wimba S.A. *
* This software is redistributed under the Xiph.org variant of *
* the BSD license. *
* Redistribution and use in source and binary forms, with or without *
* modification, are permitted provided that the following conditions *
* are met: *
* - Redistributions of source code must retain the above copyright *
* notice, this list of conditions and the following disclaimer. *
* - Redistributions in binary form must reproduce the above copyright *
* notice, this list of conditions and the following disclaimer in the *
* documentation and/or other materials provided with the distribution. *
* - Neither the name of Wimba, the Xiph.org Foundation nor the names of *
* its contributors may be used to endorse or promote products derived *
* from this software without specific prior written permission. *
* *
* WARRANTIES: *
* This software is made available by the authors in the hope *
* that it will be useful, but without any warranty. *
* Wimba S.A. is not liable for any consequence related to the *
* use of the provided software. *
* *
* Class: SpeexAudioFileWriter.java *
* *
* Author: Marc GIMPEL *
* *
* Date: 12th July 2003 *
* *
******************************************************************************/
/* $Id: SpeexAudioFileWriter.java,v 1.3 2005/02/11 12:54:05 mgimpel Exp $ */
package org.xiph.speex.spi;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.io.FileOutputStream;
import javax.sound.sampled.AudioFileFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.spi.AudioFileWriter;
/**
* Provider for Speex audio file writing services.
* This implementation can write Speex audio files from an audio stream.
*
* @author Marc Gimpel, Wimba S.A. (mgimpel@horizonwimba.com)
* @version $Revision: 1.3 $
*/
public class SpeexAudioFileWriter
extends AudioFileWriter
{
/** */
public static final AudioFileFormat.Type[] NO_FORMAT = {};
/** */
public static final AudioFileFormat.Type[] SPEEX_FORMAT = {SpeexFileFormatType.SPEEX};
/**
* Obtains the file types for which file writing support is provided by this audio file writer.
* @return array of file types. If no file types are supported, an array of length 0 is returned.
*/
public AudioFileFormat.Type[] getAudioFileTypes()
{
return SPEEX_FORMAT;
}
/**
* Obtains the file types that this audio file writer can write from the
* audio input stream specified.
* @param stream - the audio input stream for which audio file type support
* is queried.
* @return array of file types. If no file types are supported, an array of
* length 0 is returned.
*/
public AudioFileFormat.Type[] getAudioFileTypes(final AudioInputStream stream)
{
if (stream.getFormat().getEncoding() instanceof SpeexEncoding) {
return SPEEX_FORMAT;
}
else {
return NO_FORMAT;
}
}
/**
* Writes a stream of bytes representing an audio file of the file type
* indicated to the output stream provided. Some file types require that the
* length be written into the file header, and cannot be written from start
* to finish unless the length is known in advance.
* An attempt to write such a file type will fail with an IOException if the
* length in the audio file format is AudioSystem.NOT_SPECIFIED.
* @param stream - the audio input stream containing audio data to be written
* to the output stream.
* @param fileType - file type to be written to the output stream.
* @param out - stream to which the file data should be written.
* @return the number of bytes written to the output stream.
* @exception IOException - if an I/O exception occurs.
* @exception IllegalArgumentException - if the file type is not supported by the system.
* @see #isFileTypeSupported(AudioFileFormat.Type, AudioInputStream)
* @see #getAudioFileTypes()
*/
public int write(final AudioInputStream stream,
final AudioFileFormat.Type fileType,
final OutputStream out)
throws IOException
{
AudioFileFormat.Type[] formats = getAudioFileTypes(stream);
if (formats != null && formats.length > 0) {
return write(stream, out);
}
else {
throw new IllegalArgumentException("cannot write given file type");
}
}
/**
* Writes a stream of bytes representing an audio file of the file format
* indicated to the external file provided.
* @param stream - the audio input stream containing audio data to be written
* to the file.
* @param fileType - file type to be written to the file.
* @param out - external file to which the file data should be written.
* @return the number of bytes written to the file.
* @exception IOException - if an I/O exception occurs.
* @exception IllegalArgumentException - if the file format is not supported by the system
* @see #isFileTypeSupported(javax.sound.sampled.AudioFileFormat.Type)
* @see #getAudioFileTypes()
*/
public int write(final AudioInputStream stream,
final AudioFileFormat.Type fileType,
final File out)
throws IOException
{
AudioFileFormat.Type[] formats = getAudioFileTypes(stream);
if (formats != null && formats.length > 0) {
FileOutputStream fos = new FileOutputStream(out);
return write(stream, fos);
}
else {
throw new IllegalArgumentException("cannot write given file type");
}
}
/**
* Writes a stream of bytes representing an audio file of the file type
* indicated to the output stream provided.
* @param stream - the audio input stream containing audio data to be written
* to the output stream.
* @param out - stream to which the file data should be written.
* @return the number of bytes written to the output stream.
* @exception IOException - if an I/O exception occurs.
*/
private int write(final AudioInputStream stream,
final OutputStream out)
throws IOException
{
byte[] data = new byte[2048];
int read = 0;
int temp;
while ((temp = stream.read(data, 0, 2048)) > 0) {
out.write(data, 0, temp);
read += temp;
}
/*
According to jsresources.org, the write() method is supposed to close the
File or FileOutputStream on completion.
Without it, people passing in a File parameter are not able to close the
file on their own, and hence can't delete the audio file (especially on
FAT32 systems), since it's still technically open.
*/
out.flush();
out.close();
return read;
}
}