Ich möchte eine Musikausgabe für mein Keyboard bauen, die später auch
von einem Soundprogramm gelesen werden kann.
Die Richtung ist etwa die hier:
Beitrag "CUBASE per MIDI mit AVR steuern"Beitrag "Selbstbau Synth mit Midi"
Ich habe eine einfache Anwendung über UART, die auch zu funktionieren
scheint. Die Töne kommen schon aus dem Casio heraus, aber vom Programm
gelesen werden kann es irgendwie nicht. Mir fehlen noch einige Infos zu
dem Format und den Sendeoptionen, unter anderem dem Timing. Dazu brauche
ich mindestens eine Zeitbasis.
Leider sind die Infos dazu eher dünn gesäht.
Wie viele Zeitstempel (time ticks) muss ich senden? Auf einer Seite
heisst es "1/96 des Taktes" woanders heisst es "Jede 4-tel-Note", was
nicht so recht zusammenpasst.
Kann mir jemand hilfen?
P.S.: Um nicht in irgendwelche aus der Resourcenknappheit ruehrende
Sackgassen zu geraten: Nimm gleich einen vernuenftigen Controller.
Und nicht alten 8 bit Schnarpel.
Wenn ein time tick eine 96stel Note sein soll, dann wären es bei einem
4/4-tel Takt 96 ticks (?) und somit bei 60 bpm = 15 Takte die Minute
96 / 4 = 16 * 15 = 240 Takte die Minute, also 4 Schläge alle 250ms,
richtig?
Nach der anderen Rechnung wäre es ein tick für jeden beat. Das scheint
aber nicht zu stimmen, wenn ich den MIDI Monitor ansehe und mein Casio
spielen lasse.
Voltkrrraft schrieb:> Du koenntest mit wenig Aufwand selber feststellen, was dein> "Casio" an Cubase sendet.> Mal so als Orientierungshilfe.
Scheint eher Fall 1 zu sein.
Voltkrrraft schrieb:> Und nicht alten 8 bit Schnarpel.
Der kann doch einige Megaherz, das sollte reichen :-)
Alles nötige zur MIDI Clock findet man ja schon auf der Wiki seite dazu:
https://en.wikipedia.org/wiki/MIDI_beat_clock
24 Pulse pro 1/4-Note = 6 Pulse pro 1/16-Note = 96 Pulse pro Takt (bei
4/4).
Die MIDI clock ist erstmal nicht wirklich wichtig (24x pro 1/4 Note...).
Schicke als erstes einfach mal nur die Noten raus (note on/off), das
versteht jede DAW.
Bei MIDI wichtig ist es die korrekte und für die Computerwelt etwas
unkonventionelle Baudrate einzuhalten (31250 Baud).
Alles weitere (CC messages, start/stop, midi clock, time code) kannst du
dann später hinzufügen.
Evtl. nützlich:
https://www.zem-college.de/midi/mc_befe.htmhttps://www.zem-college.de/midi/mc_tabeb.htm
AVerr schrieb:> 24 Pulse pro 1/4-Note = 6 Pulse pro 1/16-Note = 96 Pulse pro Takt (bei> 4/4).
Danke für die Klärung. Ich finde die Darstellung in der englischen Wiki
auch besser.
Joe F. schrieb:> Die MIDI clock ist erstmal nicht wirklich wichtig (24x pro 1/4 Note...).>> Schicke als erstes einfach mal nur die Noten raus (note on/off), das> versteht jede DAW.
Ich muss der aber irgendwie das Tempo mitteilen, oder?
Karlchen schrieb:> Ich muss der aber irgendwie das Tempo mitteilen, oder?
Nein. Das Tempo ergibt sich über den Zeitpunkt der MIDI message.
Ist ja "real-time".
Ok, aber wie macht man das mit dem time code?
Ich habe mir die Spezifikation durchgelesen, steige aber noch nicht
durch. Bisher dachte ich immer dass der MIDI-Takt so eine Art Datentakt
für das Instrument ist, sodass er die Noten nur dann spielt, wenn der
Takt kommt, um alle zueinander passenden Noten gleichzeitig spielen zu
können. Das scheint aber nicht der Fall zu sein.
Demgemäß müsste ich wahrscheinlich jeder Note eine Erscheinungszeit mit
auf den Weg geben.
Braucht man dann noch den MIDI-Takt?
Ich wollte nochmals kurz auf das Problem eingehen:
Spiele ich mit dem AVR (oder einem Gerät) einige Noten ab, z.B. aus
einem Akkord, dann werden diese seriell gesendet, sollen aber
gleichzeitig erklingen und (hoffentlich) in dem PC im
Aufzeichnungsprogramm auch gleichzeitig aufgenommen und einer Zeit
zugeordnet werden.
Ich finde aber immer noch keine Erklärung wie das zu machen ist und wie
das bei MIDI gelöst ist.
Ich habe heute mit dem MIDI Monitor verschiedene Akkorde gespielt, sehe
aber ausser dem MIDI Takt keine weiteren Informationen darin.
Karlchen schrieb:> Demgemäß müsste ich wahrscheinlich jeder Note eine Erscheinungszeit mit> auf den Weg geben.>> Braucht man dann noch den MIDI-Takt?
Jede Note wird dann sofort gespielt, wenn der note-on event übertragen
wurde.
Eine "Presentation-Time-Information" gibt es (noch) nicht.
Bei Akkorden, die ja aus mehreren Noten bestehen, haben die einzelnen
Noten tatsächlich einen minimalen zeitlichen Versatz.
Da Note-On Messages aus 2 Bytes bestehen, ist das im besten Fall
2 x 10 x 1/31250s = 0.64 Millisekunden. Also nicht wirklich hörbar.
Zusätzlich gibts noch die Möglichkeit bei mehreren Noten das Command
Byte nur einmal zu senden, damit wird für die Noten nach der ersten Note
nur noch 1 Byte übertragen (="running state") - das ist dann auch eher
was für "später mal".
Mit der MIDI Clock kann man Geräte miteinander synchronisieren.
Wenn du z.B. einen Sequencer hast (z.B. eine Drummachine, die Loops
abspielen kann), dann kann diese sich als Slave auf die Clock
synchronisieren.
Oder auch die Geschwindigkeit von LFOs mehrerer Synthesizer möchte man
manchmal gerne synchronisieren.
Ein Masterkeyboard schickt die Tasten-Events immer sofort raus.
Wenn dein Gerät aber auch einen Seqencer-Mode haben soll, dann kann es
natürlich Sinn machen die DAW als MIDI-Clock Master zu konfigurieren,
dein Gerät empfängt dann die MIDI Clock der DAW (über den MIDI-In deines
Gerätes) und erzeugt die Noten auf MIDI-Out synchron zu dieser Clock.
Joe F. schrieb:> Bei Akkorden, die ja aus mehreren Noten bestehen, haben die einzelnen> Noten tatsächlich einen minimalen zeitlichen Versatz.> Da Note-On Messages aus 2 Bytes bestehen, ist das im besten Fall> 2 x 10 x 1/31250s = 0.64 Millisekunden. Also nicht wirklich hörbar.
Note-On besteht aus 3 Bytes (Das Status-Byte, die zu spielende Note und
die Anschlagdynamik) und braucht damit eine knappe Millisekunde.
> Zusätzlich gibts noch die Möglichkeit bei mehreren Noten das Command> Byte nur einmal zu senden, damit wird für die Noten nach der ersten Note> nur noch 1 Byte übertragen (="running state") - das ist dann auch eher> was für "später mal".
Es heißt "running status", da das erste Byte "status byte" genannt wird.
Und damit sind es dann zwei Bytes.
Hi,
ich kann nicht konkret was zur Fragestellung beitragen, aber zwei
Programme sind vielleicht für den OP interssant:
MidiOX [1] erlaubt in Verbindung mit loopMidi [2] Daten die zwischen
verschiedenen Geräten ausgetauscht werden mitzulesen (sofern man irgend
ein Midi IO Gerät für den PC hat.
Grüße
Flo
[1] http://www.midiox.com/
[2] https://www.tobias-erichsen.de/software/loopmidi.html
Rolf M. schrieb:> Joe F. schrieb:>> Bei Akkorden,> Und damit sind es dann zwei Bytes
Leider ist auf dem MIDI Kanal immer dann, wenn Akkorde kommen, immer am
Meisten los, weil dann auch gerne ein Taktwechsel stattfindet. Da kommen
dann noch der Clock Tic, Stimm- und Parameter-Änderungen und das Ganze
nicht nur für Begleitung sondern auch noch für die Lead Voice.
Dh. es müssen eigentlich mehrere Sachen gleichzeitig passieren.
Besonders schwierig wird es, wenn noch Klangverdopplung durch Layering,
Split oder Velocity Split benutzt werden. Analysiert man das, was ein
Arranger-Keyboard an eine externen Sounderzeuger sendet, sind das in dem
Moment oft eine mittlere zweistellige Anzahl von MIDI-Informationen. Das
geht eben echtzeitmässig nicht, egal, wie man es anstellt. Beim USB hat
man gfs einen offset, der durch das Aufteilen von Paketen und die
Interpretation / Schleife im OS entsteht und beim normalen MIDI eben das
Bandbreitenlimit. Selbst mit meinem MIDI im FPGA gibt es nenneswerten
Offset.
Theoretisch kriegt man es über MTC geregelt, aber da gibt es oft ein
Problem mit nicht passenden (und IMHO auch zu groben) frame rates.
Die einzige Möglichkeit ist, das mit einem Song-Modus zu machen und über
absolute time codes zu arbeiten, also den Sequenzer online in Echtzeit
zu programmieren. Dazu muss die Quellinstanz aber rücksynchronisierbar
sein, es braucht also einen Mastertakt von der Senke in Form eines
Synchronisations-Tracks.
In den meisten DAWs ist das intern so gemacht, was auch kein Problem
ist, da alles in einer Maschine läuft.
Andere Möglichkeit: Manche Klangerzeuger synchen sich auf den nächsten
MIDI-Tic und puffern alles, bis dahin, d.h. man schiebt es in Echtzeit
raus und alles, was zwischen zwei Time Codes gesendet wird, wird dann
schlagartig beim nächsten tic gespielt. So mache ich das jedenfalls in
meinem Synth, allerdings muss man dann mit Echtzeitspiel aufpassen, dass
die Akkorde nicht etwa zu spät gegriffen werden und den time tic
verpassen.
Hat alles Vor- und Nachteile.
Das Beste und Einfachste, was es gibt ist nach wie vor Echtzeit ohne
Granularisierung aber richtig performant.
Jürgen S. schrieb:> Leider ist auf dem MIDI Kanal immer dann, wenn Akkorde kommen, immer am> Meisten los, weil dann auch gerne ein Taktwechsel stattfindet. Da kommen> dann noch der Clock Tic, Stimm- und Parameter-Änderungen und das Ganze> nicht nur für Begleitung sondern auch noch für die Lead Voice.>> Dh. es müssen eigentlich mehrere Sachen gleichzeitig passieren.
Am besten paßt MIDI für eine elektrische Orgel: Registerwechsel und
Bewegungen von Schweller passieren nicht zu oft. Für Note ein - Note aus
reicht Geschwindigkeit mit Überschuß.
MIDI ist von Anfang an nicht dazu gedacht, um Wellenform zu übertragen.
Note ein - Note aus, Register ein - Register aus, Regler bewegen. Mehr
ist von MIDI nicht zu erwarten. Aber für alles oben genannte reicht
MIDI-Geschwindigkeit aus.
Jürgen S. schrieb:> Rolf M. schrieb:>> Joe F. schrieb:>>> Bei Akkorden,>> Und damit sind es dann zwei Bytes>> Leider ist auf dem MIDI Kanal immer dann, wenn Akkorde kommen, immer am> Meisten los, weil dann auch gerne ein Taktwechsel stattfindet. Da kommen> dann noch der Clock Tic, Stimm- und Parameter-Änderungen und das Ganze> nicht nur für Begleitung sondern auch noch für die Lead Voice.
Naja, aber oft will man auch nicht, dass alles exakt gleichzeitig
angeschlagen wird, denn dann klingt es arg mechanisch. Auf einem echten
Klavier wird man auch selten einen Akkord so spielen können und wollen,
dass alle Tasten auf eine Millisekunde genau gleichzeitig angeschlagen
werden.
> Andere Möglichkeit: Manche Klangerzeuger synchen sich auf den nächsten> MIDI-Tic und puffern alles, bis dahin, d.h. man schiebt es in Echtzeit> raus und alles, was zwischen zwei Time Codes gesendet wird, wird dann> schlagartig beim nächsten tic gespielt.
Das ist dann im Prinzip eine Quantisierung.
> So mache ich das jedenfalls in meinem Synth, allerdings muss man dann mit> Echtzeitspiel aufpassen, dass die Akkorde nicht etwa zu spät gegriffen> werden und den time tic verpassen.
Ist halt blöd, dass die Zeit immer vorwärts läuft. ;-)
Du musst immer einen "Tick" zu früh spielen. Das erscheint mir für das
live-Einspielen irgendwie unpraktisch.
Mit 8-Bit-µCs kann man mehr machen, als sich kaum ein Dödel mit
einem 32-Bit-Schnurpel bei GHz-Takt vorstellen kann.
Aber selbst das uralte MIDI braucht etwas RAM. Nicht nur 128 Byte,
auch 1024 Byte sind zu knapp. 10 K wären schon ein Anfang, aber die
findeste nun mal wirklich nicht bei 8-Bit-Geschnarpel.
Schnorpel schrieb:> Aber selbst das uralte MIDI braucht etwas RAM. Nicht nur 128 Byte,> auch 1024 Byte sind zu knapp. 10 K wären schon ein Anfang, aber die> findeste nun mal wirklich nicht bei 8-Bit-Geschnarpel.
Warum sollte das ausgerechnet für MIDI nötig sein? Abgesehen von SysEx
sind MIDI-Botschaften maximal 3 Bytes lang, und für die Übertragung kann
man einen gewöhnlichen UART verwenden.
Ketzerisch gesagt: ein uc der MIDI nicht hinkriegt, scheitert auch an
jedem anderen Protokol. Das müsste sogar ohne ram nur mit Registern
entspannt funkionieren....
Rolf M. schrieb:> Naja, aber oft will man auch nicht, dass alles exakt gleichzeitig> angeschlagen wird, denn dann klingt es arg mechanisch.
Das bleibt einem ja unbenommen, ungenau zu spielen. Das passiert ja
auch. Allerdings sind das aus musikalischen Gründen verzögerte
Anschläge. Man möchte aber nicht, dass die Übertragung da zusätzlich
reinpfeift.
> Das ist dann im Prinzip eine Quantisierung.
Ja, wobei man unterstellt, dass alles, was innerhalb einer Zeitperiode
gesendet wurde, auch in dieser auftauchen möge. Der Erzeuger muss dann
nur den MIDI Synch später schicken. Das geschieht auch, wenn sich die
Informationen stauen und man nicht der MIDI Clock eine höhere Prio gibt,
was leider viele Sequenzer tun, wie mir scheint.
Leider hat sich darüber keiner so richtig Gedanken gemacht. MIDI bietet
einfach nur irgenwelche Synch-Mechanismen an, und jedes Gerät macht in
anderer Weise davon Gebrauch.
Schnorpel schrieb:> Aber selbst das uralte MIDI braucht etwas RAM. Nicht nur 128 Byte,> auch 1024 Byte sind zu knapp.
Und wozu braucht man für MIDI so viel RAM? Stack, globale Variablen...
Wozu sonst?
Ich habe im 2000 2 Manuale und Pedal mit 89C2051 bedient, d.h. mit 128
bit RAM. Das arbeitet immer noch. 2x 60 Tasten + 30 Pedaltasten, 150
alte Tastenzustände, die man merken sollte. 19 Bytes insgesamt.
Jürgen S. schrieb:> Rolf M. schrieb:>> Naja, aber oft will man auch nicht, dass alles exakt gleichzeitig>> angeschlagen wird, denn dann klingt es arg mechanisch.> Das bleibt einem ja unbenommen, ungenau zu spielen. Das passiert ja> auch. Allerdings sind das aus musikalischen Gründen verzögerte> Anschläge. Man möchte aber nicht, dass die Übertragung da zusätzlich> reinpfeift.
Natürlich nicht. Ich wollte damit sagen, dass sie das sowieso oft nicht
tut, denn wenn man nicht alles auf die Millsekunde genau gleichzeitig
spielt, werden auch die Latenzen nicht so groß, dass es ein Problem
wäre.
>> Das ist dann im Prinzip eine Quantisierung.> Ja, wobei man unterstellt, dass alles, was innerhalb einer Zeitperiode> gesendet wurde, auch in dieser auftauchen möge. Der Erzeuger muss dann> nur den MIDI Synch später schicken. Das geschieht auch, wenn sich die> Informationen stauen und man nicht der MIDI Clock eine höhere Prio gibt,> was leider viele Sequenzer tun, wie mir scheint.
Das würde mich wundern. MIDI Clock ist eine Realtime-Message. Das heißt,
dass sie nur ein Byte groß ist und dass sie jederzeit gesendet werden
kann, selbst zwischen den Bytes einer anderen MIDI-Nachricht. Wenn's
also nicht ganz schlecht implementiert ist, dürfte der Jitter der
MIDI-Clock nicht größer als 320 µs sein (wenn gerade ein Byte gesendet
wird und darauf gewartet wird, dass die Schnittstelle wieder frei ist).
Im besten Fall dürfte es nahezu gar keinen Jitter geben, wenn man vorher
dafür sorgt, dass die Schnittstelle beim Senden des Clock-Nachricht auf
jeden Fall frei ist. Man weiß ja vorher, wann sie gesendet werden muss.
So hab ich das bei meiner Clock-Quelle implementiert, und die
angeschlossenen Geräte laufen damit super stabil.