/*
* 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.lang.*;
import java.net.*;
import java.util.concurrent.*;
import org.xiph.speex.SpeexEncoder;
import javax.sound.sampled.*;
public class StreamSender extends Thread
{
private ThreadedPacketSender.SessionInfo sessionInfo;
private TargetDataLine targetDataLine;
private ThreadedPacketSender[] packetSender;
private BlockingQueue<byte[]> blockingQueue;
private int baseByteArraySize;
private CodecInfo codecInfo;
private boolean isListenOnly = false;
private boolean endFlag = false;
public static class CodecInfo
{
public AudioFormat format;
public int mode;
public int quality;
public boolean vbr;
public int countFrames;
public CodecInfo(AudioFormat format, int mode, int quality, boolean vbr, int countFrames)
{
this.format = format;
this.mode = mode;
this.quality = quality;
this.vbr = vbr;
this.countFrames = countFrames;
}
}
public StreamSender(ThreadedPacketSender.SessionInfo sessionInfo, TargetDataLine targetDataLine, CodecInfo codecInfo) throws LineUnavailableException
{
this.blockingQueue = new LinkedBlockingQueue<byte[]>(16);
packetSender = new ThreadedPacketSender[1];
for(int i=0; i < packetSender.length; ++i) {
packetSender[i] = new ThreadedPacketSender(sessionInfo, codecInfo, blockingQueue);
}
this.codecInfo = codecInfo;
// DataLine
this.targetDataLine = targetDataLine;
// Sound buffer
baseByteArraySize = packetSender[0].getBaseArraySize();
}
public int getDecodeBufferSize()
{
return baseByteArraySize * codecInfo.countFrames;
}
public void setListenOnly(boolean flag)
{
if(flag != isListenOnly && targetDataLine != null) {
if(flag) {
targetDataLine.stop();
} else {
targetDataLine.flush();
targetDataLine.start();
}
}
isListenOnly = flag;
}
public void end()
{
endFlag = true;
}
public void run()
{
for(ThreadedPacketSender s : packetSender) {
s.start();
}
try {
while (!endFlag) {
if(isListenOnly) {
Thread.sleep(500);
byte[] zero = new byte[0];
blockingQueue.put(zero);
} else {
// Input voice data
byte[] soundBuffer = new byte[baseByteArraySize * codecInfo.countFrames];
targetDataLine.read(soundBuffer, 0, baseByteArraySize);
for (int i = 1; i < codecInfo.countFrames; i++) {
targetDataLine.read(soundBuffer, baseByteArraySize * i, baseByteArraySize);
}
// put
blockingQueue.put(soundBuffer);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}