/*
* Mobicents, Communications Middleware
*
* Copyright (c) 2008, Red Hat Middleware LLC or third-party
* contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Middleware LLC.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* 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 Lesser General Public License
* for more details.
*
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
*
* Boston, MA 02110-1301 USA
*/
package org.mobicents.media.server.impl.resource.audio;
import javax.sound.sampled.AudioFormat;
import org.mobicents.media.Buffer;
import org.mobicents.media.Format;
import org.mobicents.media.server.impl.AbstractSource;
import org.mobicents.media.server.spi.dsp.Codec;
import org.mobicents.media.server.spi.resource.TTSEngine;
import com.sun.speech.freetts.Voice;
import com.sun.speech.freetts.VoiceManager;
import java.io.IOException;
import java.net.URL;
import java.net.URLConnection;
import org.mobicents.media.server.spi.events.NotifyEvent;
/**
*
* @author kulikov
*/
public class TTSEngineImpl extends AbstractSource implements TTSEngine {
private String text;
private String url;
private Format FORMATS[] = new Format[]{Codec.LINEAR_AUDIO};
private Voice voice;
private String voiceName;
private boolean isReady = false;
private int offset;
private int length;
private byte[] localBuff;
private int pSize = 320;
private long timestamp;
public TTSEngineImpl(String name) {
super(name);
}
public void setVoice(String name) {
VoiceManager voiceManager = VoiceManager.getInstance();
voice = voiceManager.getVoice(voiceName);
voice.allocate();
voice.setAudioPlayer(new TTSAudioStream());
}
public String getVoice() {
return voice != null? voice.getName() : null;
}
public void setURL(String url) {
this.url = url;
}
public String getURL() {
return url;
}
@Override
public void beforeStart() {
isReady = false;
if (url != null) {
try {
URL uri = new URL(url);
URLConnection connection = uri.openConnection();
voice.speak(connection.getInputStream());
} catch (IOException e) {
failed(NotifyEvent.START_FAILED, e);
}
} else {
voice.speak(text);
}
}
@Override
public void evolve(Buffer buffer, long timestamp, long sequenceNumber) {
if (isReady) {
buffer.setSequenceNumber(sequenceNumber);
buffer.setFormat(Codec.LINEAR_AUDIO);
buffer.setDuration(getDuration());
buffer.setTimeStamp(getSyncSource().getTimestamp());
buffer.setDiscard(false);
byte[] data = (byte[]) buffer.getData();
int len = Math.min(pSize, length - offset);
System.arraycopy(localBuff, offset, data, 0, len);
offset += len;
buffer.setOffset(0);
buffer.setLength(len);
buffer.setEOM(offset == length);
} else {
buffer.setDiscard(true);
}
}
public Format[] getFormats() {
return FORMATS;
}
public void setText(String text) {
this.text = text;
}
public String getText() {
return text;
}
private class TTSAudioStream implements com.sun.speech.freetts.audio.AudioPlayer {
private AudioFormat fmt;
private float volume;
public void setAudioFormat(AudioFormat fmt) {
this.fmt = fmt;
}
public AudioFormat getAudioFormat() {
return fmt;
}
public void pause() {
}
public void resume() {
}
public void reset() {
offset = 0;
isReady = false;
}
public boolean drain() {
return true;
}
public void begin(int size) {
localBuff = new byte[size];
}
public boolean end() {
length = offset;
offset = 0;
isReady = true;
return true;
}
public void cancel() {
}
public void close() {
}
public float getVolume() {
return volume;
}
public void setVolume(float volume) {
this.volume = volume;
}
public long getTime() {
return 0;
}
public void resetTime() {
}
public void startFirstSampleTimer() {
}
public boolean write(byte[] buff) {
return write(buff, 0, buff.length);
}
public boolean write(byte[] buff, int off, int len) {
System.arraycopy(buff, off, localBuff, offset, len);
offset += len;
return true;
}
public void showMetrics() {
}
}
}