Hello all,
I'm the happy owner of the book Arduino Music and Audio Projects by Mike Cook.
I am experimenting with the theremin in chapter 5.
The code comments in the book say that it spans 6 octaves. However, mine does not seem to span that much. I am using potentiometers instead of the distance sensor in the original project. I plan to add distance sensors later, but wanted to keep things simple for now until I see that it works.
I output the MIDI signal to a Yamaha PSR-225GM, and it basically works, both with the (modified) theremin sketch and with the simple "MIDI Note Out" sketch (after fixing i typo in the downloaded code (baud rate was wrong).
My problem here, is that as far as I can hear the span is far from six octaves. So I'd like to try setting it for a different span. I do that by amending the controlSend statement in the setup section from "controlSend(6,72)" to "controlSend(6,24)" (for two octaves).
Rotating the pots does change the pitch and volume, respectively, but not to six octaves (as far as I can tell by comparing to playing the same voice directly on the keyboard of the Yamaha).
I can't hear much of a difference, so I wonder if there is something wrong somewhere in the code. I have tried to look up the MIDI standard for setting the number of octaves, but I did not have much luck with that.
So, does anyone of you have experince with this? Do you have any suggestions for troubleshooting?'
Full code is below.
Best regards,
Lars
--
/* Theremin - Mike Cook
* LM 2019-09-23: modifying to use potentiometers instead of infrared sensors.
* Middle pin of pots is connected to pins A0 and A3, respectively.
* Other pins are connected to +5V and GND.
*/
boolean playing = false;
const byte channel = 0;
const byte baseNote = 72;
void setup(){
Serial.begin(31250); // MIDI baud rate
// analogReference(EXTERNAL);
controlSend(0, 0); // set bank 0 MSB
controlSend(32, 0); // set bank 0 LSB
programChange(52); // send voice number
// programChange(52); // send voice number
// set up Pitch bend sensitivity
controlSend(101, 0);
controlSend(100, 0);
controlSend(6,72); // set to 6 octaves
// controlSend(6,24); // set to 2 octaves
controlSend(38, 0); // and zero cents
}
void loop(){
int av1 = 1027 - analogRead(0);
int av2 = 1027 - analogRead(3);
if(av1 <870 && av2 < 870){
if(!playing)noteOn();
else {
trackNote(av2,av1);
}
}
else {
if(playing) noteOff();
}
}
void noteOff(){
playing= false;
// note off + sustain off
noteSend(0x80,baseNote,127);
controlSend(64, 0);
}
void noteOn(){
// note on + sustain on
noteSend(0x90,baseNote,127);
controlSend(64, 127);
playing = true;
}
int trackNote(int freq, int volume){
int pb = 0x2000 - (435 - freq);
sendPB(pb);
int vel = volume>> 3;
controlSend(7, vel);
}
void noteSend(byte cmd, byte data1, byte data2) {
cmd = cmd | channel;
Serial.write(cmd);
Serial.write(data1);
Serial.write(data2);
}
void controlSend(byte CCnumber, byte CCdata) {
byte CCchannel = channel | 0xB0; // convert to Controller message
Serial.write(CCchannel);
Serial.write(CCnumber);
Serial.write(CCdata);
}
void sendPB(int pb){ // send pitch bend message
Serial.write( (byte)0xE0 | channel);
Serial.write( pb & (byte)0x7f);
Serial.write( (pb>>7) & (byte)0x7f);
}
void programChange(byte voice){
Serial.write((byte)0xC0 | channel);
Serial.write(voice);
}