MIDI- und DirectMusic-Komponenten
Anwendungsprogramme basieren auf einer Kombination aus Benutzer- und Kernelmoduskomponenten, um MIDI- und DirectMusic-Streams zu erfassen und wiederzugeben.
Eine Anwendung kann eine der folgenden Softwareschnittstellen für die MIDI-Wiedergabe und -Aufnahme verwenden:
Microsoft Windows Multimedia midiOutXxx und midiInXxx Funktionen
DirectMusic-API
Das Verhalten der Funktionen midiOutXxx und midiInXxx basiert auf den Funktionen von älteren MIDI-Treibern und -Geräten. Ab Windows 98 übersetzt der WDMAud-Systemtreiber Aufrufe dieser Funktionen in Befehle in WDM-Audiotreiber. Durch die Nachahmung des Verhaltens älterer Software und Hardware opfern die MidiOutXxx - und midiInXxx-Funktionen jedoch das Präzise timing und die erweiterte Funktionalität, die jetzt über die DirectMusic-API verfügbar sind. Weitere Informationen zu DirectMusic und den MIDI-Funktionen von Windows Multimedia finden Sie in der Microsoft Windows SDK-Dokumentation.
DirectMusic und die Windows Multimedia MIDI-Funktionen sind Clients des SysAudio-Systemtreibers, der die Audiofilterdiagramme erstellt, die die MIDI- und DirectMusic-Streams verarbeiten. Die Grapherstellung ist für die Anwendungen transparent, die diese Softwareschnittstellen verwenden.
MIDI-Komponenten
Die folgende Abbildung zeigt die Komponenten des Benutzermodus und des Kernelmodus, die eine MIDI-Anwendung zum Wiedergeben von MIDI-Daten verwendet. Diese Anwendung ist über die midiOutXxx-Funktionen , die in der WinMM-Systemkomponente implementiert sind, Winmm.dll an die WDM-Audiotreiber an schnittstellen.
Die MIDI-Anwendung in der vorherigen Abbildung liest zeitstempelte MIDI-Ereignisse aus einer MIDI-Datei und gibt sie ab. Die MIDI- und DMus-Miniporttreiber werden als abgedunkelte Felder angezeigt, um anzugeben, dass es sich um vom Hersteller bereitgestellte Komponenten handelt. Bei Bedarf kann ein Anbieter einen der vom System bereitgestellten Miniporttreiber ( FMSynth, UART oder DMusUART) verwenden, anstatt einen benutzerdefinierten Miniporttreiber zu schreiben. Alle anderen Komponenten in der Abbildung werden vom System bereitgestellt.
Die Standard Schleife einer typischen MIDI-Wiedergabeanwendung ruft timeSetEvent auf, um das nächste Note-On- oder Note-Off-Ereignis zu planen. Dieser Aufruf verwendet als einen seiner Parameter einen Funktionszeiger auf die Rückrufroutine der Anwendung. Wenn das Ereignis auftritt und das Betriebssystem die Rückrufroutine aufruft, ruft diese Routine midiOutShortMsg auf, um eine oder mehrere geplante Notizen zu aktivieren oder zu deaktivieren. Die midiOutShortMsg-Funktion speichert die MIDI-Nachrichten in seitengesperrten Datenpuffern, um das Ausblättern dieses Speichers während eines Anrufs zu vermeiden. Weitere Informationen zu den Aufrufen timeSetEvent und midiOutShortMsg finden Sie in der Microsoft Windows SDK-Dokumentation.
WDMAud, das aus Benutzer- und Kernelmoduskomponenten (Wdmaud.drv und Wdmaud.sys) besteht, zeichnet die Zeiten auf, zu denen die UN-MIDI-Nachrichten der midiOutShortMsg-Aufrufe eintreffen. WDMAud kombiniert diese Zeitstempel mit den MIDI-Nachrichten, um den MIDI-Stream zu generieren, den es an eine der Kernelmoduskomponenten sendet, die unter WDMAud in der Abbildung angezeigt werden.
Beim Erstellen des Audiofilterdiagramms für die MIDI-Anwendung wählt SysAudio nur eine der drei möglichen Verbindungen aus– mit SWMidi, dem MIDI-Port oder dem DMus-Porttreiber, die in der vorherigen Abbildung angezeigt werden. Wenn die Anwendung das STANDARD-MIDI-Gerät auswählt, sucht SysAudio zunächst nach einem Synthesizergerät, dessen MIDI- oder DMus-Miniporttreiber über einen MIDI-Pin verfügt. Wenn es kein solches Gerät in der Registrierung findet, verwendet SysAudio stattdessen den SWMidi-Systemtreiber (Swmidi.sys). SWMidi ist ein KS-Filter, der einen wavetable-Synth in Software implementiert und nur ein Gerät benötigt, das einen Wave-Audiostream rendern kann.
SWMidi mischt alle Stimmen zusammen, um einen PCM-Stream mit einer einzelnen Welle zu erzeugen, den es an den KMixer-Systemtreiber ausgibt. KMixer wiederum übergibt einen PCM-formatierten Wellenstrom an ein WaveCyclic- oder WavePci-Gerät, dessen Port- und Miniporttreiber in der unteren linken Ecke der Abbildung angezeigt werden. Alternativ kann KMixer seinen Ausgabestream an ein USB-Audiogerät übergeben, das vom USBAudio-Klassensystemtreiber gesteuert wird (nicht in abbildung dargestellt).
In der vorherigen Abbildung übernimmt der MIDI-Porttreiber den zeitstempelten MIDI-Stream von WDMAud und konvertiert ihn in unformatierte MIDI-Nachrichten, die der MIDI-Miniporttreiber über das Synthesizergerät abspielt. Der MIDI-Porttreiber enthält einen Sequenzer, der in der Software implementiert ist und in der Lage ist, die unformatierten MIDI-Nachrichten mit einer Timerauflösung von einer Millisekunde zu planen.
Der DMus-Porttreiber ist in der Lage, eine viel höhere Timinggenauigkeit als der MIDI-Porttreiber zu erzielen, wenn das Synthesizergerät einen Hardwaresequenzer enthält. In diesem Fall sollte der DMus-Miniporttreiber einen Hardwarepuffer angeben, der groß genug ist, um den Jitter zu absorbieren, der sich aus dem Wettbewerb um CPU-Zeit mit ISRs (Unterbrechungsdienstroutinen) und anderen Vorgängen mit hoher Priorität ergibt. Die Zeitstempel im MIDI-Stream, die der DMus-Porttreiber an den Miniporttreiber ausgibt, sind 64-Bit-Werte mit einer Auflösung von 100 Nanosekunden.
Wenn der DMusic-Synth nicht über einen Hardwaresequenzer verfügt, muss er sich auf den Softwaresequenzer des DMus-Porttreibers verlassen, der wie der MIDI-Porttreiber eine Timerauflösung von einer Millisekunde aufweist.
Ein Adaptertreiber erstellt einen MIDI- oder DMus-Porttreiber, indem PcNewPort mit dem GUID-Wert CLSID_PortMidi bzw. CLSID_PortDMus aufgerufen wird. In Windows XP und höher teilen sich die MIDI- und DMus-Porttreiber die gleiche Softwareimplementierung.
Am unteren Rand der vorherigen Abbildung werden die Namen der vom System bereitgestellten Miniporttreiber FMSynth, UART und DMusUART angezeigt, die in Portcls.sys enthalten sind. Ein Adaptertreiber erstellt einen dieser Miniporttreiber durch Aufrufen von PcNewMiniport. FMSynth und UART stellen IMiniportMidi-Schnittstellen bereit, und DMusUART stellt eine IMiniportDMus-Schnittstelle bereit. Beachten Sie, dass UART jetzt veraltet ist (nach Windows 98 Gold) und nur für vorhandene Treiber unterstützt wird. Neue Adaptertreiber sollten stattdessen DMusUART (in Windows 98 SE und höher und in Windows 2000 und höher) verwenden, wodurch eine Übermenge der UART-Funktionalität implementiert wird. DMusUART ist ein Beispiel für einen DMus-Miniporttreiber, der weder DLS-Downloads noch Hardwaresequenzierung unterstützt. Der Quellcode für die FMSynth- und DMusUART-Miniporttreiber ist in den Beispiel-Audiotreibern im Windows Driver Kit (WDK) verfügbar.
Die folgende Abbildung zeigt die Komponenten des Benutzermodus und des Kernelmodus, die ein MIDI-Anwendungsprogramm zum Erfassen von MIDI-Daten verwendet. Diese Anwendung ist über die midiInXxx-Funktionen mit den WDM-Audiotreibern kompatibel.
In der vorherigen Abbildung werden die MIDI- und DMus-Miniporttreiber als abgedunkelte Felder angezeigt, um anzugeben, dass es sich um vom Hersteller bereitgestellte Komponenten handelt. Bei Bedarf kann ein Anbieter stattdessen einen der vom System bereitgestellten Miniporttreiber verwenden, UART oder DMusUARTCapture. Alle anderen Komponenten in der Abbildung werden vom System bereitgestellt.
Die Quelle der MIDI-Daten ist in der Regel ein MPU-401-Gerät. Durch Aufrufen von PcNewMiniport kann ein Adaptertreiber einen der vom System bereitgestellten Miniporttreiber, UART oder DMusUARTCapture, erstellen, um MIDI-Daten von einem MPU-401-Gerät zu erfassen. Auch hier ist UART veraltet, und neue Treiber sollten stattdessen DMusUARTCapture (in Windows 98 SE und höher und in Windows 2000 und höher) verwenden.
Jedes Mal, wenn ein MIDI-Note-On- oder Note-Off-Ereignis auftritt, fügt der MIDI- oder DMusic-Capture-Miniporttreiber (unten in der vorherigen Abbildung) der MIDI-Nachricht einen Zeitstempel hinzu, bevor er ihn zum MIDI-Stream hinzufügt, der zum MIDI- oder DMus-Porttreiber fließt.
Der MIDI- oder DMusic-Aufnahmeporttreiber gibt einen zeitstempelten MIDI-Stream an Wdmaud.sys aus, der Kernelmodushälfte des WDMAud-Systemtreibers. Die Benutzermodushälfte, Wdmaud.drv, gibt den zeitstempelten MIDI-Stream über die midiInXxx-Funktionen an das Anwendungsprogramm aus, die in Winmm.dll implementiert werden.
Die MIDI-Anwendung oben in der Abbildung schreibt zeitstempelte MIDI-Ereignisse in eine MIDI-Datei. Zu dem Zeitpunkt, zu dem die Anwendung midiInOpen aufruft , um den MIDI-Eingabestream zu öffnen, übergibt sie einen Funktionszeiger an die Rückrufroutine. Wenn ein Note-On- oder Note-Off-Ereignis auftritt, ruft das Betriebssystem die Rückrufroutine mit einem Datenblock auf, der mindestens eine zeitstempelte MIDI-Nachricht enthält. Die Zeitstempel für diese Nachrichten sind im Wesentlichen dieselben, die der MIDI- oder DMus-Miniporttreiber ursprünglich generiert hat.
DirectMusic-Komponenten
Die folgende Abbildung zeigt die Benutzer- und Kernelmoduskomponenten, die von einem DirectMusic-Anwendungsprogramm zum Wiedergeben oder Erfassen von MIDI-Daten verwendet werden.
Die Wiedergabekomponenten werden in der linken Hälfte der vorherigen Abbildung angezeigt, und die Aufnahmekomponenten werden auf der rechten Seite angezeigt. Die DMus-Miniporttreiber werden als abgedunkelte Felder angezeigt, um anzugeben, dass es sich um vom Hersteller bereitgestellte Komponenten handelt. Bei Bedarf kann ein Anbieter stattdessen einen der vom System bereitgestellten Miniporttreiber verwenden, DMusUART oder DMusUARTCapture. Die anderen Komponenten in der Abbildung werden vom System bereitgestellt.
In der oberen linken Ecke der Abbildung leitet eine DirectMusic-Anwendung einen zeitstempelten MIDI-Stream aus einer Datei an die Benutzermodus-DirectMusic-Systemkomponente (DMusic.dll) weiter, wodurch der Stream wiederum an einen DMus-Porttreiber geleitet wird. Dieser Treiber kann an den Miniporttreiber für ein DirectMusic-Synth- oder MPU-401-Gerät gebunden werden, sofern verfügbar. Alternativ kann der Porttreiber an den DMusic-Systemtreiber (Dmusic.sys) gebunden werden, bei dem es sich um einen vom System bereitgestellten DMus-Miniporttreiber handelt, der einen DLS-fähigen Wavetable-Synth in Software implementiert und nur ein Gerät benötigt, das einen Wave-Audiostream rendern kann.
Wie SWMidi mischt der DMusic-Treiber, Dmusic.sys, alle stimmen zusammen, um einen einzelnen PCM-formatierten Wellenstrom zu erzeugen, den er an KMixer ausgibt. KMixer wiederum kann einen Wellenstrom an ein Wellengerät übergeben, dessen Port- und Miniporttreiber in der unteren linken Ecke der Abbildung angezeigt werden, oder an ein USB-Audiogerät, das vom USBAudio-Systemtreiber gesteuert wird, der in der Abbildung nicht angezeigt wird.
Die DirectMusic-Erfassungskomponenten werden in der rechten Hälfte der vorherigen Abbildung angezeigt. Der DMusic-Capture-Miniporttreiber in der unteren rechten Ecke der Abbildung steuert die Erfassungshardware und zeitstempelt jede MIDI-Nachricht, die er aufzeichnet. Der DMus-Porttreiber leitet den zeitstempelten MIDI-Stream an die DirectMusic-Komponente des Benutzermodus weiter, DMusic.dll. Die Anwendung greift über die DirectMusic-API auf diesen Stream zu und schreibt die zeitstempelten MIDI-Daten in eine Datei.
Ein Adaptertreiber kann den vom System bereitgestellten DMusUARTCapture-Miniporttreiber verwenden, um ein MPU-401-Erfassungsgerät zu steuern. Der Adaptertreiber erstellt diesen Miniporttreiber, indem PcNewMiniport mit dem GUID-Wert CLSID_DMusUARTCapture aufgerufen wird. Das resultierende Miniporttreiberobjekt unterstützt eine IMiniportDMus-Schnittstelle . Der Quellcode für den DMusUARTCapture-Miniporttreiber ist in den Beispiel-Audiotreibern im Windows Driver Kit (WDK) verfügbar.
Eine DirectMusic-Anwendung kann bei Bedarf auch über ein midiOutXxx-Gerät wie SWMidi (Swmidi.sys) ausgeführt werden. Der Einfachheit halber wird dieser Pfad in der vorherigen Abbildung weggelassen. Der DMusic-Treiber (Dmusic.sys) erfordert einen ersten DLS-Download, um ordnungsgemäß zu funktionieren. Die Verwendung von SWMidi vermeidet diese Anforderung.