Pages: [1]   Go Down
Author Topic: Array and play...  (Read 397 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
Full Member
***
Karma: 0
Posts: 142
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

So Im stuck in the mud here.
I have a mega2560 and Ive reprogrammed the mega8U2 firmware to be a midi port.
I have a button matrix, that outputs a midi note on each button that is pressed. That works fine.
What I am trying to do, is store the buttons that are pressed (or the notes that represent the buttons) in a matrix, and play them continuously - i.e the user can hold three buttons down, but they will be played as midi notes one after the other - I am using an internal timer to set the delay between playing each one.
So using a couple of loops that check each button in the matrix for a state change from last known state, if the button is pressed the function:
addToArray(note); is called. When it is released, removeFromArray(note); is called. They look like this:
Code:
void addToArray(int Key){
  for(byte i = 0; i<sizeof(pressedNoteOrder); i++){
    if (pressedNoteOrder[i] == 0){
      pressedNoteOrder[i] = Key;
      break;
    }
  }
}
void removeFromArray(int Key){
  for (byte i = 0; i<sizeof(pressedNoteOrder); i++){//go through each item in the array
    if(pressedNoteOrder[i] == Key){//look for a match to the note that was released
      for (byte j=i+1; j<sizeof(pressedNoteOrder); j++){
        pressedNoteOrder[j-1] = pressedNoteOrder[j];//when found, shift each note after down one, i.e to clear it out of the array
      }
      pressedNoteOrder[sizeof(pressedNoteOrder)-1]=0;//set the end note in the array to 0
      break; 
    }
  }
}
I.e when a button is released any notes after that are shifted down the array.
Then each time the timer 'ticks' this function is called:
Code:
void playArray(){
static int i = 0;
  do{
    i++;
    if (i > sizeof(pressedNoteOrder)){
      i = 0;
    }
  }while(pressedNoteOrder[i] == 0);
    Play(pressedNoteOrder[i]);
  }
i.e loops through the array playing the notes on each tick.
Well thats what I thought it does. However that doesnt work
The idea is to play the notes in the order the user presses them, however the user can hold them down, or change the notes they are holding and it will continue to play them in order.
I have struggled to debug this in midi mode, and now my mega2560 wont play ball and I cant update the firmware back to serial.
Can anyone see my error - or simulate for me what im after, to see where Im going wrong.
Thanks Guys
Logged

North Queensland, Australia
Offline Offline
Edison Member
*
Karma: 74
Posts: 2214
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

is
Code:
Play(pressedNoteOrder[i]);
supposed to be in the loop. the calculation seems static, or at least not needing the loop.
« Last Edit: August 03, 2012, 12:56:22 pm by pYro_65 » Logged


0
Offline Offline
Full Member
***
Karma: 0
Posts: 142
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Good spot, thank you, thats got me 60% of the way there. can you see anything wrong with the remove from array function? Its not quite right but I cant spot the pattern...
Logged

0
Offline Offline
Full Member
***
Karma: 0
Posts: 142
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ok so I have updated the functions, to something that is closer...
Code:
void addToArray(int Mappedkey){
  pressedNoteOrder[sizeOfArray+1] = Mappedkey-1;
  sizeOfArray++;
}
void removeFromArray(int MappedKey){
  for (byte i = 0; i<sizeof(pressedNoteOrder); i++){//go through each item in the array
    if(pressedNoteOrder[i] == MappedKey-1){//look for a match to the note that was released
      for (byte j=i+1; j<sizeof(pressedNoteOrder); j++){
        pressedNoteOrder[j-1] = pressedNoteOrder[j];//when found, shift each note after down one, i.e to clear it out of the array
      }
      break; 
    }
  }
  pressedNoteOrder[sizeof(pressedNoteOrder)-1] = 0;
  sizeOfArray--;
}
void playArray(){
  static int i = -1;
  i++;
  if (i > sizeOfArray){
    i = 0;
  }
  Play(pressedNoteOrder[i]);
}
Adding seems to work fine.
PlayArray() is going through the array but seems to be going one further than the length - i.e if two buttons are held down, and the timer is calling it once a second, then it goes back to 0 as after a third (that dosnt exist) so i hear the two correct notes, and then there is a silence in the position of the third 'tick' before returning to the first note again.
Remove seems to be causing big problems, in that if I release a button, I then hear nothing after that. I think its messing the array up somehow - I know that you cant "remove" an element but I am trying to shift them all down.
Any help would be greatly appreciated
Thanks
Logged

North Queensland, Australia
Offline Offline
Edison Member
*
Karma: 74
Posts: 2214
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
pressedNoteOrder[sizeof(pressedNoteOrder)-1] = 0;

This will reset the last item only, will fail after removing more than one item. I would decrement sizeOfArray and use it as the index.

Code:
pressedNoteOrder[--sizeOfArray - 1] = 0;

Also, if pressedNoteOrder is an int array, the quote below may help.

From wikipedia:
Quote
When sizeof is applied to the name of an array, the result is the size in bytes of the whole array

E.g.
Code:
char a[5];

sizeof( a ); // = 5

int b[5];

sizeof( b ); // = 10

sizeof( b ) / sizeof( b[0] ); // = 5

So if pressedNoteOrder is an int, your reset code at the top of my post is out of bounds.
Logged


Pages: [1]   Go Up
Jump to: