2 voices simultaneously on 1 Arduino

Here’s a function that will play 2 voices simultaneously on 1 Arduino. You could write a melody and a harmony and have 1 Arduino play them both. The function to do the magic is a bit complicated but you can just ignore it and call it with your melody and harmony pitches and note lengths. Hookup instructions etc. are in the code comments.

_2_voices

01
khaya
March 23rd, 2015 9:55 am

i’ve been using this code to program a melody and a harmony with the arduino, and i am trying to repeat the melody with a pause in between, but instead of pausing, the harmony plays a random note and then plays something other than I programmed. I tried making the melody all rests and left the harmony alone, but the harmony then played something really different than I programmed. why isn’t the harmony working the way I want it to?

02
March 23rd, 2015 4:36 pm

upload your code somewhere and provide a link

03
khaya
March 24th, 2015 12:07 pm

sorry about that. here it is:

#include “pitches.h”

#define FIRST_TONE_PIN 11

#define NUM_OF_VOICES 2

int melody1[] = {
NOTE_C6, NOTE_E6, NOTE_A5, NOTE_C6, NOTE_F5, NOTE_A5, NOTE_F5, NOTE_REST, NOTE_C6, NOTE_E6 };
int mel1Durations[] = {
1800, 600, 1800, 600, 1800, 600, 2400, 300, 1800, 600 };

int harmony1[] = {
NOTE_F4, NOTE_D4, NOTE_AS4, NOTE_A4, NOTE_REST, NOTE_F4 };
int harm1Durations[] = {
2400, 2400, 2400, 2400, 300, 2400 };

void setup() {
Serial.begin(9600);
for (unsigned char i = 0; i < NUM_OF_VOICES; i++) {
pinMode(i+FIRST_TONE_PIN,OUTPUT);
}
for (int j = 0; j < (sizeof(harmony1) / sizeof(int)); j++) {
harmony1[j] = harmony1[j] << 1;
harm1Durations[j] = harm1Durations[j] << 1;
}
playTune(melody1, sizeof(melody1)/sizeof(int), mel1Durations, harmony1, sizeof(harmony1)/sizeof(int), harm1Durations);
}

void loop() {
while (1)
;
}

void playTune(int melody[], int melLength, int melDurations[], int harmony[], int harmLength, int harmDurations[])
{
unsigned int Counts[] = { 0, 0};
unsigned int Periods[] = { 0, 0};
unsigned char States[] = { 0, 0};
unsigned long stopTimeNote1 = 0;
unsigned long stopTimeNote2 = 0;
unsigned char TimedPin = 0;
unsigned int CurrentCount = 0;
unsigned char i;
unsigned char indexMel = 0, indexHarm = 0;

while (1) {
CurrentCount = Counts[0];
TimedPin = 0;
for (i=1;i<NUM_OF_VOICES;i++) {

if (Counts[i] 3)
delayMicroseconds(CurrentCount);

if (Periods[TimedPin] = stopTimeNote1) {

if (indexMel >= melLength)
break;
stopTimeNote1 = millis() + melDurations[indexMel];
Periods[0] = 1000000 / melody[indexMel++];
}

if (millis() >= stopTimeNote2) {
if (indexHarm >= harmLength)
break;
stopTimeNote2 = millis() + harmDurations[indexHarm];
Periods[1] = 1000000 / harmony[indexHarm++];
}

for (i = 0; i < NUM_OF_VOICES; i++) {
Counts[i] = Counts[i] – CurrentCount;
}
Counts[TimedPin] = Periods[TimedPin];

}

}

Leave Your Comment

Name*
Mail*
Website
Comment