Funktion für (brauchbare) Velocitykurve

  • Ersteller guitar_1
  • Erstellt am
G
guitar_1
Registrierter Benutzer
Zuletzt hier
17.07.13
Registriert
22.05.10
Beiträge
14
Kekse
0
Hallo,

ich hab in letzter Zeit einen Ersatzcontroller für mein Masterkeyboard zusammen gelötet, dass klappt auch alles ganz gut, einzig die Velocity der Tasten bekomm ich nicht "rund". Entweder sind die Anschläge zu hart oder zu weich oder der bereich von 0 bis 127 wird nicht gut abgedeckt (zB ist es dann selbst mit enormen "draufhacken" nicht möglich 127 zu erreichen).

Ich wollte mal fragen, ob es hier jemanden gibt, der Erfahrungen mit der Berechnung der Velocity hat und vielleicht kennt ja sogar jemand eine "gängige" Funktion ... ?

Hier mal mein bisheriger Versuch:
Beim "schellstmöglichen Drücken" einer Taste vergehen etwa 1400µs bis 1500µs zwischen dem erkennen des 1. und 2. Buttons.

Die "beste" Funktion war bisher die folgende, allerdings etwas zu "hart" für meinen Geschmack, man kann kaum leise Anschläge spielen:
847e-10 * t^2 - 678e-5 * t + 136 // t ist da bei die Zeitdifferenz zwischen dem 1. und 2. Button einer Taste in µs

der code (c++/arduino):

Code:
inline void processSecondButton(byte col, byte row){
  // calculate velocity
  unsigned long timeDiff = micros() - keyFirstButtonTime[col][row];
  char velo = 847e-10 * timeDiff * timeDiff - 678e-5 * timeDiff + 136;
  
  if (velo < 1) {
    velo = 1;
  }  
  if (velo > 127) {
    velo = 127;
  }
  
  if (debug) {
    Serial.print("Velocity Time: ");
    Serial.print(timeDiff);
    Serial.print("us Velo: ");
    Serial.println((int) velo);
  }
  
  // send MIDI Note On
  MIDINoteOn(0, keyToMidi[row][col] + keyToMidiOffset, velo);
  
  // mark key as pressed
  keyPressed[col][row] = true;

  // remove button from watch list
  keyInWatchList[col][row] = false;
}


Mit der Idee eine Parabel zu nehmen um eine lineare Ausgabe zu bekommen lieg ich doch richtig oder? - die "Kraft" mit der die Taste gedrückt wird wird ja hier als die Beschleunigung gemessen und der zusammenhang zwischen kraft und zeit ist bei der beschleunigung doch quadratisch - wenn ich mich recht entsinne. Und durch eine quadratische funktion ("in die andere richtung") bekomme ich dann etwas (halbwegs) lineares bei raus. oder?
Also mein Ziel ist erst mal eine lineare Velocitykurve - das war laut Bedienungsanleitung die Standardeinstellung des Keyboards vor dem Controllertausch und ich war damit eigentlich sehr zufrieden. Als "Sahnehäubchen" würde ich natürlich auch gern noch eine veränderbare Velocitykurve implementieren .. aber ich bekomm ja nicht mal die einfachste Variante sicher hin bis jetzt :D

schon mal Danke und schöne Grüße
 
Eigenschaft
 
Mit der Idee eine Parabel zu nehmen um eine lineare Ausgabe zu bekommen lieg ich doch richtig oder? - die "Kraft" mit der die Taste gedrückt wird wird ja hier als die Beschleunigung gemessen
Nein, du misst nur eine Zeitdifferenz, mehr erstmal nicht. Wenn man annimmt, dass die Tastengeschwindigkeit im Bereich zwischen den beiden Kontakten konstant ist, kann man sie aus der Zeitdifferenz berechnen (v = s/t), daher auch "velocity" - nicht etwa "acceleration". Der Zusammenhang ist dann linear. Eine Aussage über die Kraft macht man aber eigentlich gar nicht.

Also mein Ziel ist erst mal eine lineare Velocitykurve
Dann musst du nur einmal die Zeitdifferenz bei maximalem Anschlag (hast du ja schon) und minimalem Anschlag messen. Die zugehörigen MIDI-Velocities kennst du ja (0 und 127), also kannst du die Parameter einer Geradengleichung (y=mx+b, bzw. in deinem Falle v=mt+b) einfach berechnen.

Edit: Bei deiner Funktion oben wäre Velocity=0 übrigens bei ca. 40ms - wenn das passen sollte, wird dir die lineare Kurve noch weniger gefallen als deine bisherige...
 
hmm okay - physik liegt doch schon etwas länger zurück mittlerweile :D

.. und wie messe ich am besten den minimalen Anschlag? weil wenn ich die Taste "langsam" drücke, kommen trotz - nach meinem Empfinden - gleichem Anschlag deutlich unterschiedliche Werte raus ... ich habe da auch schon drüber nach gedacht, aber was sind da so "standardwerte"? 2-3 sec? erscheint mir etwas kurz, aber bei 10sec zum Beispiel ist das schon ein sehr verzerrtes Spielgefühl, mir kommt es so vor als lägen normaler und starker Anschlag in einem deutlich kleinerem Bereich als leichte Anschläge - deshalb auch mein Ansatz mit der Parabel..


EDIT: Zeiteinheit korrigiert
 
.. und wie messe ich am besten den minimalen Anschlag? weil wenn ich die Taste "langsam" drücke, kommen trotz - nach meinem Empfinden - gleichem Anschlag deutlich unterschiedliche Werte raus ...
Na klar, das ist die Problematik ;) Im Endeffekt wird dir nichts anderes übrig bleiben als einen Wert festzulegen, der dir halbwegs passend erscheint. Du kannst ja ein paar Mal "leicht" anschlagen und über die erzielten Werte mitteln. Am Besten spielst du mal ein kleines Stück, ohne auf die Zahlen zu achten und schaust dir dann mal an, in welchem Bereich die Werte liegen. Korrigieren kannst du ja später immer noch, wenn es sich falsch anfühlt.

ich habe da auch schon drüber nach gedacht, aber was sind da so "standardwerte"? 2-3 sec? erscheint mir etwas kurz
So aus dem Bauch heraus würde ich das schon als extrem viel einschätzen. Das würde ja bedeuten, dass die Tastengeschwindigkeit bei starkem Anschlag über ca. das 2000-fache sein müsste als bei leichtem Anschlag. Außerdem glaube ich auch nicht, dass ich 3 Sekunden brauche, um beim Piano-Spiel die Taste zu drücken... Aber wie gesagt, das ist nur mein Bauchgefühl, ich habs nicht nachgemessen.
 
Wenn ich deine Strategie richtig verstehe, gilt es nur als ein Tastenanschlag, wenn der erste und danach der zweite Schalter aktiviert werden, denn nur dann wird ja wohl deine Callback-Funktion aufgerufen. Dann würde ich einfach einen Maximalwert der Zeit zwischen dem Auslösen von Schalter 1 und 2 festlegen, der als Velocity 1 gilt. Alles, was darüber liegt, wird ebenfalls als Velocity 1 gewertet.
 
ja, so mache ich das auch, alles was länger dauert hat Velocity 1.

ich bin jetzt nach sehr langen rumprobieren bei - 0.0074 * (t - 1820) + 127 gelandet, das fühlt sich ganz ok an, da werden die Werte etwa zwischen 1,8 und 19ms verteilt. (ursprünglich ging ich ja von 1,4 ms als Minimalwert aus, das war aber noch eine Messung aus vergangengen Tagen, wo das "Drumherum" noch nicht implementiert war).
Auch insgesamt muss ich den Code wohl noch etwas optimieren (bzw richtig in C schreiben und nicht im Arduino Dialekt), denn mommentan bekomm ich nur eine auflösung von etwa 7-15 Einheiten hin ... das trägt auch dazu bei, das Spielgefühl zu lindern :D

Aber vielen Dank für die Anregungen und schnelle Hilfe :) - wenn jemand aber trotzdem vllt den quellcode eines "zu kaufenden" keyboards kennt oder sonstiges wissen zu dem Thema Velocityberechnung hat darf es gerne noch post! :)
 
Was mich interessieren würde: wie sieht denn die Schaltung aus? Wie liest du die ganzen Schalter aus? Hast du einen Multiplexer vor die digitalen Eingänge gehängt? Oder arbeitest du mt Spannungsteilern an den analogen Inputs? Pollst du die Schalter oder gibt es einen Interrupt, wenn sich ein Schalter ändert?
 
ne ne, die Taster sind in einer Matrix angeordnet, etwa wie hier: http://2.bp.blogspot.com/-lrOeKuxQc...AEmE/mzyzVhgv65A/s1600/scanKeyboard_schem.jpg bloß das meine Matrix etwas größer ist (8 x 20) und ich je 2 Schalter mit Diode pro Taste habe (bei 76 Tasten = 152 Taster), meinen restlicher Schaltplan sieht so aus:

keyboard_controller_Schaltplan.jpg

die Matrix ist da aber nicht mit drin (ich war zu faul die zu zeichnen ;) ) ... die zwei Konnektoren unten sind für die Tasten, rechts für die LEDs auf dem Keyboard, links noch Buttons, Fader, Aftertouch und Potis. ... Wenn das Projekt ganz abgeschlossen ist und ich etwas Zeit dafür finde, wollte ich das auch mal detailierter hier vorstellen ;) es war mal ein CME UF 70 .. aber der Controller war hinüber

einen Multiplexer hab ich nicht verwendet, dass verschwendet zu viel Zeit, und mein Controller (Teensy++ 2) hat auch genug Eingänge, nur das Treiben der Matrix überlasse ich einem Shiftregister. Interrupts mache ich auch nicht, die könnten dem Senden der MIDI-Daten vielleicht in die Quere kommen, ich lese einfach immer aus, ob sich was geändert hat. Deshalb will ich den Code ja auch noch in richtiges C fassen, weil das lesen und setzten der Pins dort deutlich schneller geht als mit Arduino. Aber alles in allem ist es auch mit dem Arduinocode einsetzbar, bis auf die etwas grob aufgelöste Velocity ist alles bestens :)
 
  • Gefällt mir
Reaktionen: 2 Benutzer

Ähnliche Themen


Unser weiteres Online-Angebot:
Bassic.de · Deejayforum.de · Sequencer.de · Clavio.de · Guitarworld.de · Recording.de

Musiker-Board Logo
Zurück
Oben