MIDI2USB - Musik hat uns verbunden

Russisch-Chinesisch-Amerikanischer MIDI-zu-USB-Wandler.Abb.1 Russisch-Chinesisch-Amerikanischer MIDI-zu-USB-Wandler. Foto vom Autor.



Die Leute lieben Musik. Viele Menschen wissen, wie man Musikinstrumente spielt. Und manche versuchen zu improvisieren und sogar Musik zu komponieren. Elektronische Musikinstrumente können für kreativere Möglichkeiten an Ihren Computer angeschlossen werden. Dies scheint eine einfache Sache zu sein, aber die meisten billigen chinesischen USB-MIDI-Adapter arbeiten mittelmäßig. Wen interessiert es, wie ich meinen MIDI2USB-Adapter hergestellt habe? Ich lade Sie zum Lesen ein



Formulierung des Problems



Vor ein paar Jahren begann mein Neffe, der Musik studiert, zu improvisieren und Musik zu komponieren. Ich wollte, dass seine Arbeit nicht verloren geht, aber ich konnte seine musikalischen Studien nur auf einem Diktiergerät aufzeichnen. Die Qualität dieser Aufnahme war unbefriedigend. Ich wollte Notizen direkt in Cubase oder MuseScore aufnehmen und dann bearbeiten. Dafür habe ich mich für einen chinesischen USB-zu-MIDI-Adapter (Konverter) entschieden.



Anekdote zum Thema
:

— , !

— , ?

— !


Dieses Adapterkabel ist billig und funktioniert nicht gut. Die Datenübertragung vom Synthesizer (E-Piano) zum Computer funktioniert nicht. Wenn Sie mit einem Finger spielen, können Sie mehrere Noten aufnehmen. Wenn Sie einen Akkord nehmen oder Skalen spielen, hängt der Adapter und verwandelt sich in einen Stein. Eine andere Richtung, d.h. Das Übertragen von Daten vom Computer zum Synthesizer funktioniert gut. Ähnliche Geschichten finden sich in den Bewertungen vieler Käufer.



Möglichkeiten zur Verfeinerung des chinesischen Adapters



Im Internet gibt es viele Diskussionen darüber, wie der chinesische Adapter verbessert oder geändert werden kann. In einigen Versionen dieses Adapters wird ein Optokoppler bereitgestellt, der jedoch nicht verlötet ist, wodurch eine galvanische Trennung zwischen dem Computer und dem Synthesizer gewährleistet wird. Leider war in meinem Fall die Überarbeitung schwierig, weil Anstelle eines Optokopplers sind zwei NPN-Transistoren installiert. Beachten Sie, dass der MIDI-Standard direkt die Verwendung eines Optokopplers festlegt , z. B. PC900V oder 6N138. Optokoppler H11L1M (DIP-8) oder H11L1SM (SO-6) weisen ähnliche Eigenschaften auf. Andere Komponenten mit geeigneten Parametern können verwendet werden.



Chinesischer Adapter beim Abbau

Abb. 2. Chinesischer Adapter beim Abbau. Foto vom Autor.



Das Foto zeigt, dass im Gehäuse genügend Platz für den Optokoppler und die zugehörigen Elemente vorhanden ist. Einige Handwerker löten die vorhandenen Komponenten und installierten an ihrer Stelle einen Optokoppler mit einem "Bodykit". Offensichtlich erfordert diese Operation nicht nur Kenntnisse, sondern auch gute handmotorische Fähigkeiten.



Es reicht jedoch nicht aus, eine optische Isolation zwischen dem Musikinstrument und dem Computer bereitzustellen. Ein Präzisionskristalloszillator oder -resonator ist ebenfalls erforderlich, um sicherzustellen, dass der serielle UART gemäß dem MIDI-Standard getaktet wird. Dem chinesischen Adapter, den ich gekauft habe, fehlt nicht nur ein Optokoppler, sondern auch ein Quarzresonator. Natürlich gibt es Mikroschaltungen, in denen Takteinheiten werkseitig kalibriert werden, aber es gibt nichts Vergleichbares. Im Allgemeinen ist die Leistung dieses chinesischen Produkts gering. Auf dem CH345-Chip sind Adapter eingebaut - ein USB-zu-MIDI-Wandler in einem SSOP-20-Paket, aber das ist nicht mein Fall. Der CH345-Mikrochip verfügt über Hardware-USB-Tags. Hersteller-ID: 1a86, Produkt-ID: 752d. Jede "linke" Mikroschaltung kann (und tut) jedoch dieselben Identifikatoren ausgeben und kann sogar "vorgeben", irgendetwas zu sein.



Der letzte kleine Fehler, den ich im chinesischen Adapter gefunden habe, ist die Software (Firmware). Genauer gesagt ist dies eine kleine Puffergröße für Endpunkte mit jeweils nur 8 Byte. Dies reicht aus, um die gedrückten Noten zu übertragen, da die MIDI-Nachricht über die USB-Schnittstelle aus 4 Bytes besteht (Kabelnummer, Befehlsnummer und 2 Datenbytes). Erweiterungen, z. B. SysEx, können jedoch größer sein.



Nach einer Weile kaufte ich ein weiteres Adapterkabel namens "Professional USB MIDI Interface". Dieser Adapter war deutlich teurer und lief deutlich besser, aber immer noch fehlerhaft. Dies zeigte sich in der Tatsache, dass er nach einigen Minuten des Spielens des Synthesizers plötzlich anfing, Tastenanschläge zu verpassen oder umgekehrt - die Freigabe der Taste nicht wahrnahm. Ich war von den Ergebnissen der chinesischen Adapter enttäuscht und entschied mich, dem Rat zu folgen: "Wenn Sie etwas gut machen wollen, dann machen Sie es selbst."



Hardware-Teil



Zunächst war es notwendig, über das Schema des zukünftigen Geräts nachzudenken und die Erfahrungen anderer Ingenieure zu studieren. Der vorhandene Adapter sah von außen sehr gut aus, daher entschied ich mich für ein Gehäuse, LEDs und abgeschirmte Kabel. Darüber hinaus sind MIDI-Kabel in Moskau teurer als ein fertiger chinesischer Adapter. Ich zog das chinesische Board heraus, maß seine Abmessungen und begann, den MIDI-Standard und erfolgreiche MIDI-Projekte im öffentlichen Bereich zu studieren.





Abb. 3 USB-MIDI-Adapter im Gehäuse und mit Kabeln.



Zum Zeitpunkt dieses Schreibens kenne ich einige interessante Projekte:



  1. Diagramm aus der Dokumentation zum CH345-Chip von Nanjing Qinheng Microelectronics.
  2. Alte Projekte auf Atmega-Mikrocontrollern mit Software-Implementierung des USB-Protokolls. Sie verwenden den Low-Speed-Modus, der veraltet ist und in Windows 7 nicht unterstützt wird.
  3. MIDIUSB-Bibliothek für Arduino-Boards mit Hardware-Unterstützung für USB-Schnittstelle (Atmega32u4, Cortex-M) sowie Maple usw.


Die elektrischen Schaltpläne in allen Projekten enthalten viele Beispielfragmente, die auf den Empfehlungen des MIDI-Standards basieren . Daher blieb es, einen Mikrocontroller mit Unterstützung für den USB-Full-Speed-Modus zu wählen, einen PC900V-Optokoppler und eine DIN-5-Buchse (MIDI) im Angebot zu finden.



Platinenlayout
MIDI2USB Schematics




Das Herzstück meines MIDI2USB-Adapters ist ein 8-Bit-Mikrocontroller EFM8UB20F64G von Silicon Laboratories. Ich mag es wirklich und benutze es, wo immer ich kann. Dieser Controller ist der Nachfolger (nach dem Rebranding) des C8051F380-Controllers, der den legendären C8051F320 ersetzte - eine erfolgreiche Entwicklung von Cygnal, die 2003 von SiLabs gekauft wurde.



Ich werde meine Argumente für den EFM8UB20F64-Mikrocontroller auflisten:



  • Bequemlichkeit der Softwareentwicklung, die sich in der Anwesenheit von schnellem und benutzerfreundlichem GPIO, SPI, UART, USB, PCA ausdrückt;
  • verbesserter 8051-Kern (1-2 Zyklen pro Befehl, 48 MIPS), Frequenzänderung "on the fly";
  • eingebauter Spannungsregler, Ausgangstoleranz bis + 5V, Strom bis 100 mA;
  • eingebauter genauer Taktgenerator mit Kalibrierung vom USB-Host (± 0,25%);
  • Verfügbarkeit von USBXpress-, VCPXpress-, USB-Geräte-API-Bibliotheken und Beispielen für den Schnellstart;
  • reine Errata.


Es ist eine Freude, diesen Controller als zu programmieren Es gibt nur wenige Register und Sie können sich auf die Lösung eines angewandten Problems konzentrieren. Leider sind arithmetische Operationen (insbesondere 32-Bit-Operationen) langsam, aber ansonsten ist EFM8 gut. Die Entwicklung von Software für USB-Geräte ist keine leichte Aufgabe. Der Hauptvorteil von SiLabs-Controllern sind die API-Bibliotheken USBXpress, VCPXpress und USB-Geräte. Sogar Texas Instruments verwendet C8051F320-Controller in ihren SmartRF-Karten.



Der Optokoppler ist die zweitwichtigste Komponente im Adapter. Ich habe mich für den Sharp PC900V entschieden, da er genau dem entspricht, was im empfohlenen MIDI-Spezifikationsdiagramm angegeben ist. Die Besonderheit dieses Optokopplers sind schnelle Ein- und Ausschaltzeiten (1 μs und 2 μs) sowie das Vorhandensein eines digitalen Ausgangs. Es gibt aber auch Nachteile - die Größe des Mikroschaltkreises (7 x 10 mm) und das Ausbrennen um 50% nach 5 Betriebsjahren. Aufgrund der Abmessungen des Optokopplers konnten nicht alle Komponenten auf einer Seite der Platine markiert werden. Ich wollte auch nicht auf den MIDI-Anschluss verzichten, der viel Platz beanspruchte.



Die Rückseite der Platine mit Optokoppler und LEDs.

Abb. 4 Rückseite der Platine mit PC900V-Optokoppler und LEDs. Foto vom Autor.



Die Ausgangsstufe wird gemäß dem von der Norm empfohlenen Schema auf einer 74LVC2G04-Logikmikroschaltung montiert, die aus zwei Wechselrichtern besteht. Der Hauptzweck dieser Komponente besteht darin, logische Signalpegel von 3 V => 5 V umzuwandeln und einen Ausgangsstrom von mindestens 10 mA bereitzustellen.



Eine weitere Anekdote
:

- , , , , , …

. :

— - ?

— , !


Die übrigen Komponenten erfüllen Zusatzfunktionen und beeinträchtigen den Betrieb des Geräts nicht wesentlich. Widerstände, Kondensatoren, Dioden und LEDs können sinnvoll ausgetauscht werden. Anstelle eines Mini-USB-Anschlusses können Sie wie bei den Chinesen einen Micro-USB-Anschluss oder einen Pin-Anschluss zum Löten des Kabels verwenden. Der MIDI-Anschluss nimmt viel Platz ein und passt nicht in das Gehäuse. Daher wird er nur in der Adapterversion ohne Gehäuse verwendet. Die MIDI-IN- und MIDI-OUT-Signale werden zur Kabelverdrahtung an den Pin-Header geleitet. Im Allgemeinen sollte die Position der LEDs und Anschlüsse für die optimale Platzierung im Gehäuse angepasst werden.





Abb.5 Debug- und Box-Versionen des MIDI2USB-Adapters. Foto vom Autor.



Der Gesamtverbrauchsstrom überschreitet 50 mA nicht. Es besteht aus folgenden Teilen:



  • Mikrocontroller, 15 mA;
  • drei LEDs, 15 mA (3 × 5 mA);
  • Mikroschaltung 74LVC2G04, 10 mA;
  • Optokoppler PC900V, 10 mA.


Die 2- lagige Leiterplatte wurde von Amerikanern im OSH Park aus 1,6 mm dickem, 0,035 mm Kupfer-FR-4-Material hergestellt.



Software-Teil



Die Erstellung von Software für Geräte ist eine wichtige und entscheidende Entwicklungsstufe. Glücklicherweise verfügen alle modernen Betriebssysteme über Treiber für USB-MIDI-Geräte. Die Aufgabe ist reduziert und Sie müssen nur die Firmware für den Adapter schreiben.



Normalerweise verwende ich Keil uVision PK51 in Verbindung mit Configuration Wizard 2, manchmal IAR Embedded Workbench und sehr selten SiLabs Simplicity Studio. Jede Umgebung hat Vor- und Nachteile. In diesem Projekt habe ich mich für IAR entschieden, weil ich "C mit Klassen" haben wollte. Darüber hinaus bietet der IAR-Compiler Zugriff auf alle Bits der Systemregister. Zum Beispiel ist P2_bit.B0 = 1; oder PCA0MD_bit.WDTE = 0;



Es ist nicht erforderlich, die "magischen Konstanten" oder mehrstufigen Bitausdrücke zu verwenden, die voll von CMSIS oder "SI_EFM8UB2_Register_Enums.h" sind. Leider ist all diese Funktionalität in der Datei ioEFM8UB20F64G.h deklariert, die sich als nicht kompatibel mit den Bibliotheken si_toolchain.h (z. B. dem Makro B0..B3) herausstellte. Ich habe das Projekt nicht in Keil uVision PK51 übersetzt, sondern einfach kompatiblen C-Code für alle Entwicklungsumgebungen geschrieben.



Der Projektcode ist in mehrere Funktionsteile unterteilt



  1. Die Datei "main.c" enthält den Einstiegspunkt, Deklarationen globaler Variablen, einen Aufruf zum Initialisieren von Peripheriegeräten und die Hauptprogrammschleife.
  2. Die Datei "init.c" enthält die Einstellungen für Taktung, Ports, UART und deren Interrupts.
  3. Die Datei deskriptors.c enthält USB-Deskriptoren für das Audioklassengerät.
  4. Die Datei "midi.c" enthält zwei Funktionen zum Konvertieren von MIDI-Meldungen in USB-Events und umgekehrt. Eine Zustandsmaschine wird verwendet.
  5. Die Datei "usbconfig.h" enthält Makros und Definitionen (#define) zum Konfigurieren der Betriebsmodi der USB-Geräte-API-Bibliothek.


Werfen wir einen Blick auf die main () - Funktion mit den Ports, Peripheriegeräten und der Hauptschleife.



int main( void )
{
	WDT_Init();                             // Disable WDTimer (not used)
	PORT_Init();                            // Initialize ports (UART, LEDs)
	SYSCLK_Init();                          // Set system clock to 48MHz
	UART0_Init();                           // Initialize UART0 @31250, 8-N-1
	USBD_Init( &usbInitStruct );            // Initialize USB, clock calibrate
	LED_IN  = 1;                            // Blink LED
	LED_OUT = 1;                            // Blink LED
	IE_EA   = 1;                            // Global enable IRQ

	while(1)
	{
		//--- MIDI => USB
		if( nMidiCount > 0 )
		{
			IE_EA  = 0;                     // Begin: Critical section
			if( USB_STATUS_OK==USBD_Write(EP1IN,aMidiBuffer,nMidiCount,false) )
			{
				nMidiCount = 0;             // Reset MIDI data byte counter
			}
			IE_EA  = 1;                     // End of: Critical section
			LED_IN = 0;                     // Turn off input LED
		}

		//--- USB => MIDI
		if( nUsbCount )
		{
			uint8_t i;
			LED_OUT = 1;                    // Turn on Led on New packet
			for(i = 0; i < nUsbCount; i++)  // Process every data byte
			{
				USB2MIDI( aUsbBuffer[i] );  // Convert USB packet into MIDI
			}
			nUsbCount = 0;                  // Reset counter
			USBD_Read(EP2OUT, aUsbBuffer, sizeof(aUsbBuffer), true);
			LED_OUT = 0;                    // Turn off Led, when done
		}
	}
}


Die Bibliothek von SiLabs für USB-Geräte besteht aus einer Reihe von Unterprogrammen, die abhängig von den Einstellungen in der Datei „usbconfig.h“ kompiliert und in das Projekt aufgenommen werden. Dies ist der Bibliothek "libusb, V-USB" im Code für Mikrocontroller von Atmel (jetzt Microchip) sehr ähnlich. Es sollte beachtet werden, dass SiLabs aus Sicht eines Programmierers eine gute und bequeme Bibliothek hat.



Deskriptoren (Deskriptoren) des Geräts, der Konfiguration und der Schnittstellen spielen eine wichtige Rolle beim Betrieb eines USB-Geräts. Mithilfe dieser Deskriptoren informiert das Gerät den Host (Computer) über seine Anforderungen, Funktionen, Parameter usw. Eine Funktion zum Behandeln von Deskriptoranforderungen befindet sich normalerweise in jeder USB-Bibliothek, und der Programmierer muss nur die Datenstrukturen, die diese Deskriptoren enthalten, korrekt ausfüllen.



Code mit Deskriptoren
SI_SEGMENT_VARIABLE
(usbDeviceDesc[], const USB_DeviceDescriptor_TypeDef, SI_SEG_CODE) =
{
	USB_DEVICE_DESCSIZE,               // bLength, 18 bytes
	USB_DEVICE_DESCRIPTOR,             // bDescriptorType, 1
	htole16(0x0110),                   // bcdUSB Ver, 1.10
	0x00,                              // bDeviceClass, 0 for Audio
	0x00,                              // bDeviceSubClass, 0 for Audio
	0x00,                              // bDeviceProtocol, 0 for Audio
	SLAB_USB_EP1IN_MAX_PACKET_SIZE,    // bMaxPacketSize0, 64 bytes
	htole16(0x1209),                   // idVendor, Free GPL (SiLabs 0x10C4)
	htole16(0x7522),                   // idProduct
	htole16(0x0100),                   // bcdDevice, 1.00
	0x01,                              // iManufacturer string
	0x02,                              // iProduct string
	0x03,                              // iSerialNumber (no serial string)
	0x01                               // bNumConfigurations
};


Alle Deskriptoren, Topologien und Terminologien werden im Standard "Universal Serial Bus Device Class Definition für MIDI-Geräte" ausführlich und ausführlich beschrieben . Für einen schnellen Einstieg und einen Einblick in das Thema reicht es aus, die Informationen zu studieren, die von den Programmen "usbview.exe" aus dem Windows Driver Kit 7600 oder "USB Descriptor Dumper" bereitgestellt werden . Etwas, das Sie sogar in Ihr Programm kopieren können.





Abb.6 Informationen zu Deskriptoren im Programm "usbview.exe"



Deskriptoren und entsprechende Arrays und Strukturen befinden sich im Flash-Speicher des Mikrocontrollers (Codesegment), da sich diese Daten nicht ändern (Konstanten). Das Speichern von Konstanten im Flash-Speicher ist ein typischer Programmiertrick, mit dem Sie RAM sparen können.



Beachten Sie die Felder Vendor_ID und Product_ID in der Gerätedeskriptorstruktur. Dies ist ein Zahlenpaar, um das USB-Gerät eindeutig zu identifizieren. Um eine solche Nummer für Ihr Gerät zu erhalten, müssen Sie Geld an die USB-IF-Organisation zahlen oder eine Anfrage an den Eigentümer der vorhandenen Vendor_ID (Hersteller von Mikrocontrollern) senden und die Product_ID abrufen. Und Sie können zum Beispiel wie die Chinesen die am besten geeignete VID & PID anderer Leute verwenden. Für Open Source-Projekte besteht die Möglichkeit , eine kostenlose Product_ID zu erhalten .



Ein weiterer Punkt, den Sie bei der Entwicklung von USB-Geräten der MIDI-Streaming-Audioklasse beachten sollten, sind Anschlüsse (Buchse). Konnektoren sind imaginäre (virtuelle) Entitäten zur Beschreibung der Topologie und der Verbindungen zwischen einem Gerät und einem Host. Sie sind Eingang (In Jack) und Ausgang (Out Jack), intern (Embedded) und extern (Extern). Jeder Anschluss hat eine eindeutige Jack_Id (Nummer von 0 bis 15). Die Ausgangsanschlüsse enthalten die Quell-ID-Nummer, d.h. Steckernummer für den Anschluss. Schließlich arbeiten Audio-Endpunkte (EP) über den gebildeten Kanälen (Eingangs- und Ausgangsströme). Dies sind fast gewöhnliche Bulk-EPs, deren Deskriptoren Verbindungsbindungsinformationen enthalten.



Eingebettete und externe Buchsen

Zahl: 7 Buchsen und virtuelle Streams zu USB (MIDI-Klasse).



MIDI Jack Descriptors
	// EMB:  IN Jack #1 <-----> EXT: OUT Jack #4
	// EMB: OUT Jack #3 <-----> EXT:  IN Jack #2

	//--- Class-Specific MS Interface Header Descriptor, p.40
	USB_MIDI_INTERFACE_DESCSIZE,       // bLength, 7 bytes
	USB_CS_INTERFACE_DESCRIPTOR,       // bDescriptorType, 0x24
	MIDI_CS_IF_HEADER,                 // bDescriptorSubtype, 0x01
	0x00,                              // bcdADC(LSB)
	0x01,                              // bcdADC(MSB), 0x0100 (version)
	0x41,                              // wTotalLength(LSB), 65 bytes
	0x00,                              // wTotalLength(MSB)

	//--- MIDI IN JACK EMB(it connects to the USB OUT Endpoint), p.40
	USB_IN_JACK_DESCSIZE,              // bLength, 6 bytes
	USB_CS_INTERFACE_DESCRIPTOR,       // bDescriptorType, 0x24
	MIDI_CS_IF_IN_JACK,                // bDescriptorSubtype, 0x02
	MIDI_JACK_TYPE_EMB,                // bJackType, 0x01 (embedded)
	1,                                 // bJackID, #1
	0,                                 // Jack string descriptor, unused
	//--- MIDI IN JACK EXT, p.40
	USB_IN_JACK_DESCSIZE,              // bLength, 6 bytes
	USB_CS_INTERFACE_DESCRIPTOR,       // bDescriptorType, 0x24
	MIDI_CS_IF_IN_JACK,                // bDescriptorSubtype, 0x02
	MIDI_JACK_TYPE_EXT,                // bJackType, 0x02 (external)
	2,                                 // bJackID, #2
	0,                                 // Jack string descriptor, unused

	//--- MIDI OUT JACK EMB (connects to IN Endpoint), p.41
	USB_OUT_JACK_DESCSIZE,             // bLength, 9 bytes
	USB_CS_INTERFACE_DESCRIPTOR,       // bDescriptorType, 0x24
	MIDI_CS_IF_OUT_JACK,               // bDescriptorSubtype, 0x03
	MIDI_JACK_TYPE_EMB,                // bJackType, 0x01
	3,                                 // bJackID
	1,                                 // bNrInputPins
	2,                                 // baSourceID, this <=> Jack #2
	1,                                 // baSourcePin
	0,                                 // iJack, unused
	//--- MIDI OUT JACK EXT, p.41
	USB_OUT_JACK_DESCSIZE,             // bLength, 9 bytes
	USB_CS_INTERFACE_DESCRIPTOR,       // bDescriptorType, 0x24
	MIDI_CS_IF_OUT_JACK,               // bDescriptorSubtype, 0x03
	MIDI_JACK_TYPE_EXT,                // bJackType, 0x02
	4,                                 // bJackID
	1,                                 // bNrInputPins
	1,                                 // baSourceID, this <=> Jack #1
	1,                                 // baSourcePin
	0,                                 // iJack, unused




Der Datenaustausch in einem Audiogerät der USB-MIDI-Klasse besteht in der Übertragung von 32-Bit-Paketen (USB-MIDI-Ereignispaket). Nachrichten von 1, 2 oder 3 Bytes werden vom MIDI-Gerät empfangen. Bei der Übertragung über USB wird diesen Bytes ein Kopfbyte mit einer Kabelnummer und einem Befehlscode hinzugefügt. Wenn das Paket weniger als 4 Bytes umfasst, wird es mit 0 aufgefüllt. In der aktuellen Firmware-Version fülle ich bis zum 32-Bit-Rand keine Nullen. Es klappt. Die Frage bleibt offen.



In Kabel 1 wird beispielsweise der Befehl zum Drücken der Note-On-Taste (Übertragungszeit 960us) in das folgende Paket konvertiert:

MIDI: 0x90 0x60 0x7f => USB: 0x19 0x90 0x60 0x7f


USB-MIDI Event Packet

Abb. 8 Schema des USB-MIDI-Event-Pakets aus der USB-Spezifikation.



typedef union
{
	struct PACKET
	{
		uint8_t  cable : 4;            // Cable Number (we use #0)
		uint8_t  cin   : 4;            // Code Index Number (cmd: 0x08)
		uint8_t  cmd;                  // MIDI command (status byte)
		uint8_t  data1;                // MIDI data byte #1
		uint8_t  data2;                // MIDI data byte #2
	};
	uint8_t buffer[sizeof(struct PACKET)];
} MIDI_EVENT_PACKET;


Die direkte und umgekehrte Konvertierung erfolgt über die Funktionen MIDI2USB () und USB2MIDI () . In diesen Funktionen wird eine Zustandsmaschine verwendet, wenn die Funktion beim Eintreffen von Eingabedaten vom Wartezustand (IDLE) in den Zustand des Empfangs von Befehlen (STATUS) und dann in den Zustand des Empfangens von Daten (DATA) übergeht und schließlich Daten mit einer Rückkehr in ihren ursprünglichen Zustand sendet Erwartungen.



Im MIDI-Protokoll sind die Datenbytes im Wesentlichen 7-Bit (0..127). Sie haben immer das höchstwertige 8. Bit auf 0 gesetzt. Befehle (Statusbytes) kommen dagegen immer mit dem höchstwertigen Bit auf 1 gesetzt, d. H. haben Werte von 128 bis 255.



Arten von MIDI-Bytes

Abb. 9 Arten von Bytes im MIDI-Protokoll.



Scherz über die Ziffernkapazität von Zahlen
:

— , ?

— H, .

— , 11-22-33?

— H, 11-22-34.

— H ! , !


Alle Schemata und Quellcodes sowie die fertige Firmware befinden sich in meinem Git-Repository . MIT-Lizenz.



Software



Nach der Installation der Karte sollte der Mikrocontroller programmiert werden. Zu diesem Zweck können Sie entweder einen proprietären / geklonten SiLabs C2-Debug-Adapter oder J-Link v10 + (mit EFM8-Unterstützung) oder einen werkseitig geflashten Bootloader (Revision Rev-B) oder schließlich Arduino mit einem geeigneten Skript verwenden. Zum Überprüfen und Debuggen von MIDI-Nachrichten ist MIDI-OX eine große Hilfe .



MIDI-OX

Abb. 10 MIDI-OX-Programmschnittstelle.



Wenn Sie mit Cubase arbeiten, sollten Sie die Asio-Treiber installieren, da bei Verwendung von DirectSound und DirectInput eine Verzögerung zwischen dem Drücken einer Taste und dem Spielen einer Note auftritt. Die Latenz hängt nicht mit der Hardware zusammen und ist ein Merkmal der Betriebssystemimplementierung. Im Allgemeinen erfüllt das Gerät seine Funktionen perfekt mit dem Casio CDP-100-Instrument.



Cubase MIDI-Konfiguration

Abb. 11 Cubase 5-Schnittstelle.



Die experimentelle Firmware erzeugte den größtmöglichen Strom von Noten und anderen MIDI-Befehlen. Die Kakophonie war schrecklich, aber alles funktionierte wie beabsichtigt. Und mit MuseScore 3.2 können Sie Mid-Dateien aufnehmen und abspielen.



Letzter Witz
1990-. . — . . :

— , !

— , ! — !

— ! !

— … . !

— ! !

. . , , , … . , . :

— , , ?


Arbeitsergebnisse



Der Adapter funktioniert! Es scheint, dass ich es geschafft habe, einen guten MIDI-zu-USB-Wandler zu machen. Für mein Gerät habe ich ein Gehäuse, einige Teile und Kabel von einem chinesischen Adapter verwendet. Der Mini-USB-Anschluss landete tief im Gehäuse und ich musste das USB-Kabel wiederholen und mit einer Datei arbeiten. Die LEDs passen, obwohl in einem Winkel, fest in die Löcher. Das Board muss für den chinesischen Fall modifiziert werden.



Mini-USB-Kabel

Zahl: 12. Kompakter, zerlegter Mini-USB-Stecker.



Die Entscheidung, den 8-Bit-Mikrocontroller EFM8UB20 zu verwenden, mag einigen kontrovers erscheinen. Natürlich gibt es auch andere Optionen und Controller. Eine alternative Möglichkeit besteht darin, eine reine Hardwarelösung für den CH345-Konverter zu wählen und das Gerät gemäß der von den Chinesen empfohlenen Referenzschaltung herzustellen. Aber meine Version ist universell, tk. Mit dieser Option können Sie die Firmware ändern, die gewünschte Funktionalität hinzufügen oder gefundene Fehler beheben. Am Ende habe ich durch das abgeschlossene Projekt Wissen, Erfahrung und moralische Zufriedenheit gewonnen. Und schließlich habe ich meinen Artikel fertiggestellt und Sie haben ihn gelesen.



Nützliche Links





Vielen Dank für Ihre Aufmerksamkeit.



All Articles