fanwander
************************
In Anlehnung oder fortführung von https://www.sequencer.de/synthesize...ware-software-entwicklung-austauschen.155044/ mache ich einfach mal einen Thread auf, wo man Fragen zu ATMega-Programmierung stellen kann.
Folge dem Video um zu sehen, wie unsere Website als Web-App auf dem Startbildschirm installiert werden kann.
Anmerkung: This feature may not be available in some browsers.
#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);
}
Warum? Der NoteOn der transponierenden Daten hat ja nichts mit dem Rhythmus der Sequenz zu tun.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.
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.Auch fraglich: Die 128 Note offs werden auch einfach alle schlagartig übergeben. Ist der Buffer da überhaupt groß genug?
Denkbar. Das kann ich mal mit variablen hochzählen ersetzen. (Wird aber vermutlich Montag werden).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.
Ach so, ich dachte es soll jeder Tastendruck transponiert werden...Warum? Der NoteOn der transponierenden Daten hat ja nichts mit dem Rhythmus der Sequenz zu tun.
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.Über Noten am MIDI-In sollte jetzt [/FONT]einfach die eine Note transponiert werden können
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.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?
Warum baut man da ein delay von 200ms ein?
Edit: Ich nehm die Frage zurück, weil sie in dem Falle zweitrangig ist.
Sehr guter Tipp! Werde ich morgen ausprobieren. Danke!int != byte
Treffer! Die Verwendung von delay war es.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.
#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 ... */
}
}
}
case midi::PitchBend:
MIDI.sendPitchBend(MIDI.get<WAS MUSS HIER HIN?>(),outchannel);
break;
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.Ich habe was mit MIDI.setHandle... gefunden, aber 1.) verstehe ich nicht, was ein Handle genau macht
Danke!Im Allgemeinen ist ein Handle die Referenz auf ein Device
#include <MIDI.h>
MIDI_CREATE_DEFAULT_INSTANCE();
uint8_t setMidiChannel;
[…]
void setup() {
MIDI.begin();
[…]
digitalWrite(led1Pin, HIGH);
setMidiChannel = 0;
}
void loop() {
if ( setMidiChannel == 0 ) {
digitalWrite(led1Pin, HIGH);
}
if ( setMidiChannel == 1 ) {
digitalWrite(led1Pin, LOW);
}
[…keyPressOrderLast wird hier gesetzt…]
if (keyPressOrderLast == "Pp" ) {
keyPressOrderLast = "";
setMidiChannel = 1;
}
if ( setMidiChannel == 1 )
if (keyPressOrderLast == "Ss" ) {
setMidiChannel = 0;
keyPressOrderLast = "";
// DAS FUNKTIONIERT
}
if (MIDI.read()) {
byte type = MIDI.getType();
if (type == midi::ControlChange) {
if (MIDI.getData1() == 76) {
value[6] = MIDI.getData2();
channel = value[6];
digitalWrite(led2Pin, HIGH);
delay(100)
digitalWrite(led2Pin, LOW);
setMidiChannel = 0;
// DAS FUNKTIONIERT NICHT
}
}
}
}
}
setMidiChannel = 0;
// ... keyPressOrderLast is set here ...
setMidiChannel = 1;
volatile uint8_t setMidiChannel;