OnTopic Arduino / ATMega Programmierung

fanwander
fanwander
*****
Und dann auch gleich meine erste Frage:

Kleiner Test-Code um MIDI transponierung zu testen:
Code:
#include <MIDI.h>
MIDI_CREATE_DEFAULT_INSTANCE();
#define CHANNEL 1
int noteIn = 36;
int note = 0;

void setup() {
   MIDI.begin(CHANNEL);
   MIDI.turnThruOff();
   // evenutelle Notenhänger beenden
   for (note = 0; note < 127 ; note++) {
      MIDI.sendNoteOff(note,127,CHANNEL);
   }
}

void loop() {
   if (MIDI.read()) {                    
      byte type = MIDI.getType();
      if (type == midi::NoteOn) {
         noteIn = MIDI.getData1();
      }
   }
   note = 12 + noteIn;
   MIDI.sendNoteOn(note,127,CHANNEL);
   delay(200);
   MIDI.sendNoteOff(note,127,CHANNEL);
   delay(200);
}
Ich gebe also einfach eine Note aus die sich aus dem Notenwert 12 und einem Transposewert "noteIn" zusammensetzt. Transpose ist im default auf 36. Die Note wird auch gespielt.

Über Noten am MIDI-In sollte jetzt [/FONT]einfach die eine Note transponiert werden können. Das passiert aber nicht, bzw passiert irgendwann und ich kann keinen Zusammenhang mit einem Tastendruck feststellen. Was ist da faul?
 
recliq
recliq
¯\_(ツ)_/¯
Als Erstes würde ich mal den Outputkram in den zweiten if-Block ziehen, also nur etwas Ausgeben, wenn auch etwas reingekommen ist..
Im zweiten Step würde ich nicht nur einfache delays verwenden, sondern NoreOn senden wenn NoterOn empfangen wurde und NoteOff senden, wenn Noteoff empafngen wurde.
 
moogli
moogli
||||
Auch fraglich: Die 128 Note offs werden auch einfach alle schlagartig übergeben. Ist der Buffer da überhaupt groß genug?
 
moogli
moogli
||||
Zweite Idee: Beißt sich da ggf. das Interrupt-Handling von Delay() und der Abarbeitung des MIDI Buffers? Müsste man sich mal anschauen, wie das genau implementiert ist.
 
fanwander
fanwander
*****
Als Erstes würde ich mal den Outputkram in den zweiten if-Block ziehen, also nur etwas Ausgeben, wenn auch etwas reingekommen ist..
Im zweiten Step würde ich nicht nur einfache delays verwenden, sondern NoreOn senden wenn NoterOn empfangen wurde und NoteOff senden, wenn Noteoff empafngen wurde.
Warum? Der NoteOn der transponierenden Daten hat ja nichts mit dem Rhythmus der Sequenz zu tun.
 
fanwander
fanwander
*****
Auch fraglich: Die 128 Note offs werden auch einfach alle schlagartig übergeben. Ist der Buffer da überhaupt groß genug?
Das funktioniert. Ist ja auch nur im setup. Das ganze stammt aus einem Nachbau des JX3P sequencers, der eigentlich komplett funktioniert. Nur Transpose tut quasi nix.

Zweite Idee: Beißt sich da ggf. das Interrupt-Handling von Delay() und der Abarbeitung des MIDI Buffers? Müsste man sich mal anschauen, wie das genau implementiert ist.
Denkbar. Das kann ich mal mit variablen hochzählen ersetzen. (Wird aber vermutlich Montag werden).
 
Zuletzt bearbeitet:
moogli
moogli
||||
Nächste Frage: Woher weiß das MIDI Objekt, dass dieses Event des Input Buffers (gibt es da einen?) jetzt gelesen wurde und es verworfen werden kann?
 
MacroDX
MacroDX
Hat ein Bild mit Robotern wo aufm Mond rumlaufen
Warum baut man da ein delay von 200ms ein?
Edit: Ich nehm die Frage zurück, weil sie in dem Falle zweitrangig ist.

Über Noten am MIDI-In sollte jetzt [/FONT]einfach die eine Note transponiert werden können
Eigentlich nicht wirklich: Dein Code addiert auf die eingehende Note einen Offset von einer Oktave. Dass bedeutet, dass nicht die eingehende Note als Transpositionswert verwendet wird, sondern die transponierte Note darstellt.
Oder habe ich dein Formulierung da falsch aufgefasst?
 
Zuletzt bearbeitet:
fanwander
fanwander
*****
Eigentlich nicht wirklich: Dein Code addiert auf die eingehende Note einen Offset von einer Oktave. Dass bedeutet, dass nicht die eingehende Note als Transpositionswert verwendet wird, sondern die transponierte Note darstellt.
Oder habe ich dein Formulierung da falsch aufgefasst?
Das ist eine Vereinfachung. Die konstante 12 stellt quasi die Sequenz dar (dauernd wiederholter Ton auf C1). Da mein Keyboard als tiefsten Notenwert C3 ausgibt (dec. 36) sollte bei einer Transponierung mindestens ein C4 (dec. 48) rauskommen. In Realitas wird dann da "eigentlicheSequenzNote + noteIn - 36" stehen, aber das wäre im Beispiel verwirrend.

Warum baut man da ein delay von 200ms ein?
Edit: Ich nehm die Frage zurück, weil sie in dem Falle zweitrangig ist.

Die ersten 200ms zwischen NoteOn und NoteOff sind die Notendauer, die 200ms nach dem NoteOff sind die Abstände zwischen den Noten. Das ist jetzt nur ein Workaround. Im späteren Code wird das in Abhängigkeit von den Clockticks gemacht.
 
2bit
2bit
|||||||||
Zuletzt bearbeitet:
MacroDX
MacroDX
Hat ein Bild mit Robotern wo aufm Mond rumlaufen
Da es hier ja um Die Programmierung allgemein gehen soll, möchte ich den Hinweis von 2bit hier aufgreifen:
Ich kenne mich zwar mit Arduino nicht so aus, habe aber mit ATmegas und GCC die Erfahrung gemacht, dass es sinnvoll ist, die Datentypen immer explizit anzugeben. Also eben uint8_t, uint16_t usw.
Ich versuche auch soweit möglich globale Variablen zu vermeiden und verwende wann immer möglich statics in Funktionen. Ob der Arduino Compiler dieselben Scopes auf Variablen anwendet wie GCC weiss ich allerdings nicht.
 
fanwander
fanwander
*****
Zweite Idee: Beißt sich da ggf. das Interrupt-Handling von Delay() und der Abarbeitung des MIDI Buffers? Müsste man sich mal anschauen, wie das genau implementiert ist.
Treffer! Die Verwendung von delay war es.
Ich habe meine Test-Notenauslösung jetzt einfach so gemacht:
trigger = millis() % 400;
if (trigger == 0) MIDI.sendNoteOn(noteIn,127,CHANNEL);
if (trigger == 200) MIDI.sendNoteOff(noteIn,127,CHANNEL);
 
fanwander
fanwander
*****
Ich hab mal wieder eine Frage zur MIDI-Programmierung am Arduino

Ich will MIDI-Informationen auf einem Kanal empfangen und auf einem anderen Kanal ausgeben. Dabei soll nach Datentypen unterschieden werden.
Das funktioniert wunderbar zB mit NoteOn/Off oder ControlChange, aber ich finde nichts wie ich Pitchbend-Daten kriege, bzw was ich ausgeben muss. Hier der Code für ControlChange:
Code:
#include <MIDI.h>
MIDI_CREATE_DEFAULT_INSTANCE();
uint8_t outchannel=1;
uint8_t inchannel=2;

void setup() {
   MIDI.begin();
   MIDI.setThruFilterMode(1);
   MIDI.turnThruOff();
}

void loop() {
      MIDI.read();
      byte type=MIDI.getType();
      if (MIDI.getChannel() == inchannel) {                                           //ICH NEHMEN NUR DATEN MIT inchannel
         switch (type) {
            case midi::ControlChange:
                MIDI.sendControlChange(MIDI.getData1(),MIDI.getData2(),outchannel);   //ICH SENDE DIESE DATEN MIT outchannel
            break;
           /* ... und vieles mehr ... */
         }
      }
}

Für die BenderDaten muss es doch auch so was geben. Nur finde ich keine Info für das, was ich statt dem "WAS MUSS HIER HIN?" einsetzen müsste.

Code:
case midi::PitchBend:
   MIDI.sendPitchBend(MIDI.get<WAS MUSS HIER HIN?>(),outchannel);
break;
Ich habe was mit MIDI.setHandle... gefunden, aber 1.) verstehe ich nicht, was ein Handle genau macht, 2.) funktionieren die gefundenen Beispiele nur, wenn Eingangskanal und Ausgangskanal identisch sind.

EDIT: aus Versehen im zweiten Beispiel ProgramChange statt PitchBend geschrieben
 
Zuletzt bearbeitet:
fanwander
fanwander
*****
Mit Kollege @inorx zusammen habe ich die Lösung gefunden:

MIDI.sendPitchBend( (((MIDI.getData2() * 128) + MIDI.getData1() ) + 8192),outchannel);
 
Zuletzt bearbeitet:
MacroDX
MacroDX
Hat ein Bild mit Robotern wo aufm Mond rumlaufen
Ich habe was mit MIDI.setHandle... gefunden, aber 1.) verstehe ich nicht, was ein Handle genau macht
Im Allgemeinen ist ein Handle die Referenz auf ein Device. Daher ist das evtl. dafür gedacht, wenn ein Controller mehr als einen UART hat, sprich, man auch mehrere MIDI Ports verwenden könnte. Ist aber nur geraten in dem Falle, da ich mit der Arduino API noch nicht vertraut bin.
 
Xsample
Xsample
|
Da hier ja richtige Profis sitzen nur eine kleine Zwischenfrage, wenn es erlaubt ist. Dann lese ich auch wieder still mit .. faszinierend!

Ich habe mir den Clocky gebastelt, aber der will nicht so recht funzen.
Clocky – SoundForce (sound-force.nl)

Ohne Chip waren alle LEDs an. Nach aufspielen der Firmware geht nichts mehr, an einigen Buchsen und Schaltern liegt aber ein Clocksignal an. Über die Lötung mache ich mir mal am wenigsten Gedanken. Mir gehts um den Chip. Auf dem oberen Bild ist der vom Soundforge Orignal unten mein verbauter ... sind die baugleich?
 

Anhänge

  • clocky.jpg
    clocky.jpg
    977,6 KB · Aufrufe: 12
 


News

Oben