Dieser Artikel stammt aus Music Tools / Libraries / Technologies Adventskalender 2019 12/24.
(Dieses Mal habe ich es in Eile vorbereitet, sodass es möglicherweise nicht ein wenig zum Zweck passt. Nächstes Jahr möchte ich meine eigene Tonquelle und Sprachkomprimierung durchführen.
Ich benutze DTM seit langer Zeit mit der Kombination aus Music Studio Producer, die vor 10 Jahren eingeführt wurde, und Timidity ++ und SoundFont, die vor 8 Jahren eingeführt wurde. Aufgrund des Kompatibilitätsproblems zwischen dem nicht aktualisierten MIDI-Treiber von Timidity und Windows 10 haben wir uns schließlich entschlossen, Timidity ...
Vor zehn Jahren habe ich eine Zuordnungsdatei manuell erstellt, aber in den letzten 10 Jahren habe ich die Programmierung unterstützt. Dieses Mal spreche ich davon, eine komfortable DTM-Umgebung mit der Leistung des Programms zu schaffen.
Wenn Sie eine Soundschrift in einer DAW verwenden, die nur MIDI verarbeiten kann, verwenden Sie eine virtuelle Soundquelle, die eine Soundschrift wie Timidity als MIDI-Soundquelle verwenden kann. Der Ton der Sound-Schriftart kann durch Kombinieren von ** Banknummer und voreingestellter Nummer ** festgelegt werden, und jeder Ton in der Sound-Schriftart kann durch eine MIDI-Meldung festgelegt werden, die der ** Bankauswahl und Programmänderung ** von MIDI entspricht. Du kannst wählen.
Wenn jedoch mehrere Sound-Schriftarten gleichzeitig verwendet werden, können Bänke und voreingestellte Nummern kollidieren, und je nach Sound-Schriftart kann sich die Anordnung der von MIDI angegebenen Töne erheblich unterscheiden, was unpraktisch ist und eine Zuordnung durchgeführt wird.
Glücklicherweise hat Timidity diese Funktion und wir haben sie zur Vereinfachung platziert. (Da ich es zu diesem Zeitpunkt als Benutzer verwendet habe, kannte ich das Dateiformat der Sound-Schriftart natürlich nicht und war mit MIDI nicht vertraut.)
Platzieren Sie die Töne in Excel in einem Bereich von 256 * 256 und stimmen Sie mit der Einstellungsdatei für die Schüchternheit und der DAW-Tondatei überein (Entsprechungstabelle mit Instrumentenname, Programmnummer, Banknummer. Wenn festgelegt, wird der Instrumentenname auf der DAW-GUI angezeigt. Ich habe es erstellt, weil es angezeigt wird.) Ich habe es von Hand geschrieben.
Es gab viele Sound-Schriftarten, die ich hinzufügen wollte, aber ich habe sie in Excel zugewiesen und die Einstellungsdatei von Hand hinzugefügt ... es ist ärgerlich.
Nach einem großen Update von Win10 in diesem Sommer funktionierte Timidity ++ endlich nicht mehr. Erstens läuft Timidity ++ mit einem nicht signierten Treiber und es wurde nicht aktualisiert, daher dachte ich, es würde bald das Limit sein und umgeschaltet
Wir haben Virtual MIDI Synth als virtuelle MIDI-Soundquelle für das Übertragungsziel eingeführt.
** Es gibt jedoch keine Sound Font Mapping-Funktion **. Es ist möglich, Sound-Fonts aus mehreren Dateien zu laden, aber es scheint, dass der Sound der Sound-Font-Datei mit hoher Priorität im Falle einer Kollision verwendet wird. Das war ein Problem.
Schreiben wir also die Sound-Font-Datei neu, um Kollisionen zu vermeiden, und generieren dann automatisch die Tonzuordnung. <Lange Einführung
Ich habe das Löschen der Tonfarbe hinzugefügt, da einige der Sound-Font-Dateien Müllton-Farbdaten enthielten, und das Weglassen des Tonfarbnamens wurde hinzugefügt, weil der Tonfarbname zu lang war und die DAW-Anzeige seltsam wurde.
Beachten Sie, dass die Konfigurationsdateien Music Studio Producer und Virtual MIDI Synth hier nicht erläutert werden.
Technische Daten: http://freepats.zenvoid.org/sf2/sfspec24.pdf
Sound-Schriftarten werden im RIFF-Format gespeichert. RIFF speichert Daten in Einheiten, die als Chunks bezeichnet werden, und Chunks bestehen aus ID, Größe und Daten.
** Grundstruktur von Brocken **
Artikel | Größe | Bemerkungen |
---|---|---|
Chunk ID | 4byte | Chunk-ID(RIFF/LISTE usw.) |
Datengröße | 4byte | Datengröße (Little Tordian)) |
Daten | Nbyte |
Darüber hinaus werden der erste Block, der RIFF-Block und der LIST-Block, der mehrere Blöcke kombiniert, als spezielle Blöcke vorbereitet. (Andere Chunks als RIFF und LIST dürfen keine Chunks enthalten.)
** RIFF-Blockstruktur **
Artikel | Größe | Bemerkungen |
---|---|---|
Chunk ID | 4byte | RIFF |
Datengröße | 4byte | N+4 |
Dateikennung | 4byte | Kennung der in der RIFF-Datei gespeicherten Daten(Für Soundschriften sfbk) |
Daten | Nbyte | Enthält Chunks und LIST-Chunks |
** LIST Chunk Struktur **
Artikel | Größe | Bemerkungen |
---|---|---|
Chunk ID | 4byte | LIST |
Datengröße | 4byte | N+4 |
Listenkennung | 4byte | Kennung der in der Liste gespeicherten Daten(INFO/Daten usw.) |
Daten | Nbyte | Enthält Chunks und LIST-Chunks |
RIFF-Dateien können diese Blöcke verwenden, um verschachtelte Strukturdaten darzustellen.
Da die Größe des Datenteils am Anfang aller Chunks geschrieben wird, können unnötige Chunks übersprungen werden. Daher kann der Zweck erreicht werden, indem implementiert wird, dass nur die Chunks, die sich auf die Banknummer und die voreingestellte Nummer der Chunks der Soundschrift beziehen, verarbeitet werden und die Chunks danach so wie sie sind übersprungen werden.
Die RIFF-Struktur der Soundschrift ist wie folgt. Von diesen enthalten die Chunks unter pdta den Instrumentennamen und die voreingestellte Nummer.
pdta enthält Unterblöcke für ** Presets **, ** Instrumente ** und ** Samples **. Von diesen ist ein Instrument eine Einheit, die in einer Klangschrift als Einheit verwendet wird, die mehrere Samples kombiniert, und eine Voreinstellung ist eine Einheit, die von Benutzern verwendet werden kann, indem mehrere Instrumente kombiniert werden. Daher werden wir dieses Mal nur voreingestellte Unterblöcke verwenden.
Beachten Sie, dass Unterblöcke als Array von Strukturen gespeichert werden und der Wert am Ende ein spezieller Wert ist, der das Ende angibt. Die Größe ist auch ein ganzzahliges Vielfaches von sizeof (Struktur).
Der phdr-Unterblock enthält Header-Informationen (voreingestellter Instrumentenname, Bank, voreingestellte Nummer usw.).
struct phdr {
char achPresetName[20]; //Voreingestellter Name null Terminierung ascii
WORD wPreset; //Voreingestellte Nummer
WORD wBank; //Banknummer 0~127 für Musikinstrumente 128 für Schlagzeug
WORD wPresetBagNdx; //Index am Anfang von pbag
DWORD dwLibrary; //Reservierung 0
DWORD dwGenre; //Reservierung 0
DWORD dwMorphology; //Reservierung 0
}
Beachten Sie, dass wPresetBagNdx ab dem Beginn von phdr in der Reihenfolge erhöht werden muss.
Anfangs habe ich diese Spezifikation übersehen und dachte, dass es in Ordnung wäre, nur phdr neu zu schreiben und unnötige zu löschen, und als Ergebnis der Implementierung wurde ein anderer Sound zu hören. Die Subchunks pbag, pmod und pgen müssen ebenfalls bearbeitet werden, um diese Spezifikation zu erfüllen.
Der Wert des Endes (EOP) von phdr ist wie folgt.
Variablennamen | Wert |
---|---|
achPresetName | EOP |
wPreset | 0 |
wBank | 0 |
wPresetBagNdx | Index am Ende von pbag |
dwLibrary | 0 |
dwGenre | 0 |
dwMorphology | 0 |
Der pbag-Subchunk enthält Informationen, die angeben, welche Modulation (pmod) und welcher Generator (pgen) in der Voreinstellung verwendet werden sollen. Die Zuordnung zwischen einem Preset und einem Pbag erfolgt von dem Pbag, auf den wPresetBagNdx eines Presets zeigt, zum Pbag von wPresetBagNdx-1 des nächsten Presets. (Daher ist es möglich, mehrere Pbags einem Preset zuzuordnen.)
struct pbag {
WORD wGenNdx; //Index am Anfang von pgen
WORD wModNdx; //Index am Anfang von pmod
}
Wie phdr müssen wGenNdx und wModNdx vom Anfang des Pbags an inkrementiert werden.
Der Wert am Ende von pbag ist wie folgt.
Variablennamen | Wert |
---|---|
wGenNdx | Index am Ende von pgen |
wModNdx | Index am Ende von pmod |
Der pgen-Unterblock speichert Parameterinformationen (Generatoren) wie Instrumente, Volumes und Filter, die Voreinstellungen zugeordnet sind.
Der Inhalt liegt im Schlüsselwertformat der Parametertypen und -werte vor.
struct pgen {
WORD sfGenOper; //Parametertyp
WORD genAmount; //Parameterwert
}
Beachten Sie, dass genAmount je nach Parametertyp zwei Byte-, Kurz- oder Worttypwerte enthält. (Die Größe ist auf Wort festgelegt.)
Der Wert am Ende von pbag ist wie folgt.
Variablennamen | Wert |
---|---|
sfGenOper | 0 |
genAmount | 0 |
Der pmod-Unterblock enthält Informationen, die angeben, wie sich der Klang aufgrund dynamischer Parameter wie Änderungen und Geschwindigkeiten der MIDI-Steuerung ändert (Lautstärke ändert, Filter).
struct pmod {
WORD sfModSrcOper; //Parametertyp der Modulationsquelle(CC, Geschwindigkeit usw.
WORD sfModDestOper; //Arten von Parametern zu betreiben(Volumen, Filterstärke usw.)
SHORT modAmount; //Betriebsmenge
WORD sfModAmtSrcOper; //Arten von Modulationsquellenparametern, die den Umfang der Modulationsmanipulation ändern
WORD sfModTransOper; //Konvertieren Sie den eingegebenen Operationsbetrag(Linear, gebogen)
}
Der Wert am Ende von pmod ist wie folgt.
Variablennamen | Wert |
---|---|
sfModSrcOper | 0 |
sfModDestOper | 0 |
modAmount | 0 |
sfModAmtSrcOper | 0 |
sfModTransOper | 0 |
Wenn man die Beziehung zwischen den einzelnen Unterblöcken betrachtet, sieht es so aus.
In dem Beispiel dieser Figur ist beispielsweise die Voreinstellung 0 mit bag0 und bag1 verknüpft, bag0 ist mit gen0, gen1 und mod0 verknüpft, und bag1 ist mit gen2 mit mod1 und mod2 verknüpft, sodass der in der Voreinstellung verwendete Generator gen0 ~ ist Das Bild von Gen2 und Modulation ist mod0 ~ mod2.
(Es ist möglicherweise nicht korrekt, da es die Spezifikationen nicht liest, aber es scheint, dass der Generator und die Modulation mit jeder Tasche verbunden sind und ein Geräusch erzeugen, aber Sie müssen sich nicht zu viele Sorgen machen, so weit Sie die Datei berühren können.)
Quellcode: https://github.com/mmitti/sf2conv/blob/master/riff.py
Ich habe ein Skript mit Python und dem Strukturmodul erstellt, das die Struktur von RIFF- und Sound-Schriftarten (teilweise) analysieren kann.
Unterstützt das Lesen und Schreiben von RIFF-Chunks, LIST-Chunks, Phdr-, Pbag-, Pmod- und Pgen-Sub-Chunks. Da die anderen Blöcke nicht bearbeitet werden, wird der gelesene so geschrieben, wie er ist.
Beim Löschen von phdr müssen die entsprechenden für pbag, pmod und pgen gelöscht werden, damit der Aktualisierungsvorgang zum Zeitpunkt des Schreibens ausgeführt wird.
(Ich habe es während der Wartezeit der Automobilschule in den Sommerferien implementiert, aber jetzt ist es schmutzig. RiffRoot oder Element
Quellcode: https://github.com/mmitti/sf2conv/blob/master/main.py
Ich habe ein Skript erstellt, das die Sound-Schriftart mit dem obigen Riff-Parser (oder besser gesagt dem Sound-Font-Parser) konvertiert und die Tone Map von Music Studio Producer und die Einstellungsdatei von Virtual MIDI Synth ausspuckt.
Schreiben Sie einfach die in die JSON-Datei einzugebenden Sound-Fonts, die auszuschließenden Töne, die Ersetzungsregeln für die Töne, schreiben Sie die Sound-Font-Datei damit neu und spucken Sie die Töne, Bänke und Programmnummern in die Tones-Map aus. Es ist ein Skript.
Es gibt Sounds mit seltsamen Namen (wie ------) und Soundfonts, in denen Blasinstrumentensysteme Klavierprogrammnummern zugewiesen sind, und infolge der Erhöhung der einstellbaren Regeln hat sich die Anzahl der Einstellungselemente erhöht. Sobald die Einstellungsdatei geschrieben ist, werden die Töne jedoch den leeren Teilen zugewiesen und der DAW-Tondiste hinzugefügt, wodurch das Hinzufügen neuer Sound-Schriftarten erleichtert wird.
Dieses Mal musste ich, da die DTM-Umgebung beschädigt war, in die Soundschrift schauen, was mein Verständnis ein wenig vertiefte. Da das Hinzufügen von Sound-Schriftarten mit dem Skript einfacher geworden ist, habe ich sinfon eingeführt, das ich sofort verwenden wollte, und einen Song eingegeben.
Nachdem das von mir erstellte FPGA-USB-MIDI-Gerät fertiggestellt ist, möchte ich eine MIDI-Soundquelle erstellen, die Sound-Schriftarten liest, damit ich bald nach Sound-Schriftarten suchen und darüber schreiben kann.
Wir sehen uns wieder