πŸ“œ ⬆️ ⬇️

MIDI prefix for synthesizer (taptempo)



A colleague the musician asked to make him a prefix to the synthesizer, in order to set the tempo not with variable resistance, but with a button.

For the implementation was chosen Arduino, as the most accessible.


')
Having smoked the basics of MIDI, I found out that a special byte-0xF8 is responsible for setting the tempo. The standard accepted 24 such messages per second at a rate of 1 beat per second, that is, at 60 bpm (beats per minute).

So you need to remove the button press, take the interval between them and give the corresponding signal at the same time displaying it on a small screen.

It sounds good, but in practice it turned out that the output from the screen with the real signal is not combined, it turned out that one of the variables was INT, and not FLOAT, so the signal to the synthesizer was rounded out to the whole, although the screen showed up to 0.001.

Having corrected the types of variables, he obtained an excellent result, but the human factor failed, the colleague could not accurately tap the desired tempo. Therefore, a refinement was added β€” each subsequent interval was added to the previous one and divided by 2 (averaging).

The result was better, but it turned out to be a fork around the desired value, for example, 120bpm is needed, and 117 and 124 were output.

As a result, the optimal algorithm was born:

From 1 to 20 intervals are recorded (arbitrarily), the values ​​are averaged with each press (so that the tempo changes on the screen are visible) and if the operator does not click for 1.5 seconds, the array of interval values ​​is reset and he can start again. One and a half seconds were taken as the definition of a minimum rhythm of 40 beats per minute.

Code
//6   //Tx1-   #include <LiquidCrystal.h>/////   LiquidCrystal lcd(12, 11, 5, 4, 3, 2);///     int statButton=0;///  int laststatButton=LOW; unsigned long int lastinHigh=0;/// unsigned long int inHigh=0; unsigned long int clock=0; unsigned long int lastclock=0; int durations[19];///     int count=0; int duration=0; float sum=3000;////    float bps=2;//   float mps;/// TapTempo   float tic; int count2=0;/// int count3=0; int count4=0; void setup() { Serial.begin(31250);///////////////   //Serial.begin(9600); pinMode(6,INPUT); lcd.begin(16, 2); } void loop() { mps=bps*24 ;//  *   tic=1000000/mps;// /   clock=micros();///    if(clock-lastclock>tic)///    { Serial.write(byte(0xF8));///   lastclock=clock; } if(count2==400)///  { readbut(); count2=0; } count2++; if(count3==2000)//   { lcd.clear(); //lcd.setCursor(0, 0); lcd.print(bps*60); count3=0; } count3++; } void readbut()///   { statButton=digitalRead(6); if(statButton==HIGH&&laststatButton==LOW)///    LOW  HIGH { inHigh=millis();///   duration=inHigh-lastinHigh;//     // Serial.println(duration); if(duration<1500&&duration>100)//    { if(count<19)///     { durations[count]=duration; // Serial.println(durations[count]); count++; } }else{ for(int i=0;i<19;i++) { durations[i]=0; } count=0; } } lastinHigh=inHigh; laststatButton=statButton; for(int i=0;i<19;i++)///  { if(durations[i]!=0)//    { sum=(sum+durations[i]); // println(durations[i]); count4++ ;//   bps=1000.0/(sum/count4);///  /   } } count4=0; sum=0; } 


In the end, everything works and participates in speeches.

If you have any suggestions or suggestions - write.

Source: https://habr.com/ru/post/243971/


All Articles