login

online now

We have 56 guests and no members online

search

 
Welcome, Guest
Username: Password: Remember me
  • Page:
  • 1

TOPIC: Controlling GinSing Functions via Sensor Input

Controlling GinSing Functions via Sensor Input 4 years 7 months ago #408

I just can't keep away..

But I know people do this all the time so this should be easy I hope. I'd like to control various GinSIng functions programatically, the easiest example being the classic sensor input being used to set an oscillator frequency. If it was a simple integer value it'd be easy, eg:
thisPitch = analogRead(0); // read sensor input, and do some mapping if necessary to bring into range
s->setFrequency ( OSC_1 , thisPitch );

However GinSing would like a different variable type, eg '1000.0f' for 1000Hz. What's the best way to do this?

Similarly, setAmplitude() wants values between 0.0f nd 1.0f.

Finally, I'd like to be able to change variables such as the waveform type, something like:
s->setWaveform  ( OSC_1 , waveType );

where waveType has previously been assigned the value of SINE, TRIANGLE etc. I know I could do this using If..then or Case, but I'd prefer to do it via the variables as it gives me much more flexibility. For example, setting up an array with the various waveform types and then setting the waveform by the appropriate array index would be perfect.

Or if there are examples of this type of thing out there (I did look, honest!) just point me at them. Thanks, Clive
Last Edit: 4 years 6 months ago by administrator.
The administrator has disabled public write access.

Re: Controlling GinSing Functions via Sensor Input 4 years 7 months ago #410

Sure, this is easy enough. Most functions have both a floating point world unit function and a relative integer unit specification. If you look in GinSingSynth.h, you'll see these:

void setFrequency ( GSSynthOsc oscillator , float freqHz ); // set the frequency (Hz) for an oscillator
void setFreqVal ( GSSynthOsc oscillator , ulong freqVal ); // set the frequency value ( see above )

In the case of analogRead(), you'll get a value from 0 to 1023. How you want to map that into frequency depends on the frequency range you want to map it into. If you wanted to use the fullest possible range, you could say:

int thisPitch = analogRead(0);
float thisFreq = thisPitch * 7182.448f;
s->setFrequency ( thisFreq );

Of course you may want a min and max. For example min = 100 Hz, max = 500 Hz:

float thisFreq = 100.0f + 400.0f + ( thisPitch ) / (float) 400.0f;

If you want to do it all as an integer, you could use the integer range as described in GinSingSynth.h:

// To obtain the maximum possible frequency resolution, you may specify the frequency as a 4 byte unsigned integer via the setFreqVal() method.
// The conversion from integer to frequency is as follows:
//
// frequency (Hz) = freqInt * 0.0009313226 , so for example A 440.0 Hz = 440.0 / 0.009313226 = 427446
// frequency can range from 0.0009 Hz ( 1 ) to 7,182.448 Hz ( 7712094 )

The same allies for Amplitude. For example max amplitude range would map:

int anVal = analogRead(0);
float volume = (float) anVal / 1023.0f // map 0.0 - 1.0
s->setAmplitude ( volume );

or as analog

s->setAmplitude ( anVal >> 2 ); // use the top 8 bits of analog

The setWaveform can be done, but the selection would be based on some selection criteria. For example, to select among 4 waveforms based on analog value:

int waveSel = 4 * analogRead(0) / 1023;
GSWaveType waveType; // defined in GinSingDefs.h

switch( waveType ) {
case 0 : waveType = SINE; break;
case 1 : waveType = TRIANGLE; break;
case 2 : waveType = NOISE; break;
}

s->setWaveForm ( OSC_1 , waveType );

One caveat: for the sake of speed I have not verified the code here will compile or work, but if you have any problems just report back here and I can test it in the IDE. Hopefully this just gets you the idea on how to do it. In particular take a look at GinSingDefs.h and GinSingSynth.h to help guide you through the syntax.
The administrator has disabled public write access.

Re: Controlling GinSing Functions via Sensor Input 4 years 7 months ago #411

Thanks for the excellent mini-tutorial, exactly what I needed. Looking in the header files is a good idea too. In a perfect world I'd like to be able to set waveform etc using an array rather than switch..case or if...then. So something like:
char* waves[]={"SINE", "TRIANGLE", "PULSE", "NOISE"};

int waveSel = 4 * analogRead(0) / 1023;
String waveType = waves[waveSel];  //select waveform based on analog input

s->setWaveform  ( OSC_1 , waveType );

Is an approach like this possible, or does it break the fundamental laws of the universe? Not a biggie if it's too hard, would just be a useful technique to have in the arsenal.
The administrator has disabled public write access.

Re: Controlling GinSing Functions via Sensor Input 4 years 7 months ago #412

You should be able to use an array, but rather than using a char* array of strings, you should use an arraray of GSWaveTypes, i.e.:

GSWaveType waves[] = { SINE , TRIANGLE, ... }

GSWaveType waveType = waves [ waveSel ];
The administrator has disabled public write access.
The following user(s) said Thank You: Charlie McF

Re: Controlling GinSing Functions via Sensor Input 4 years 7 months ago #415

Perfect, thanks!
The administrator has disabled public write access.
  • Page:
  • 1
Time to create page: 0.211 seconds