hello, Im making a MIDI drum kit, but im having trouble with polyphonic hits, basically triggering multiple MIDI notes at the same time. Im using the MIDI serial library. Here is my code.
/*
This examples shows how to make a simple seven keys MIDI keyboard with volume control
Created: 4/10/2015
Author: Arturo Guadalupi <a.guadalupi@arduino.cc>
http://www.arduino.cc/en/Tutorial/MidiDevice
*/
#include "MIDIUSB.h"
#include "PitchToNote.h"
#define NUM_PIEZOS 6
//Defines analog pins
const uint8_t piezo1 = A0;
const uint8_t piezo2 = A1;
const uint8_t piezo3 = A2;
const uint8_t piezo4 = A3;
const uint8_t piezo5 = A4;
const uint8_t piezo6 = A5;
//Arrays for playnotes()
const uint8_t piezos[NUM_PIEZOS] = {piezo1, piezo2, piezo3, piezo4, piezo5, piezo6};
const byte notePitches[NUM_PIEZOS] = {48, 50, 52, 53, 55, 57};
uint8_t notesTime[NUM_PIEZOS];
uint8_t hitPiezos[NUM_PIEZOS] = {0x00,0x00,0x00,0x00,0x00,0x00};
uint8_t previousPiezos[NUM_PIEZOS] = {0x00,0x00,0x00,0x00,0x00,0x00,};
uint8_t thresh = 100;
uint8_t voltage = 0;
uint8_t intensity = 0;
void setup() {
Serial1.begin(9600);
}
void loop() {
readPiezo();
readIntensity();
polyphonic();
playNotes();
}
// First parameter is the event type (0x0B = control change).
// Second parameter is the event type, combined with the channel.
// Third parameter is the control number number (0-119).
// Fourth parameter is the control value (0-127).
void controlChange(byte channel, byte control, byte value) {
midiEventPacket_t event = {0x0B, 0xB0 | channel, control, value};
MidiUSB.sendMIDI(event);
}
// First parameter is the event type (0x09 = note on, 0x08 = note off).
// Second parameter is note-on/note-off, combined with the channel.
// Channel can be anything between 0-15. Typically reported to the user as 1-16.
// Third parameter is the note number (48 = middle C).
// Fourth parameter is the velocity (64 = normal, 127 = fastest).
void noteOn(byte channel, byte pitch, byte velocity) {
midiEventPacket_t noteOn = {0x09, 0x90 | channel, pitch, velocity};
MidiUSB.sendMIDI(noteOn);
}
void noteOff(byte channel, byte pitch, byte velocity) {
midiEventPacket_t noteOff = {0x08, 0x80 | channel, pitch, velocity};
MidiUSB.sendMIDI(noteOff);
}
//Reads Piezos. Stores triggered piezos into a bit
void readPiezo()
{
for (int i = 0; i < NUM_PIEZOS; i++)
{
if (analogRead(piezos[i]) >= thresh)
{
bitWrite(hitPiezos[i], i, 1);
delay(50);
voltage = piezos[i]; //Value for Intensity
}
else
bitWrite(hitPiezos[i], i, 0);
}
}
//Sets Velocity
void readIntensity()
{
int val = analogRead(voltage);
intensity = (uint8_t) (map(val, 0, 1023, 0, 127));
}
//Reads single note bits, plays single midi notes
void playNotes()
{
for (int i = 0,j = 1; i < NUM_PIEZOS; i++, j++)
{
if (bitRead(hitPiezos[i], i) != bitRead(previousPiezos[i], i))
{
if (bitRead(hitPiezos[i], i))
{
bitWrite(previousPiezos[i], i , 1);
noteOn(0, notePitches[i], intensity);
MidiUSB.flush();
Serial.println("Knock");
}
else
{
bitWrite(previousPiezos[i], i , 0);
noteOff(0, notePitches[i], 0);
MidiUSB.flush();
}
}
}
}
//Reads simultanious bits, and plays simultanious notes
void polyphonic()
{
if (bitRead(hitPiezos[0], 0) != bitRead(previousPiezos[0], 0) && (bitRead(hitPiezos[1], 1) != bitRead(previousPiezos[1], 1)))
{
bitWrite(previousPiezos[0], 0 , 1);
noteOn(0, notePitches[0], intensity);
MidiUSB.flush();
bitWrite(previousPiezos[1], 1 , 1);
noteOn(0, notePitches[1], intensity);
MidiUSB.flush();
Serial.println("Double knock");
}
else
{
bitWrite(previousPiezos[0], 0 , 0);
noteOff(0, notePitches[0], 0);
MidiUSB.flush();
bitWrite(previousPiezos[1], 1 , 0);
noteOff(0, notePitches[1], 0);
MidiUSB.flush();
}
It all works fine, but when i hit two piezos, i only get one or zero MIDI notes in Ableton. I do however get the correct message on the serial monitor.
This code triggers two notes, but with one piezo
for (int i = 0,j = 1; i < NUM_PIEZOS; i++, j++)
{
if (bitRead(hitPiezos[i], i) != bitRead(previousPiezos[i], i))
{
if (bitRead(hitPiezos[i], i))
{
bitWrite(previousPiezos[i], i , 1);
noteOn(0, notePitches[i], intensity);
MidiUSB.flush();
Serial.println("Knock");
bitWrite(previousPiezos[j], j , 1);
noteOn(0, notePitches[j], intensity);
MidiUSB.flush();
Serial.println("Knock");
}
so im not sure why the polyphonic() section i wrote would not work.
I'm sure this had been done in the past, i just cant seem to find any viable code examples.
thank you in advance
-Nick