package org.vocobox.apps.csv2synth;
import java.io.File;
import java.io.IOException;
import javax.sound.sampled.UnsupportedAudioFileException;
import net.bluecow.spectro.PlayerThread;
import org.vocobox.events.policies.MuteNoConfidencePolicy;
import org.vocobox.events.policies.SoundEventPolicy;
import org.vocobox.model.song.Song;
import org.vocobox.model.synth.MonitorSettings;
import org.vocobox.model.synth.VocoSynth;
import org.vocobox.model.voice.analysis.VocoParseFileAndFFT;
import org.vocobox.synth.jsyn.circuits.JsynCircuitSynth;
import org.vocobox.ui.charts.synth.SynthMonitorCharts;
import org.vocobox.ui.toolkit.transport.TransportPanel;
import org.vocobox.ui.toolkit.transport.TransportPanel.On;
/**
* Control a synthetizer using CSV files : pitch.csv and envelope.csv, computed by
* external software.
*/
public class VocoboxControllerCsv {
public static void main(String[] args) throws IOException, UnsupportedAudioFileException {
VocoboxControllerCsv controller = new VocoboxControllerCsv();
String analysisRoot = "data/analyses/";
String analysisName = "doremi";
String wavFile = "data/sound/" + analysisName + ".wav";
controller.muteWinTime = 0.10f;// good for "piano" 0.15 // good for "dp2" 0.02
controller.loadAnalysis(analysisRoot, analysisName, wavFile);
}
/* ######################################################## */
// ui
protected VocoboxAppCsv app;
protected VocoboxPanelsCsv panels;
protected SynthMonitorCharts monitor;
// model
protected VocoSynth synth;
protected Song song;
protected VocoParseFileAndFFT pitchAnalysis;
protected SoundEventPolicy soundEventPolicy;
// parameters
protected float muteWinTime = -1f; // no mute based on confidence
protected MonitorSettings monitorSettings;
public VocoboxControllerCsv() {
this(new VocoboxAppCsv(), new JsynCircuitSynth());
}
public VocoboxControllerCsv(VocoSynth synth) {
this(new VocoboxAppCsv(), synth);
}
public VocoboxControllerCsv(VocoboxAppCsv app, VocoSynth synth) {
this.app = app;
this.synth = synth;
this.monitorSettings = new MonitorSettings();
this.monitorSettings.timeMax = 20;
}
/* EXTERNAL ANALYSIS FILES */
public void loadAnalysis(String analysisRoot, String analysisName, String waveFile) throws IOException, UnsupportedAudioFileException {
loadAnalysisData(analysisRoot, analysisName, waveFile);
loadAnalysisUI();
}
public void loadAnalysisData(String analysisRoot, String analysisName, String waveFile) throws UnsupportedAudioFileException, IOException {
pitchAnalysis = new VocoParseFileAndFFT(new File(waveFile));
song = new Song(analysisRoot, analysisName);
}
public void loadAnalysisUI() throws IOException {
panels = new VocoboxPanelsCsv(synth, song, pitchAnalysis, monitorSettings);
panels.setInputControl(new TransportPanel(new On() {
@Override
public void play() {
try {
VocoboxControllerCsv.this.play();
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void stop() {
VocoboxControllerCsv.this.stop();
panels.getSynthMonitors().clear();
}
}));
app.layout(panels);
monitor = panels.getSynthMonitors();
panels.getSynthMonitors().pitchCursorAnnotation.setWidth(muteWinTime);
}
/** Play song with synthetizer and source file at the same time */
public void play() throws Exception {
playAnalysisSource();
playAnalysisSynthSong();
}
public void playAnalysisSource() {
PlayerThread player = panels.getAudioSourceCharts().getClipPlayerThread();
player.setPlaybackPosition(0);
player.startPlaying();
}
public void playAnalysisSynthSong() throws Exception {
preplayAnalysis();
song.play(synth);
}
/**
* Preprocess /filters sound events that would produce inappropriate synth
* controls (uncertain pitch variations, etc)
*/
public void preplayAnalysis() {
soundEventPolicy = new MuteNoConfidencePolicy(monitor, muteWinTime);
song.setSoundEventPolicy(soundEventPolicy);
song.preprocess();
}
public void stop() {
song.stop();
synth.off();
panels.getAudioSourceCharts().getClipPlayerThread().stopPlaying();
}
}