/*
SpeechDemoActor.java
(c) 2012-2016 Edward Swartz
All rights reserved. This program and the accompanying materials
are made available under the terms of the Eclipse Public License v1.0
which accompanies this distribution, and is available at
http://www.eclipse.org/legal/epl-v10.html
*/
package v9t9.engine.demos.actors;
import java.io.IOException;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import v9t9.common.demos.DemoHeader;
import v9t9.common.demos.IDemoActorProvider;
import v9t9.common.demos.IDemoEvent;
import v9t9.common.demos.IDemoHandler;
import v9t9.common.demos.IDemoPlaybackActor;
import v9t9.common.demos.IDemoPlayer;
import v9t9.common.demos.IDemoRecorder;
import v9t9.common.demos.IDemoRecordingActor;
import v9t9.common.demos.IDemoReversePlaybackActor;
import v9t9.common.hardware.ISpeechChip;
import v9t9.common.machine.IMachine;
import v9t9.common.settings.Settings;
import v9t9.common.speech.ILPCParameters;
import v9t9.common.speech.ILPCParametersListener;
import v9t9.engine.demos.events.SpeechEvent;
import v9t9.engine.speech.LPCParameters;
import v9t9.engine.speech.SpeechTMS5220;
import ejs.base.properties.IProperty;
import ejs.base.properties.IPropertyListener;
/**
* @author ejs
*
*/
public class SpeechDemoActor extends BaseDemoActor implements IDemoReversePlaybackActor {
public static class Provider implements IDemoActorProvider {
@Override
public String getEventIdentifier() {
return SpeechEvent.ID;
}
@Override
public IDemoPlaybackActor createForPlayback() {
return new SpeechDemoActor();
}
@Override
public IDemoRecordingActor createForRecording() {
return new SpeechDemoActor();
}
@Override
public IDemoReversePlaybackActor createForReversePlayback() {
return new SpeechDemoActor();
}
}
private SpeechTMS5220 speech;
private ILPCParametersListener paramsListener;
private List<ILPCParameters> currentPhraseParamsList;
private IProperty demoRate;
private IProperty talkRate;
private double origTalkRate;
private IPropertyListener demoRateListener;
private List<SpeechEvent> reversedEventsList;
private SpeechEvent lastSpeechEvent;
/* (non-Javadoc)
* @see v9t9.common.demo.IDemoActor#getEventIdentifier()
*/
@Override
public String getEventIdentifier() {
return SpeechEvent.ID;
}
/* (non-Javadoc)
* @see v9t9.common.demo.IDemoActor#setup(v9t9.common.machine.IMachine)
*/
@Override
public void setup(IMachine machine) {
this.speech = (SpeechTMS5220) machine.getSpeech();
speech.reset();
}
/* (non-Javadoc)
* @see v9t9.engine.demos.actors.BaseDemoActor#shouldRecordFor(byte[])
*/
@Override
public boolean shouldRecordFor(byte[] header) {
return DemoHeader.isV9t9jFormat(header);
}
/* (non-Javadoc)
* @see v9t9.common.demo.IDemoActor#connectForRecording(v9t9.common.demo.IDemoRecorder)
*/
@Override
public synchronized void connectForRecording(final IDemoRecorder recorder) throws IOException {
currentPhraseParamsList = new ArrayList<ILPCParameters>();
paramsListener = new ILPCParametersListener() {
@Override
public void parametersAdded(ILPCParameters params) {
// speech takes a really long time, so flush
// everything now
// try {
// recorder.flushData();
// } catch (IOException e) {
// recorder.fail(e);
// }
synchronized (SpeechDemoActor.this) {
LPCParameters copy = new LPCParameters();
copy.copyFrom((LPCParameters) params);
currentPhraseParamsList.add(copy);
}
}
};
speech.addParametersListener(paramsListener);
}
/* (non-Javadoc)
* @see v9t9.common.demo.IDemoActor#flushRecording(v9t9.common.demo.IDemoRecorder)
*/
@Override
public synchronized void flushRecording(IDemoRecorder recorder) throws IOException {
if (currentPhraseParamsList == null) return;
for (ILPCParameters params : currentPhraseParamsList) {
recorder.getOutputStream().writeEvent(
new SpeechEvent(params));
}
currentPhraseParamsList.clear();
}
/* (non-Javadoc)
* @see v9t9.common.demo.IDemoActor#disconnectFromRecording(v9t9.common.demo.IDemoRecorder)
*/
@Override
public synchronized void disconnectFromRecording(IDemoRecorder recorder) {
speech.removeParametersListener(paramsListener);
}
/* (non-Javadoc)
* @see v9t9.engine.demos.actors.BaseDemoActor#setupPlayback(v9t9.common.demo.IDemoPlayer)
*/
@Override
public void setupPlayback(final IDemoPlayer player) {
super.setupPlayback(player);
// have the talk speed match the demo speed
talkRate = Settings.get(player.getMachine(), ISpeechChip.settingTalkSpeed);
demoRate = Settings.get(player.getMachine(), IDemoHandler.settingDemoPlaybackRate);
origTalkRate = talkRate.getDouble();
if (demoRateListener == null) {
demoRateListener = new IPropertyListener() {
@Override
public void propertyChanged(IProperty property) {
talkRate.setDouble(property.getDouble());
}
};
}
demoRate.addListenerAndFire(demoRateListener);
}
/* (non-Javadoc)
* @see v9t9.common.demo.IDemoActor#executeEvent(v9t9.common.demo.IDemoPlayer, v9t9.common.demo.IDemoEvent)
*/
@Override
public void executeEvent(IDemoPlayer player, IDemoEvent event)
throws IOException {
SpeechEvent ev = (SpeechEvent) event;
LPCParameters params = (LPCParameters) ev.getParams();
speech.getLpcSpeech().frame(params, speech.getSamplesPerFrame());
}
/* (non-Javadoc)
* @see v9t9.engine.demos.actors.BaseDemoActor#cleanupPlayback(v9t9.common.demo.IDemoPlayer)
*/
@Override
public void cleanupPlayback(IDemoPlayer player) {
super.cleanupPlayback(player);
demoRate.removeListener(demoRateListener);
talkRate.setDouble(origTalkRate);
}
/* (non-Javadoc)
* @see v9t9.engine.demos.actors.BaseDemoActor#setupReversePlayback(v9t9.common.demos.IDemoPlayer)
*/
@Override
public void setupReversePlayback(IDemoPlayer player) {
reversedEventsList = new LinkedList<SpeechEvent>();
}
/* (non-Javadoc)
* @see v9t9.common.demos.IDemoReversePlaybackActor#queueEventForReversing(v9t9.common.demos.IDemoPlayer, v9t9.common.demos.IDemoEvent)
*/
@Override
public void queueEventForReversing(IDemoPlayer player, IDemoEvent event)
throws IOException {
SpeechEvent ev = (SpeechEvent) event;
if (ev.getParams().isRepeat()) {
// repeats the *next* event, but we may have lost the last
// params in the events list, so duplicate the last we know of
if (lastSpeechEvent != null)
ev = lastSpeechEvent;
}
reversedEventsList.add(0, ev);
lastSpeechEvent = ev;
}
/* (non-Javadoc)
* @see v9t9.common.demos.IDemoReversePlaybackActor#emitReversedEvents(v9t9.common.demos.IDemoPlayer)
*/
@Override
public IDemoEvent[] emitReversedEvents(IDemoPlayer player)
throws IOException {
IDemoEvent[] evs = (IDemoEvent[]) reversedEventsList.toArray(new IDemoEvent[reversedEventsList.size()]);
reversedEventsList.clear();
return evs;
}
/* (non-Javadoc)
* @see v9t9.engine.demos.actors.BaseDemoActor#cleanupReversePlayback(v9t9.common.demos.IDemoPlayer)
*/
@Override
public void cleanupReversePlayback(IDemoPlayer player) {
reversedEventsList = null;
}
}