A.M.
A.M.

Reputation: 647

JSyn, siren sound using oscillator fed/controlled/inputInto/daisy-chainedTo by another oscillator and a constant...and generating more than one sound

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

Answers (2)

A.M.
A.M.

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:

  1. An oscillator still needs to be connected to the synthesizer even if it will not be heard directly (and a line like this was missing from the sample code, probably because the sample code assumed a person had some previous sample code from the tutorial in it).
  2. An envelope oscillator should be set to a very low frequency in order for its effect to be heard.
  3. An envelope oscillator should be given an amplitude, and this needs to be on the order of the frequency being altered in order for its effect to be heard.

Upvotes: 0

philburk
philburk

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

Related Questions