rockbox/songdbj/org/tritonus/share/sampled/file/TAudioOutputStream.java
Michiel Van Der Kolk 9fee0ec4ca Songdb java version, source. only 1.5 compatible
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@7101 a1c6a512-1295-4272-9138-f99709370657
2005-07-11 15:42:37 +00:00

197 lines
4.5 KiB
Java

/*
* TAudioOutputStream.java
*
* This file is part of Tritonus: http://www.tritonus.org/
*/
/*
* Copyright (c) 2000 by Matthias Pfisterer
*
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as published
* by the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
/*
|<--- this code is formatted to fit into 80 columns --->|
*/
package org.tritonus.share.sampled.file;
import java.io.IOException;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioSystem;
import org.tritonus.share.TDebug;
/**
* Base class for classes implementing AudioOutputStream.
*
* @author Matthias Pfisterer
*/
public abstract class TAudioOutputStream
implements AudioOutputStream
{
private AudioFormat m_audioFormat;
private long m_lLength; // in bytes
private long m_lCalculatedLength;
private TDataOutputStream m_dataOutputStream;
private boolean m_bDoBackPatching;
private boolean m_bHeaderWritten;
protected TAudioOutputStream(AudioFormat audioFormat,
long lLength,
TDataOutputStream dataOutputStream,
boolean bDoBackPatching)
{
m_audioFormat = audioFormat;
m_lLength = lLength;
m_lCalculatedLength = 0;
m_dataOutputStream = dataOutputStream;
m_bDoBackPatching = bDoBackPatching;
m_bHeaderWritten = false;
}
public AudioFormat getFormat()
{
return m_audioFormat;
}
/** Gives length of the stream.
* This value is in bytes. It may be AudioSystem.NOT_SPECIFIED
* to express that the length is unknown.
*/
public long getLength()
{
return m_lLength;
}
/** Gives number of bytes already written.
*/
// IDEA: rename this to BytesWritten or something like that ?
public long getCalculatedLength()
{
return m_lCalculatedLength;
}
protected TDataOutputStream getDataOutputStream()
{
return m_dataOutputStream;
}
/** Writes audio data to the destination (file or output stream).
*/
// IDEA: use long?
public int write(byte[] abData, int nOffset, int nLength)
throws IOException
{
if (TDebug.TraceAudioOutputStream)
{
TDebug.out("TAudioOutputStream.write(): wanted length: " + nLength);
}
if (! m_bHeaderWritten)
{
writeHeader();
m_bHeaderWritten = true;
}
// $$fb added
// check that total writes do not exceed specified length
long lTotalLength=getLength();
if (lTotalLength!=AudioSystem.NOT_SPECIFIED && (m_lCalculatedLength+nLength)>lTotalLength) {
if (TDebug.TraceAudioOutputStream) {
TDebug.out("TAudioOutputStream.write(): requested more bytes to write than possible.");
}
nLength=(int) (lTotalLength-m_lCalculatedLength);
// sanity
if (nLength<0) {
nLength=0;
}
}
// TODO: throw an exception if nLength==0 ? (to indicate end of file ?)
if (nLength>0) {
m_dataOutputStream.write(abData, nOffset, nLength);
m_lCalculatedLength += nLength;
}
if (TDebug.TraceAudioOutputStream)
{
TDebug.out("TAudioOutputStream.write(): calculated (total) length: " + m_lCalculatedLength+" bytes = "+(m_lCalculatedLength/getFormat().getFrameSize())+" frames");
}
return nLength;
}
/** Writes the header of the audio file.
*/
protected abstract void writeHeader()
throws IOException;
/** Closes the stream.
* This does write remaining buffered data to the destination,
* backpatch the header, if necessary, and closes the destination.
*/
public void close()
throws IOException
{
if (TDebug.TraceAudioOutputStream)
{
TDebug.out("TAudioOutputStream.close(): called");
}
// flush?
if (m_bDoBackPatching)
{
if (TDebug.TraceAudioOutputStream)
{
TDebug.out("TAudioOutputStream.close(): patching header");
}
patchHeader();
}
m_dataOutputStream.close();
}
protected void patchHeader()
throws IOException
{
TDebug.out("TAudioOutputStream.patchHeader(): called");
// DO NOTHING
}
protected void setLengthFromCalculatedLength()
{
m_lLength = m_lCalculatedLength;
}
}
/*** TAudioOutputStream.java ***/