/*
* SequenceAudioInputStream.java
*
* This file is part of jsresources.org
*/
/*
* Portions Copyright 2006 DFKI GmbH.
* Portions Copyright (c) 1999 - 2001 by Matthias Pfisterer
* All rights reserved.
*
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package marytts.util.data.audio;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
public class SequenceAudioInputStream extends AudioInputStream {
protected List<AudioInputStream> m_audioInputStreamList;
protected int m_nCurrentStream;
public SequenceAudioInputStream(AudioFormat audioFormat, Collection<AudioInputStream> audioInputStreams) {
super(new ByteArrayInputStream(new byte[0]), audioFormat, AudioSystem.NOT_SPECIFIED);
m_audioInputStreamList = new ArrayList<AudioInputStream>(audioInputStreams);
m_nCurrentStream = 0;
// correct frameLength if possible:
Iterator<AudioInputStream> streamIterator = m_audioInputStreamList.iterator();
frameLength = 0;
while (streamIterator.hasNext()) {
AudioInputStream stream = streamIterator.next();
long lLength = stream.getFrameLength();
if (lLength == AudioSystem.NOT_SPECIFIED) {
frameLength = AudioSystem.NOT_SPECIFIED;
break;
} else {
frameLength += lLength;
}
}
}
private AudioInputStream getCurrentStream() {
return m_audioInputStreamList.get(m_nCurrentStream);
}
private boolean advanceStream() {
m_nCurrentStream++;
boolean bAnotherStreamAvailable = (m_nCurrentStream < m_audioInputStreamList.size());
return bAnotherStreamAvailable;
}
public int read() throws IOException {
AudioInputStream stream = getCurrentStream();
int nByte = stream.read();
if (nByte == -1) {
/*
* The end of the current stream has been signaled. We try to advance to the next stream.
*/
boolean bAnotherStreamAvailable = advanceStream();
if (bAnotherStreamAvailable) {
/*
* There is another stream. We recurse into this method to read from it.
*/
return read();
} else {
/*
* No more data. We signal EOF.
*/
return -1;
}
} else {
/*
* The most common case: We return the byte.
*/
return nByte;
}
}
public int read(byte[] abData, int nOffset, int nLength) throws IOException {
AudioInputStream stream = getCurrentStream();
int nBytesRead = stream.read(abData, nOffset, nLength);
if (nBytesRead == -1) {
/*
* The end of the current stream has been signaled. We try to advance to the next stream.
*/
boolean bAnotherStreamAvailable = advanceStream();
if (bAnotherStreamAvailable) {
/*
* There is another stream. We recurse into this method to read from it.
*/
return read(abData, nOffset, nLength);
} else {
/*
* No more data. We signal EOF.
*/
return -1;
}
} else {
/*
* The most common case: We return the length.
*/
return nBytesRead;
}
}
public long skip(long lLength) throws IOException {
throw new IOException("skip() is not implemented in class SequenceInputStream. Mail if you need this feature.");
}
public int available() throws IOException {
return getCurrentStream().available();
}
public void close() throws IOException {
// TODO: should we close all streams in the list?
}
public void mark(int nReadLimit) {
throw new RuntimeException("mark() is not implemented in class SequenceInputStream. Mail if you need this feature.");
}
public void reset() throws IOException {
throw new IOException("reset() is not implemented in class SequenceInputStream. Mail if you need this feature.");
}
public boolean markSupported() {
return false;
}
}