/*
* festivoice
*
* Copyright 2009 FURUHASHI Sadayuki, KASHIHARA Shuzo, SHIBATA Yasuharu
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.festivoice;
import java.util.*;
import java.lang.*;
import java.net.*;
import java.util.concurrent.*;
import javax.sound.sampled.*;
import org.xiph.speex.SpeexDecoder;
public class ThreadedLineOut extends Thread
{
private SourceDataLine line;
private CodecInfo codecInfo;
private BlockingQueue<byte[]> queue;
private SpeexDecoder decoder;
private byte[] decodedData;
private boolean endFlag = false;
public static class CodecInfo
{
public AudioFormat format;
public int mode;
public int decodedSize;
public int countFrames;
public CodecInfo(AudioFormat format, int mode, int decodedSize, int countFrames)
{
this.format = format;
this.mode = mode;
this.decodedSize = decodedSize;
this.countFrames = countFrames;
}
}
public ThreadedLineOut(DataLine.Info info, CodecInfo codecInfo) throws Exception
{
this.codecInfo = codecInfo;
line = (SourceDataLine)AudioSystem.getLine(info);
line.open(codecInfo.format);
decoder = new SpeexDecoder();
decoder.init(codecInfo.mode, (int)codecInfo.format.getSampleRate(), codecInfo.format.getChannels(), false);
queue = new LinkedBlockingQueue<byte[]>(16);
decodedData = new byte[codecInfo.decodedSize];
endFlag = false;
}
public void put(byte[] buffer) throws Exception
{
queue.put(buffer);
}
public void run()
{
line.start();
try {
while(!endFlag) {
byte[] buffer = queue.take();
if(buffer.length == 0) {
// listen only packet
continue;
}
decoder.processData(buffer, 0, buffer.length);
for (int i = 1; i < codecInfo.countFrames; i++) {
decoder.processData(false);
}
int decsize = decoder.getProcessedData(decodedData, 0);
line.write(decodedData, 0, decsize);
}
} catch (Exception e) {
System.out.println("line out error: "+e);
e.printStackTrace();
}
line.stop();
}
public void end()
{
endFlag = true;
}
}