Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 7 of 7

Thread: timing problem (midi note On/Off)

  1. #1
    Junior Member
    Join Date
    Jun 2020
    Posts
    4

    timing problem (midi note On/Off)

    Goodmorning everyone.
    I am writing to find a pious soul to help me with this problem (I state that I have been researching for days).
    I have a code that is almost fully functional to create a step sequencer (16 steps that are activated with a time calculated in bpm and functional).
    I use a bpm calculation that is entered via a "tap tempo" and two buttons, one that increases and one that decreases the tempo in 1 bpm steps.
    My problem is the following:

    I state that I am using, for the midi, the "control_surface" library and a teensy 3.5 card that natively uses the midi via usb (although everything also works with an arduino with the modified firmware).

    For each step I send a MidiNoteOn and a MidiNoteOff that go to drive my video software (I also need the noteoff to release the clips I'm going to triggherare).
    For the NoteOn there are no problems, it is sent correctly, however, obviously sending an on and off signal are consecutively sent at the same time, I would need to understand how to insert a delay (without DELAY) in each step so that the all send "NoteON - Delay - NoteOff".

    Code:
    if (!played) {
    
      {
          midi.update();
        }
       
        if (stepNum == 0 && state1 == 1) {
          Serial.print("  primo_step  ");
          midi.sendNoteOn(noteAddress0, velocity);
          midi.sendNoteOff(noteAddress0, velocity);
        }
        played = true;
    
        if (stepNum == 1 && state2 == 1 ) {
         Serial.print("  secondo_step  ");
    
          midi.sendNoteOn(noteAddress1, velocity);
          midi.sendNoteOff(noteAddress1, velocity);
        }
        played = true;
    
       if (stepNum == 2 && state3 == 1) {
          Serial.print("  terzo_step  ");
          midi.sendNoteOn(noteAddress2, velocity);
          midi.sendNoteOff(noteAddress2, velocity);
        }
        played = true;
    
        if (stepNum == 3 && state4 == 1) {
          Serial.print("  quarto_step  ");
          midi.sendNoteOn(noteAddress3, velocity);
          midi.sendNoteOff(noteAddress3, velocity);
        }
        played = true;
    
     if (stepNum == 4 && state5 == 1) {
          Serial.print("  quinto_step  ");
          midi.sendNoteOn(noteAddress4, velocity);
          midi.sendNoteOff(noteAddress4, velocity);
        }
        played = true;
    
        if (stepNum == 5 && state6 == 1) {
          Serial.print("  sesto_step  ");
          midi.sendNoteOn(noteAddress5, velocity);
          midi.sendNoteOff(noteAddress5, velocity);
        }
        played = true;
    
        if (stepNum == 6 && state7 == 1) {
          Serial.print("  settimo_step  ");
          midi.sendNoteOn(noteAddress6, velocity);
          midi.sendNoteOff(noteAddress6, velocity);
        }
        played = true;
    
       if (stepNum == 7 && state8 == 1) {
          Serial.print("  ottavo_step  ");
          midi.sendNoteOn(noteAddress7, velocity);
          midi.sendNoteOff(noteAddress7, velocity);
    
        }
        played = true;
    
           if (stepNum == 8 && state9 == 1) {
          Serial.print("  nono_step  ");
          midi.sendNoteOn(noteAddress8, velocity);
          midi.sendNoteOff(noteAddress8, velocity);
        }
        played = true;
    
        if (stepNum == 9 && state10 == 1 ) {
         Serial.print("  drcimo_step  ");
          midi.sendNoteOn(noteAddress9, velocity);
          midi.sendNoteOff(noteAddress9, velocity);
        }
        played = true;
    
     if (stepNum == 10 && state11 == 1) {
          Serial.print("  undicesimo_step  ");
          midi.sendNoteOn(noteAddress10, velocity);
          midi.sendNoteOff(noteAddress10, velocity);
        }
        played = true;
    
        if (stepNum == 11 && state12 == 1) {
          Serial.print("  dodicesimo_step  ");
          midi.sendNoteOn(noteAddress11, velocity);
          midi.sendNoteOff(noteAddress11, velocity);
        }
        played = true;
    
     if (stepNum == 12 && state13 == 1) {
          Serial.print("  tredicesimo_step  ");
          midi.sendNoteOn(noteAddress12, velocity);
          midi.sendNoteOff(noteAddress12, velocity);
        }
        played = true;
    
        if (stepNum == 13 && state14 == 1) {
          Serial.print("  quattordicesimo_step  ");
          midi.sendNoteOn(noteAddress13, velocity);
          midi.sendNoteOff(noteAddress13, velocity);
        }
        played = true;
    
        if (stepNum == 14 && state15 == 1) {
          Serial.print("  quindicesimo_step  ");
          midi.sendNoteOn(noteAddress14, velocity);
          midi.sendNoteOff(noteAddress14, velocity);
        }
        played = true;
    
       if (stepNum == 15 && state16 == 1) {
          Serial.print("  sedicesimo_step  ");
          midi.sendNoteOn(noteAddress15, velocity);
          midi.sendNoteOff(noteAddress15, velocity);
    
        }
        played = true;
      }
    This is the part that sends the midi notes at each step:
    stepNum is the step number
    played is a bool that says the step has been performed
    state is put in &&, I send notes only if the button for the step has been pressed and brought state from 0 to 1.
    Serial.println is only for debugging on the serial monitor.

    I will give you an example:
    Setting the bpm to 60 (therefore one step every second), the reading of the millis at each step increases by 1000 ms, I need to understand the mechanism by which I can tell him: the step has started, send MidiNoteOn, wait for total ms and send MidiNoteOff. (I can't put the note off in the next step before the note on because it would get me all wrong).

    If anyone wants to lose 10 minutes I'm here, if you need other code or explanations, write as well.

    Another little question: it would be better if you use the native midi commands in teensy or if using an external library does not cause problems?

    I hope to be able to make a nice post with a 100% working step sequencer as soon as possible, this is the last game to overcome.
    Thank you all.

  2. #2
    Senior Member
    Join Date
    Nov 2012
    Posts
    1,492
    Without seeing all your code it is hard to know what is happening but *after* each if statement you set played = true. But this sets played to true whether or not you sent the note on and off. Each if statement should presumably look like this:
    Code:
        if (stepNum == 0 && state1 == 1) {
          Serial.print("  primo_step  ");
          midi.sendNoteOn(noteAddress0, velocity);
          midi.sendNoteOff(noteAddress0, velocity);
          played = true;
        }
    Pete

  3. #3
    Junior Member
    Join Date
    Jun 2020
    Posts
    4
    Played is referred to step, not to note.

    I have 16 buttons, every button pressed sets state(in your case 1) to 1 and only if state is 1 sends note on and note off.
    I'm trying to figure out how delay note on and note off, not with "delay" because I have a timing to follow.
    Entire step sequencer is work in progress, code is a bit confused but working... I try to post it tomorrow

  4. #4
    Senior Member
    Join Date
    Nov 2012
    Posts
    1,492
    Played is referred to step, not to note.
    In that case you don't need to set played = true after every if statement. Set it once.

    Pete

  5. #5
    Hi Qcontiuum,

    I haven't compiled this since I'm writing this in notepad, but maybe this could help?
    I think you should consider using arrays to slim down the code a little.

    Code:
    unsigned int noteIsOn;
    unsigned int stepCount;
    String textDescription[16]={"STEP 1 ","STEP 2 ","STEP 3 ","STEP 4 ","STEP 5 ","STEP 6 ","STEP 7 ","STEP 8 ","STEP 9 ","STEP 10 ","STEP 11 ","STEP 12 ","STEP 13 ","STEP 14 ","STEP 15 ","STEP 16 "};
    unsigned int midiNoteValue[16]={1,5,10,15,20,25,30,35,40,45,50,55,60,65,70,75};
    bool stateOfButton[16];
    unsigned int BPM;
    
    void setup(){
            beatsPerMinute = 125;
    	beatLength = 16; // Number of divisions in a beat
    	beatDivisionTime = ((60.000/beatsPerMinute)*4)/beatLength; // The delay or pause in milliseconds between beat divisions
    }
    
    void loop(){
    	timeThisBeat = millis();
    	if(stepCount == beatLength){
    		stepCount = 0;
    	}
    	if(timeThisBeat > timeForNextBeat){
    		if(noteIsOn){
    			playSequence(stepCount - 1, 0)
    			noteIsOn = false;
    		}
    		if(stateOfButton[stepCount]){
    			playSequence(stepCount, 1)
    			noteIsOn = true;
    		}				
    	}
    	stepCount++;
    	timeForNextBeat = timeThisBeat + beatDivisionTime;
    	stepCount++;
    }
    
    void playSequence(int stepCount,bool noteOnOff){
    	if(noteOnOff){
          		Serial.print(textDescription[stepCount]);
          		midi.sendNoteOn(midiNoteValue[stepCount], velocity);
    	}else{
          		midi.sendNoteOff(midiNoteValue[stepCount], velocity);
    	}
    }
    Last edited by johanbilen; 06-18-2020 at 01:24 PM.

  6. #6
    Edit: please remove the last stepCount++

  7. #7
    Junior Member
    Join Date
    Jun 2020
    Posts
    4
    Thank you for help.
    I've found a solution, I think on Monday I 'll post the working code.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •