Reputation: 647
I have been trying to follow the example here, but it is not working, and I have not been able to find any other sources: [ http://www.softsynth.com/jsyn/tutorial/osc_control.php ][1]
As far as I can tell, I have followed this sample code snippet exactly (except that I found out that AddUnit
changed to Add
sometime since that webpage was updated):
[...]make the frequency to waver slightly about a central frequency that is in a more useful range. We can do this by using an AddUnit to add the output of an oscillator to a constant value that we can set. We can also reduce the amplitude of the first oscillator to be within a smaller range.
AddUnit freqAdder = new AddUnit();
sineOsc1.output.connect( freqAdder.inputA ); // pass through adder
freqAdder.output.connect( sineOsc2.frequency ); // control second oscillator freq
freqAdder.inputB.set( 500.0 ); // add constant that will center us at 500 Hz
sineOsc1.amplitude.set( 100.0 ); // reduce offset to +/- 100 Hz
Thus the frequency of sineOsc2 will be sineOsc1.output plus inputB.
Can anybody see what is wrong with my code (below)? I already have a simple oscillator sound working. I just can't hear this second, more complicated sound, which is supposed to be siren-like.
It may be a problem with my coding of the siren sound, or it may just be a problem with my coding of generating two sounds. (Are 2 Synthesizers
required? I have tried it with 1 and 2 Synthesizers
.) (Are 2 lineOuts required? Other web sources say "no".)
Here is my code with 2 synthesizers
and 1 output:
(Comments in quotes are from other sample code. I only understand a little of what those comments are getting at.)
import com.jsyn.JSyn;
import com.jsyn.Synthesizer;
import com.jsyn.unitgen.Add;
import com.jsyn.unitgen.LineOut;
import com.jsyn.unitgen.SineOscillator;
[...]
com.jsyn.Synthesizer synthPCMSonification = JSyn.createSynthesizer();
com.jsyn.Synthesizer synthPCMAlarm = JSyn.createSynthesizer();
// "an instance of Synthesizer"
com.jsyn.unitgen.SineOscillator oscData = new SineOscillator();
SineOscillator oscAlarmWaverEnvelope = new SineOscillator();
SineOscillator oscAlarmComplete = new SineOscillator();
// "a unit"
com.jsyn.unitgen.LineOut oscsLineOut = new LineOut();
// "a unit"
[...]
// "start synthesis engine"
synthPCMSonification.start();
synthPCMAlarm.start();
// "build unit generators"
synthPCMSonification.add(oscData);
//synthPCM.add(oscAlarmWaverEnvelope); //TODO: Figure out if need line
synthPCMAlarm.add(oscAlarmComplete);
synthPCMSonification.add(oscsLineOut);
synthPCMAlarm.add(oscsLineOut);
oscData.frequency.set(LOWEST_FREQUENCY_C);
oscData.amplitude.set(volSonification);
//create a frequency adder for a siren-like alarm
com.jsyn.unitgen.Add oscAlarmFreqAdder = new Add(); //used to be AddUnit
//set the alarm centre frequency
alarmCentreFreq = (LOWEST_FREQUENCY_C
* Math.pow(2, OCTAVES_SPANNED_C + 1));
//This formula centres the alarm one octave
//above the threshold's sonification freqency
alarmWaverFreq = alarmCentreFreq / 10;
//This sets the waver at one tenth of the centre freq
//Unfortunately, the waver appears to need to be the
//same amount above and below the centre
//(linear, vice perceptually-linear (exponential))
System.out.println(alarmCentreFreq + "-Hz alarm centre frequency");
oscAlarmFreqAdder.inputB.set(alarmCentreFreq);
//set the alarm waver envelope
//(alarm will range between centre-waver and centre+waver)
oscAlarmWaverEnvelope.frequency.set(alarmCentreFreq / 10);
//"pass through adder" (??)
oscAlarmWaverEnvelope.output.connect(oscAlarmFreqAdder.inputA);
//(entered this with by starting to type, then hitting [Ctrl]+[Space]!)
//"control the 2nd oscillator frequency" (?)
oscAlarmFreqAdder.output.connect(oscAlarmComplete.frequency);
//set alarm volume
oscAlarmComplete.amplitude.set(volAlarm);
// "connect unit generators"
// connect oscillator to both channels of stereo player
oscAlarmComplete.output.connect(0, oscsLineOut.input, 0);
oscAlarmComplete.output.connect(0, oscsLineOut.input, 1);
// "startUnitGenerators"
// "start execution of units. JSyn 'pulls' data so the only unit
// you have to start() is the last one, in this case our LineOut"
oscsLineOut.start();
How many people out there know and use JSyn
? How about meta-oscillators
?
If you have ever connected different JSyn
parts together, or even just got it to output more than one sound at once, you know more than I do...
Upvotes: 1
Views: 869
Reputation: 647
(Note: I really wanted to just add this to the answer @philburk gave, as his answer certainly helped, but my requests to add this to his answer were rejected, so I have to give this as a separate answer. I am torn on whether I should move the 'accept' to this answer or not, though, even though this is the actual fix.)
The code in the question can be fixed by adding (or changing to, in the case of the frequency line) the following lines of code:
synthPCM.add(oscAlarmWaverEnvelope) //(this is the line I already suspected I needed)
oscAlarmWaverEnvelope.frequency.set(4.0);
oscAlarmWaverEnvelope.amplitude.set(alarmCentreFreq / 10);
...meaning:
Upvotes: 0
Reputation: 711
There are a number of things that could be improved here.
1) You created two synthesizers:
com.jsyn.Synthesizer synthPCMSonification = JSyn.createSynthesizer();
com.jsyn.Synthesizer synthPCMAlarm = JSyn.createSynthesizer();
That is only needed if you are running some synthesis in non-real-time or at a different sample rate. I highly recommend only using one synthesizer. Connecting units across synthesizers or running the same unit on both synthesizers will cause problems. I suspect that is the main error.
You can have multiple LineOut units in one synth. Or you can mix automatically by connecting multiple units to the LineOut.
2) I recommend starting with just one oscillator connected to a LineOut. After you can get that to make sound, add the modulation.
3) You can get exponential frequency (pitch) modulation using the optimized PowerOfTwo unit.
http://www.softsynth.com/jsyn/docs/javadocs/com/jsyn/unitgen/PowerOfTwo.html
Connect the LFO to a PowerOfTwo unit. Then use a Multiply unit to scale the center frequency. An LFO that goes from +1.0 to -1.0 will scale the frequency up and down an octave.
4) The tutorial uses the old JSyn API. I need to update it. Note that in the new JSyn API you rarely need an Add unit because the input ports will automatically sum any connected inputs.
5) StackOverflow is great but you can get support from the JSyn community of over 600 people by signing up for the JSyn mail list.
http://www.softsynth.com/jsyn/support/index.php
Upvotes: 1