login

online now

We have 120 guests and no members online

search

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

TOPIC: Sketch: GinSing+MIDI; CCs for extra control

Sketch: GinSing+MIDI; CCs for extra control 5 years 8 months ago #253

#include <GinSing.h>
#include <MIDI.h>

/********************************** GINSING DEFINES *******************************************/
#define rcvPin 4 // this is the pin used for receiving ( can be either 4 or 12 )
#define sndPin 3 // this is the pin used for transmitting ( can be either 3 or 11 )
#define ovfPin 2 // this is the pin used for overflow control ( can be either 2 or 10 )

GinSing GS; // create the class library from which all methods and data are accessed
GinSingSynth *my_synth; // our global pointer to the synth mode interface ( set up after initialization )
GinSingMaster *master;

byte freq_mod_A_is_active;
byte freq_mod_B_is_active;
byte amp_mod_A_is_active;
byte amp_mod_B_is_active;

/********************************* MIDI callback Functions ************************************/

void HandleNoteOn(byte channel, byte pitch, byte velocity) {

byte get_note = 0;

if ((pitch > 11) && (pitch < 108)) { // make sure the incoming note is w/in GinSing's boundaries
if ( pitch <= 23 ) { get_note = pitch-12; }
else if ( pitch <= 35 ) { get_note = pitch-8; }
else if ( pitch <= 47 ) { get_note = pitch-4; }
else if ( pitch <= 59 ) { get_note = pitch; }
else if ( pitch <= 71 ) { get_note = pitch+4; }
else if ( pitch <= 83 ) { get_note = pitch+8; }
else if ( pitch <= 95 ) { get_note = pitch+12; }
else { get_note = pitch+16; }
}// end if pitch > 11 && pitch < 108

my_synth->selectBank (BANK_A);
my_synth->setNote( OSC_1, (GSNote)get_note );
my_synth->trigger( OSC_1 );

my_synth->selectBank (BANK_B);
my_synth->setNote( OSC_1, (GSNote)get_note );
my_synth->trigger( OSC_1 );

} // end HandleNoteOn

void HandleNoteOff(byte channel, byte pitch, byte velocity) {

my_synth->selectBank (BANK_A);
my_synth->release( OSC_1 );
my_synth->selectBank (BANK_B);
my_synth->release( OSC_1 );

} // end HandleNoteOff

void HandleControlChange (byte channel, byte number, byte value){

if (number == 7) { master->setMasterAmplitudeVal(value); } // CC7 is Channel Volume in the MIDI spec

//NOTE: Control Change numbers 20-31 are "undefined" in the MIDI spec
// So I use them here to control the various GinSing features

/***************************** Main OSC Waveform Select ******************************/

if (number == 20) { // I chose CC 20 for Bank A setWaveform...
my_synth->selectBank (BANK_A);
if (value == 0) { my_synth->setWaveform ( OSC_1, SINE ); }
else if (value == 1) { my_synth->setWaveform ( OSC_1, TRIANGLE ); }
else if (value == 2) { my_synth->setWaveform ( OSC_1, SAWTOOTH ); }
else if (value == 3) { my_synth->setWaveform ( OSC_1, RAMP ); }
else if (value == 4) { my_synth->setWaveform ( OSC_1, PULSE ); }
else { my_synth->setWaveform ( OSC_1, NOISE ); }
} // if number==20

if (number == 21) { // ...and CC 21 for Bank B setWaveform
my_synth->selectBank (BANK_B);
if (value == 0) { my_synth->setWaveform ( OSC_1, SINE ); }
else if (value == 1) { my_synth->setWaveform ( OSC_1, TRIANGLE ); }
else if (value == 2) { my_synth->setWaveform ( OSC_1, SAWTOOTH ); }
else if (value == 3) { my_synth->setWaveform ( OSC_1, RAMP ); }
else if (value == 4) { my_synth->setWaveform ( OSC_1, PULSE ); }
else { my_synth->setWaveform ( OSC_1, NOISE ); }
} // if number==21

/***************************** Frequency Modulation ******************************/

if (number == 22) { // CC 22 to apply lower frequency FreqMod OSCs to Bank A; 0 to release, >0 to set
if (value){
freq_mod_A_is_active = 1;
my_synth->selectBank ( BANK_A );
if (amp_mod_A_is_active) { my_synth->setPatch ( OSC_1_TO_MIXER|OSC_3_FRQMOD_OSC_1|OSC_2_AMPMOD_OSC_1); }
else { my_synth->setPatch ( OSC_1_TO_MIXER|OSC_3_FRQMOD_OSC_1 ); }
my_synth->setFrequency ( OSC_3 , (value*2) );
my_synth->trigger ( OSC_3 );
} else {
freq_mod_A_is_active = 0;
my_synth->selectBank(BANK_A);
my_synth->release(OSC_3);
}
} // if number==22

if (number == 23) { // CC 23 to apply higher frequency FreqMod OSCs to Bank A; 0 to release, >0 to set
if (value){
freq_mod_A_is_active = 1;
my_synth->selectBank ( BANK_A );
if (amp_mod_A_is_active) { my_synth->setPatch ( OSC_1_TO_MIXER|OSC_3_FRQMOD_OSC_1|OSC_2_AMPMOD_OSC_1); }
else { my_synth->setPatch ( OSC_1_TO_MIXER|OSC_3_FRQMOD_OSC_1 ); }
my_synth->setFrequency ( OSC_3 , (value*60) );
my_synth->trigger ( OSC_3 );
} else {
freq_mod_A_is_active = 0;
my_synth->selectBank(BANK_A);
my_synth->release(OSC_3);
}
} // if number==23

if (number == 24) { // CC 24 to apply lower frequency FreqMod OSCs to Bank B; 0 to release, >0 to set
if (value){
freq_mod_B_is_active = 1;
my_synth->selectBank ( BANK_B );
if (amp_mod_B_is_active) { my_synth->setPatch ( OSC_1_TO_MIXER|OSC_3_FRQMOD_OSC_1|OSC_2_AMPMOD_OSC_1 ); }
else { my_synth->setPatch ( OSC_1_TO_MIXER|OSC_3_FRQMOD_OSC_1 ); }
my_synth->setFrequency ( OSC_3 , (value*2) );
my_synth->trigger ( OSC_3 );
} else {
freq_mod_B_is_active = 0;
my_synth->selectBank(BANK_B);
my_synth->release(OSC_3);
}
} // if number==24

if (number == 25) { // CC 25 to apply higher frequency FreqMod OSCs to Bank B; 0 to release, >0 to set
if (value){
freq_mod_B_is_active = 1;
my_synth->selectBank ( BANK_B );
if (amp_mod_B_is_active) { my_synth->setPatch ( OSC_1_TO_MIXER|OSC_3_FRQMOD_OSC_1|OSC_2_AMPMOD_OSC_1 ); }
else { my_synth->setPatch ( OSC_1_TO_MIXER|OSC_3_FRQMOD_OSC_1 ); }
my_synth->setFrequency ( OSC_3 , (value*60) );
my_synth->trigger ( OSC_3 );
} else {
freq_mod_B_is_active = 0;
my_synth->selectBank(BANK_B);
my_synth->release(OSC_3);
}
} // if number==25

/***************************** Amplitude Modulation ******************************/

if (number == 26) { // CC 26 to apply lower frequency AmpMod OSCs to Bank A; 0 to release, >0 to set
if (value){
amp_mod_A_is_active = 1;
my_synth->selectBank ( BANK_A );
if (freq_mod_A_is_active) { my_synth->setPatch ( OSC_1_TO_MIXER|OSC_2_AMPMOD_OSC_1|OSC_3_FRQMOD_OSC_1 ); }
else { my_synth->setPatch ( OSC_1_TO_MIXER|OSC_2_AMPMOD_OSC_1 ); }
my_synth->setFrequency ( OSC_2 , (value*2) );
my_synth->trigger ( OSC_2 );
} else {
amp_mod_A_is_active = 0;
my_synth->selectBank(BANK_A);
my_synth->release(OSC_2);
}
} // if number==26

if (number == 27) { // CC 27 to apply higher frequency AmpMod OSCs to Bank A; 0 to release, >0 to set
if (value){
amp_mod_A_is_active = 1;
my_synth->selectBank ( BANK_A );
if (freq_mod_A_is_active) { my_synth->setPatch ( OSC_1_TO_MIXER|OSC_2_AMPMOD_OSC_1|OSC_3_FRQMOD_OSC_1 ); }
else { my_synth->setPatch ( OSC_1_TO_MIXER|OSC_2_AMPMOD_OSC_1 ); }
my_synth->setFrequency ( OSC_2 , (value*60) );
my_synth->trigger ( OSC_2 );
} else {
amp_mod_A_is_active = 0;
my_synth->selectBank(BANK_A);
my_synth->release(OSC_2);
}
} // if number==27

if (number == 28) { // CC 28 to apply lower frequency AmpMod OSCs to Bank B; 0 to release, >0 to set
if (value){
amp_mod_B_is_active = 1;
my_synth->selectBank ( BANK_B );
if (freq_mod_B_is_active) { my_synth->setPatch ( OSC_1_TO_MIXER|OSC_2_AMPMOD_OSC_1|OSC_3_FRQMOD_OSC_1 ); }
else { my_synth->setPatch ( OSC_1_TO_MIXER|OSC_2_AMPMOD_OSC_1 ); }
my_synth->setFrequency ( OSC_2 , (value*2) );
my_synth->trigger ( OSC_2 );
} else {
amp_mod_B_is_active = 0;
my_synth->selectBank(BANK_B);
my_synth->release(OSC_2);
}
} // if number==28

if (number == 29) { // CC 29 to apply higher frequency AmpMod OSCs to Bank B; 0 to release, >0 to set
if (value){
amp_mod_B_is_active = 1;
my_synth->selectBank ( BANK_B );
if (freq_mod_B_is_active) { my_synth->setPatch ( OSC_1_TO_MIXER|OSC_2_AMPMOD_OSC_1|OSC_3_FRQMOD_OSC_1 ); }
else { my_synth->setPatch ( OSC_1_TO_MIXER|OSC_2_AMPMOD_OSC_1 ); }
my_synth->setFrequency ( OSC_2 , (value*60) );
my_synth->trigger ( OSC_2 );
} else {
amp_mod_B_is_active = 0;
my_synth->selectBank(BANK_B);
my_synth->release(OSC_2);
}
} // if number==29

} // end HandleControlChange


void setup() {

/***************************************** GINSING SETUP ************************/

// NOTE: These flags are needed so that a FreqMod doesn't cancel out an AmpMod, and vice versa
freq_mod_A_is_active = 0;
freq_mod_B_is_active = 0;
amp_mod_A_is_active = 0;
amp_mod_B_is_active = 0;

GS.begin ( rcvPin , sndPin , ovfPin ); // start the device (required)

my_synth = GS.getSynth(); // get the synth mode interface
master = GS.getMaster();
master->setMasterAmplitudeVal(32); // set master volume to 25%
my_synth->begin (); // enter synth mode

// SETUP NOISEMAKING OSCs
my_synth->selectBank (BANK_A);
my_synth->setWaveform ( OSC_1, SINE );
my_synth->setPatch ( OSC_1_TO_MIXER );

my_synth->selectBank (BANK_B);
my_synth->setWaveform ( OSC_1, PULSE );
my_synth->setPatch ( OSC_1_TO_MIXER );

// SETUP MODULATION OSCs
my_synth->selectBank (BANK_A);
my_synth->setWaveform ( OSC_2, SINE );
my_synth->setWaveform ( OSC_3, SINE );
my_synth->selectBank (BANK_B);
my_synth->setWaveform ( OSC_2, SINE );
my_synth->setWaveform ( OSC_3, SINE );

// GS.end(); // commented out because THE FUN NEVER ENDS

/***************************************** MIDI SETUP ****************************/
// Initiate MIDI communications, listen to all channels
MIDI.begin(MIDI_CHANNEL_OMNI);
// Setup callback handlers
MIDI.setHandleNoteOn(HandleNoteOn);
MIDI.setHandleNoteOff(HandleNoteOff);
MIDI.setHandleControlChange(HandleControlChange);

} // end setup()

void loop() { MIDI.read(); } // read MIDI as it comes in; callbacks do all the "work"
The administrator has disabled public write access.

Documentation 5 years 8 months ago #254

/*****************************************

GinSing + MIDI Sketch
with CC support for modulation control

This sketch provides a simplified (i.e. slightly dumbed-down) interface to the GinSing synth library, implemented via MIDI. In addition to accepting MIDI to play the full range of notes GinSing supports, and playing those notes across two independent oscillators, this sketch provides basic support for frequency and amplitude modulation oscillators via MIDI CCs.

The GinSing synth in this sketch is as follows:

2 Banks (A+B), each containing 3 oscillators. In each bank, Oscillator #1 is the primary noise-making oscillator. Oscillators 2 and 3 are used in their respective banks for frequency (OSC3) and amplitude (OSC2) modulation.

Each bank can have its modulations set independently; you can have amp mod, freq mod, or both (or neither). Because of the wide frequencies available to the modulation oscillators, and due to the fact that MIDI CC’s only provide for 127 values, setting the amp and freq mods has been split into 4 CC commands—2 CC commands per bank, with the 1st of the 2 used to set the frequency to CC value times two, and the 2nd of the 2 used to set the frequency to CC value times sixty.

This sketch was tested on the following 3-piece setup:

An Arduino Uno R3 (actually an OSEPP Uno R3)
A pre-assembled GinSing v1.2
A MIDI breakout based upon the MIDI breakout board at SparkFun.com

NOTE: If you’d like to avoid the potential drama of working through hardware issues, just buy the breakout from SparkFun.

The following software libraries are needed:

The GinSing code library that comes with GinSing 1.2
The MIDI library v3.2 for Arduino: arduino.cc/playground/Main/MIDILibrary

MIDI CC cheatsheet for the code-timid:

CC# Function
7 Set main volume

NOTE: The possible CC values for the following two CC #s are: 0 SINE, 1 TRIANGLE, 2 SAWTOOTH, 3 RAMP, 4 PULSE, and anything 5 or greater is set to NOISE.

20 Set the waveform type for the primary Bank A oscillator
21 Set the waveform type for the primary Bank B oscillator

NOTE: To clear (turn off) the following modulation oscillators, just send a CC value of 0 to either the low or high CC # (it doesn’t matter which).

22 Apply low-frequency freq oscillation to Bank A (frequency is
incoming CC value times two)
23 Apply high-frequency freq oscillation to Bank A (frequency
is incoming CC value times sixty)
24 Apply low-frequency freq oscillation to Bank B (frequency is
incoming CC value times two)
25 Apply high-frequency freq oscillation to Bank B (frequency
is incoming CC value times sixty)
26 Apply low-frequency amp oscillation to Bank A (frequency
is incoming CC value times two)
27 Apply high-frequency amp oscillation to Bank A (frequency
is incoming CC value times sixty)
28 Apply low-frequency amp oscillation to Bank B (frequency
is incoming CC value times two)
29 Apply high-frequency amp oscillation to Bank B (frequency
is incoming CC value times sixty)

******************************************/
The administrator has disabled public write access.
The following user(s) said Thank You: administrator
  • Page:
  • 1
Time to create page: 0.317 seconds