Skip to content

Commit

Permalink
added stop and is_speaking to SpeechSynthesis
Browse files Browse the repository at this point in the history
  • Loading branch information
dennisppaul committed Nov 28, 2024
1 parent 3e84c72 commit 732f317
Show file tree
Hide file tree
Showing 12 changed files with 194 additions and 58 deletions.
Binary file modified lib/wellen.jar
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ import wellen.dsp.*;
/*
* this example demonstrate how to use a vocoder with SAM. see the vocoder example for further explanation.
*/
Vocoder mVocoder;
Vocoder mVocoder;
Wavetable mVocoderCarrierOsc;
SAM mSAM;
SAM mSAM;
void settings() {
size(640, 480);
}
Expand All @@ -19,17 +19,17 @@ void setup() {
mVocoder = new Vocoder(24, 4, Wellen.DEFAULT_SAMPLING_RATE, 1);
mVocoder.set_volume(8);
mSAM = new SAM();
mSAM.set_speed(60);
DSP.start(this, 1);
Beat.start(this, 140);
Beat.start(this, 25);
}
void draw() {
background(255);
stroke(0);
final int mBufferSize = DSP.get_buffer_size();
DSP.draw_buffers(g, width, height);
}
void beat(int beatCount) {
mSAM.say("hello");
mSAM.say("Harder, Better, Faster, Stronger");
}
void mouseMoved() {
mVocoder.set_formant_shift(map(mouseX, 0, width, 0.25f, 2.5f));
Expand All @@ -51,7 +51,7 @@ void keyPressed() {
}
void audioblock(float[] output_signal) {
for (int i = 0; i < output_signal.length; i++) {
float mCarrier = mVocoderCarrierOsc.output();
float mCarrier = mVocoderCarrierOsc.output();
float mModulator = mSAM.output() * 0.5f;
output_signal[i] = mVocoder.process(mCarrier, mModulator);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,26 +4,32 @@ import wellen.dsp.*;
/*
* this example demonstrates how to use the built-in speech synthesis engine ( macOS only ).
*/
int mBeatCount;
int mBeatCount;
SpeechSynthesis mSpeech;
String[] mWords;
String[] mWords;
void settings() {
size(640, 480);
}
void setup() {
String mText = "I know not by what power I am made bold, Nor how it may concern my modesty, In such a " +
"presence here to plead" + " my thoughts; But I beseech your grace that I may know The worst that " + "may" + " " + "befall me in " + "this case, If I refuse to " + "wed Demetrius.";
"presence here to plead my thoughts; But I beseech your grace that I may know The worst that " +
"may befall me in this case, If I refuse to wed Demetrius.";
mWords = split(mText, ' ');
printArray(SpeechSynthesis.list());
mSpeech = new SpeechSynthesis();
mSpeech.blocking(true);
mSpeech.say("Daniel", "A Midsummer Night's Dream Act 1 Scene 1");
mSpeech.blocking(false);
Beat.start(this, 140);
Beat.start(this, 80);
}
void draw() {
background(255);
noStroke();
fill(0);
float mScale = (mBeatCount % 32) * 0.025f + 0.25f;
if (mSpeech.is_speaking()) {
mScale *= 1 + random(0.05f);
}
ellipse(width * 0.5f, height * 0.5f, width * mScale, width * mScale);
}
void beat(int beatCount) {
Expand Down
Binary file modified processing-library/wellen/library/wellen.jar
Binary file not shown.
16 changes: 14 additions & 2 deletions processing-library/wellen/src/wellen/MidiOut.java
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,12 @@ public MidiOut(int pMidiOutputDevice) {
mMidiOut = find(pMidiOutputDevice);
}

// public static String[] availableOutputs() {
// }

public static String[] availableOutputs() {
ArrayList<String> mMidiOutputs = new ArrayList<>();
MidiDevice.Info[] mInfos = MidiSystem.getMidiDeviceInfo();
MidiDevice.Info[] mInfos = MidiSystem.getMidiDeviceInfo();
for (MidiDevice.Info mInfo : mInfos) {
try {
MidiDevice mDevice = MidiSystem.getMidiDevice(mInfo);
Expand All @@ -62,6 +65,9 @@ public static String[] availableOutputs() {
return mMidiOutputs.toArray(mMidiOutputsStr);
}

// public void sendNoteOn(int channel, int pitch, int velocity) {
// }

public void sendNoteOn(int channel, int pitch, int velocity) {
ShortMessage message = new ShortMessage();
try {
Expand All @@ -75,6 +81,9 @@ public void sendNoteOn(int channel, int pitch, int velocity) {
}
}

// public void sendControllerChange(int channel, int number, int value) {
// }

public void sendControllerChange(int channel, int number, int value) {
ShortMessage message = new ShortMessage();
try {
Expand All @@ -88,6 +97,9 @@ public void sendControllerChange(int channel, int number, int value) {
}
}

// public void sendNoteOff(int channel, int pitch, int velocity) {
// }

public void sendNoteOff(int channel, int pitch, int velocity) {
ShortMessage message = new ShortMessage();
try {
Expand Down Expand Up @@ -148,7 +160,7 @@ private Receiver find(String pMidiOutputDevice) {

private Receiver find(int pMidiOutputDeviceID) {
MidiDevice.Info[] mInfos = MidiSystem.getMidiDeviceInfo();
MidiDevice.Info mInfo = mInfos[pMidiOutputDeviceID];
MidiDevice.Info mInfo = mInfos[pMidiOutputDeviceID];
try {
MidiDevice mDevice = MidiSystem.getMidiDevice(mInfo);
if (mDevice.getMaxReceivers() != 0) {
Expand Down
65 changes: 49 additions & 16 deletions processing-library/wellen/src/wellen/SpeechSynthesis.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,33 +29,34 @@
*/
public class SpeechSynthesis {

private boolean mBlocking = true;
private String mFileName = null;
private boolean mBlocking = true;
private String mFileName = null;
private final boolean mRemoveSpecialChars;
private final boolean mVerbose;
private int mWordsPerMinute = 0;

public SpeechSynthesis() {
mVerbose = false;
mRemoveSpecialChars = true;
}
private int mWordsPerMinute = 0;
private Process mProcess;

public SpeechSynthesis(boolean verbose, boolean remove_special_characters) {
mVerbose = verbose;
mVerbose = verbose;
mRemoveSpecialChars = remove_special_characters;
mProcess = null;
}

public SpeechSynthesis() {
this(false, true);
}

public static String[] list() {
String[] mCommand = new String[]{"say", "-v", "?"};
String[] mCommand = new String[]{"say", "-v", "?"};
final Process p;
try {
p = Runtime.getRuntime().exec(mCommand);
int mExit = p.waitFor();
int mExit = p.waitFor();
BufferedReader stdInput = new BufferedReader(new InputStreamReader(p.getInputStream()));
BufferedReader error = new BufferedReader(new InputStreamReader(p.getErrorStream()));
BufferedReader error = new BufferedReader(new InputStreamReader(p.getErrorStream()));

ArrayList<String> mVoices = new ArrayList<>();
String s;
String s;
while ((s = stdInput.readLine()) != null) {
String[] mNames = s.split(" ");
mVoices.add(mNames[0]);
Expand All @@ -75,7 +76,7 @@ public void say(String pVoice, String pMessage, boolean pBlocking, int pWordsPer
}
try {
if (mRemoveSpecialChars) {
final String[] searchList = {"ƒ", "‰", "÷", "ˆ", "‹", "¸", "fl"};
final String[] searchList = {"ƒ", "‰", "÷", "ˆ", "‹", "¸", "fl"};
final String[] replaceList = {"Ae", "ae", "Oe", "oe", "Ue", "ue", "sz"};
for (int i = 0; i < replaceList.length; i++) {
pMessage = pMessage.replace(searchList[i], replaceList[i]);
Expand All @@ -97,18 +98,50 @@ public void say(String pVoice, String pMessage, boolean pBlocking, int pWordsPer
}
System.out.println();
}
final Process p = Runtime.getRuntime().exec(mCommand);
mProcess = Runtime.getRuntime().exec(mCommand);
if (pBlocking) {
int mExit = p.waitFor();
int mExit = mProcess.waitFor();
if (mVerbose) {
System.out.println("+++ exit value: " + mExit);
}
} else {
new Thread(() -> {
try {
int mExit = mProcess.waitFor();
mProcess = null;
if (mVerbose) {
System.out.println("+++ exit value: " + mExit);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
}
} catch (Exception e) {
e.printStackTrace();
}
}

public boolean is_speaking() {
if (mProcess == null) {
return false;
}
return mProcess.isAlive();
}

public void stop() {
if (mProcess == null) {
return;
}
if (mProcess.isAlive()) {
mProcess.destroy();
if (mProcess.isAlive()) {
mProcess.destroyForcibly();
}
}
mProcess = null;
}

public void blocking(boolean pMakeBlocking) {
mBlocking = pMakeBlocking;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ public class ExampleDSP25VocoderSAM extends PApplet {
* this example demonstrate how to use a vocoder with SAM. see the vocoder example for further explanation.
*/

private Vocoder mVocoder;
private Vocoder mVocoder;
private Wavetable mVocoderCarrierOsc;
private SAM mSAM;
private SAM mSAM;

public void settings() {
size(640, 480);
Expand All @@ -34,20 +34,20 @@ public void setup() {
mVocoder.set_volume(8);

mSAM = new SAM();
mSAM.set_speed(60);

DSP.start(this, 1);
Beat.start(this, 140);
Beat.start(this, 25);
}

public void draw() {
background(255);
stroke(0);
final int mBufferSize = DSP.get_buffer_size();
DSP.draw_buffers(g, width, height);
}

public void beat(int beatCount) {
mSAM.say("hello");
mSAM.say("Harder, Better, Faster, Stronger");
}

public void mouseMoved() {
Expand All @@ -72,7 +72,7 @@ public void keyPressed() {

public void audioblock(float[] output_signal) {
for (int i = 0; i < output_signal.length; i++) {
float mCarrier = mVocoderCarrierOsc.output();
float mCarrier = mVocoderCarrierOsc.output();
float mModulator = mSAM.output() * 0.5f;
output_signal[i] = mVocoder.process(mCarrier, mModulator);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,30 +10,36 @@ public class ExampleExternal06SpeechSynthesis extends PApplet {
* this example demonstrates how to use the built-in speech synthesis engine ( macOS only ).
*/

private int mBeatCount;
private int mBeatCount;
private SpeechSynthesis mSpeech;
private String[] mWords;
private String[] mWords;

public void settings() {
size(640, 480);
}

public void setup() {
String mText = "I know not by what power I am made bold, Nor how it may concern my modesty, In such a " +
"presence here to plead" + " my thoughts; But I beseech your grace that I may know The worst that " + "may" + " " + "befall me in " + "this case, If I refuse to " + "wed Demetrius.";
"presence here to plead my thoughts; But I beseech your grace that I may know The worst that " +
"may befall me in this case, If I refuse to wed Demetrius.";
mWords = split(mText, ' ');
printArray(SpeechSynthesis.list());
mSpeech = new SpeechSynthesis();
mSpeech.blocking(true);
mSpeech.say("Daniel", "A Midsummer Night's Dream Act 1 Scene 1");
mSpeech.blocking(false);

Beat.start(this, 140);
Beat.start(this, 80);
}

public void draw() {
background(255);
noStroke();
fill(0);
float mScale = (mBeatCount % 32) * 0.025f + 0.25f;
if (mSpeech.is_speaking()) {
mScale *= 1 + random(0.05f);
}
ellipse(width * 0.5f, height * 0.5f, width * mScale, width * mScale);
}

Expand Down
Loading

0 comments on commit 732f317

Please sign in to comment.