[PYTHON] Problème de mappage de la police sonore

Cet article est tiré du Music Tools / Libraries / Technologies Advent Calendar 2019 12/24.

(Cette fois, je l'ai préparé à la hâte, donc ça ne correspond peut-être pas un peu à l'objectif. L'année prochaine, j'aimerais faire ma propre source sonore et compression de voix.

introduction

J'utilise DTM depuis longtemps avec la combinaison de Music Studio Producer, qui a été introduit il y a 10 ans, et Timidity ++ et SoundFont, qui a été introduit il y a 8 ans. Cependant, en raison du problème de compatibilité entre le pilote MIDI de Timidity qui n'a pas été mis à jour et Windows 10, nous avons finalement décidé de supprimer Timidity ...

Il y a dix ans, j'ai créé un fichier de mappage manuellement, mais au cours des 10 dernières années, j'ai pris en charge la programmation, donc cette fois je parle d'essayer d'obtenir un environnement DTM confortable avec la puissance du programme.

Cartographie des polices sonores

Lorsque vous utilisez une police sonore dans une DAW qui ne peut gérer que le MIDI, utilisez une source sonore virtuelle qui peut utiliser une police sonore telle que Timidity comme source sonore MIDI. La tonalité de la police sonore peut être spécifiée en combinant ** le numéro de banque et le numéro de présélection **, et n'importe quelle tonalité de la police sonore peut être spécifiée par message MIDI pour correspondre à ** la sélection de banque et le changement de programme ** de MIDI. Tu peux choisir.

Cependant, si plusieurs polices sonores sont utilisées en même temps, les banques et les numéros de préréglage peuvent entrer en collision et, selon la police sonore, la disposition des tonalités spécifiées par MIDI peut différer considérablement, ce qui est peu pratique et le mappage est effectué.

Heureusement, Timidity a cette fonctionnalité et nous l'avons placée pour la facilité d'utilisation. (Puisque je l'utilisais en tant qu'utilisateur à ce moment-là, bien sûr, je ne connaissais pas le format de fichier de la police sonore, et je ne connaissais pas le MIDI.)

Placez les tonalités sur Excel dans un espace de 256 * 256 et faites correspondre le fichier de réglage de la timidité et le fichier de tonalités DAW (table de correspondance du nom de l'instrument, numéro de programme, numéro de banque. S'il est défini, le nom de l'instrument sera affiché sur l'interface graphique de la DAW. Je l'ai créé parce qu'il est affiché.) Je l'ai écrit à la main. image.png

Il y avait beaucoup de polices sonores que je voulais ajouter, mais je les ai affectées dans Excel et j'ai ajouté le fichier de paramètres à la main ... c'est ennuyeux.

Synthétiseur MIDI virtuel de Timidity

Après une mise à jour majeure de Win10 cet été, Timidity ++ a finalement cessé de fonctionner. En premier lieu, Timidity ++ fonctionne avec un pilote non signé, et il n'a pas été mis à jour, donc j'ai pensé que c'était sur le point d'être la limite et j'ai changé

Nous avons introduit Virtual MIDI Synth comme source sonore MIDI virtuelle pour la destination du transfert.

Cependant, ** il n'y a pas de fonction de mappage de police sonore **. Il est possible de charger des polices sonores à partir de plusieurs fichiers, mais il semble que le son du fichier de police sonore avec une priorité élevée sera utilisé en cas de collision. C'était un problème.

Réécrivons donc le fichier de police sonore pour éviter les collisions, puis générons automatiquement la carte des tons. <Longue introduction

spécification

J'ai ajouté la suppression de la couleur de tonalité car certains des fichiers de polices sonores contenaient des données de couleur de ton indésirable, et l'omission du nom de couleur de tonalité a été ajoutée car le nom de la couleur de ton était trop long et l'affichage de la DAW est devenu étrange.

Notez que les fichiers de configuration de Music Studio Producer et Virtual MIDI Synth ne sont pas expliqués ici.

Structure des fichiers de polices sonores

Spécifications: http://freepats.zenvoid.org/sf2/sfspec24.pdf

Les polices sonores sont stockées au format RIFF. RIFF stocke les données dans des unités appelées morceaux, et les morceaux se composent d'ID, de taille et de données.

Structure RIFF

** Structure de base des morceaux **

article Taille Remarques
ID de bloc 4byte Identificateur de bloc(RIFF/LISTE etc.)
Taille des données 4byte Taille des données (petit tordien))
Les données Nbyte

En outre, le premier bloc, le bloc RIFF et le bloc LIST, qui combine plusieurs blocs, sont préparés sous forme de blocs spéciaux. (Les blocs autres que RIFF et LIST ne peuvent pas contenir de blocs.)

** Structure de bloc RIFF **

article Taille Remarques
ID de bloc 4byte RIFF
Taille des données 4byte N+4
Identificateur de fichier 4byte Identifiant des données stockées dans le fichier RIFF(Pour les polices sonores sfbk)
Les données Nbyte Contient des morceaux et des morceaux de liste

** Structure de bloc de LISTE **

article Taille Remarques
ID de bloc 4byte LIST
Taille des données 4byte N+4
Identifiant de liste 4byte Identifiant des données stockées dans la liste(INFO/données etc.)
Les données Nbyte Contient des morceaux et des morceaux de liste

Les fichiers RIFF peuvent utiliser ces blocs pour représenter des données de structure imbriquées. image.png

Étant donné que la taille de la partie de données est écrite au début de tous les blocs, les blocs inutiles peuvent être ignorés. Par conséquent, le but peut être atteint en implémentant que seuls les morceaux liés au numéro de banque et au numéro prédéfini des morceaux de la police sonore sont traités et les morceaux suivants sont sautés tels quels.

Structure RIFF du fichier son

La structure RIFF de la police sonore est la suivante. Parmi ceux-ci, les blocs sous pdta contiennent le nom de l'instrument et le numéro de préréglage. image.png

pdta contient des sous-blocs pour ** préréglages **, ** instruments ** et ** échantillons **. Parmi ceux-ci, un instrument est une unité qui est utilisée dans une police sonore comme une unité qui combine plusieurs échantillons, et un préréglage est une unité qui est utilisée par un utilisateur en tant que groupe de plusieurs instruments. Par conséquent, cette fois, nous n'utiliserons que des sous-blocs liés aux préréglages.

Notez que les sous-blocs sont stockés sous forme de tableau de structures et que la valeur à la fin est une valeur spéciale qui indique la fin. De plus, la taille est un multiple entier de sizeof (structure).

sous-bloc phdr

Le sous-bloc phdr contient des informations d'en-tête (nom de l'instrument prédéfini, banque, numéro de preset, etc.).

struct phdr {
  char achPresetName[20];  //Nom du préréglage null terminaison ascii
  WORD wPreset;  //Numéro de préréglage
  WORD wBank;  //Numéro de banque 0~127 pour instruments de musique 128 pour percussions
  WORD wPresetBagNdx;  //index au début de pbag
  DWORD dwLibrary; //Réservation 0
  DWORD dwGenre; //Réservation 0
  DWORD dwMorphology; //Réservation 0
}

Notez que wPresetBagNdx doit être incrémenté dans l'ordre depuis le début de phdr.

Au départ, j'ai négligé cette spécification, et j'ai pensé qu'il serait correct de réécrire uniquement les phdr et de supprimer les fichiers inutiles, et à la suite de sa mise en œuvre, un son différent a été entendu. Les sous-blocs pbag, pmod et pgen doivent également être modifiés pour répondre à cette spécification.

La valeur de la fin (EOP) de phdr est la suivante.

Nom de variable valeur
achPresetName EOP
wPreset 0
wBank 0
wPresetBagNdx index à la fin de pbag
dwLibrary 0
dwGenre 0
dwMorphology 0

sous-bloc pbag

Le sous-bloc pbag contient des informations qui indiquent la modulation (pmod) et le générateur (pgen) à utiliser dans le préréglage. L'association entre un préréglage et pbag est du pbag pointé par wPresetBagNdx d'un préréglage vers le pbag de wPresetBagNdx-1 du préréglage suivant. (Par conséquent, il est possible d'associer plusieurs pbags à un préréglage)

struct pbag {
  WORD wGenNdx;  //index au début de pgen
  WORD wModNdx; //index au début de pmod
}

Comme phdr, wGenNdx et wModNdx doivent être incrémentés depuis le début du pbag.

La valeur à la fin de pbag est la suivante.

Nom de variable valeur
wGenNdx index à la fin de pgen
wModNdx index à la fin de pmod

sous-bloc pgen

Le sous-bloc pgen stocke les informations de paramètres (générateurs) telles que les instruments, les volumes et les filtres associés aux préréglages.

Le contenu est au format de valeur de clé des types et valeurs de paramètres.

struct pgen {
  WORD sfGenOper; //Type de paramètre
  WORD genAmount;  //Valeur du paramètre
}

Notez que genAmount contient deux valeurs de type octet, court ou mot, selon le type de paramètre. (La taille est fixée au mot.)

La valeur à la fin de pbag est la suivante.

Nom de variable valeur
sfGenOper 0
genAmount 0

sous-bloc pmod

Le sous-bloc pmod contient des informations qui associent la manière dont le son change (changement de volume, filtres) à partir de paramètres dynamiques tels que les changements de contrôle MIDI et les vélocités.

struct pmod {
  WORD sfModSrcOper; //Type de paramètre de source de modulation(CC, vitesse, etc.
  WORD sfModDestOper; //Types de paramètres à utiliser(Volume, force du filtre, etc.)
  SHORT modAmount; //Montant de l'opération
  WORD sfModAmtSrcOper; //Types de paramètres de source de modulation qui modifient la quantité de manipulation de modulation
  WORD sfModTransOper; //Convertir le montant de l'opération d'entrée(Linéaire, courbé)
}

La valeur à la fin de pmod est la suivante.

Nom de variable valeur
sfModSrcOper 0
sfModDestOper 0
modAmount 0
sfModAmtSrcOper 0
sfModTransOper 0

Relation sous-bloc

image.png

En regardant la relation entre chaque sous-bloc, cela ressemble à ceci.

Par exemple, dans l'exemple de cette figure, le preset 0 est associé à bag0 et bag1, bag0 est associé à gen0, gen1 et mod0, et bag1 est associé à gen2 avec mod1 et mod2, donc le générateur utilisé dans le preset est gen0 ~ L'image de gen2 et de la modulation est mod0 ~ mod2.

(Ce n'est peut-être pas correct car il ne lit pas les spécifications, mais il semble que le générateur et la modulation soient associés à chaque sac et produisent un son, mais vous n'avez pas à vous inquiéter tant que vous pouvez toucher le fichier.)

Analyseur de polices sonores

Code source: https://github.com/mmitti/sf2conv/blob/master/riff.py

J'ai créé un script en utilisant Python et le module struct qui peut analyser (une partie de) la structure des polices RIFF et son.

Prend en charge la lecture et l'écriture de blocs RIFF, de blocs LIST, de sous-blocs phdr, pbag, pmod et pgen. De plus, étant donné que les autres blocs ne sont pas modifiés, celui lu est écrit tel quel.

Lors de la suppression de phdr, il est nécessaire de supprimer les correspondants pour pbag, pmod et pgen, de sorte que le processus de mise à jour est effectué au moment de l'écriture.

(Je l'ai implémenté pendant le temps d'attente de l'école de voiture pendant les vacances d'été, mais c'est sale maintenant. RiffRoot ou Element

Un programme qui mappe les polices sonores

Code source: https://github.com/mmitti/sf2conv/blob/master/main.py

J'ai créé un script qui convertit la police sonore à l'aide de l'analyseur Riff ci-dessus (ou plutôt l'analyseur de polices sonores) et crache la carte des tons de MusicStudio Producer et le fichier de réglage de Virtual MIDI Synth.

Écrivez simplement les polices sonores à entrer dans le fichier json, les tonalités à exclure, les règles de remplacement des tonalités, réécrivez le fichier de police sonore en utilisant ceci et crachez les tonalités, les banques et les numéros de programme sur la carte des tonalités. C'est un script.

Il y a des sons avec des noms étranges (tels que ------) et des polices sonores dans lesquelles les systèmes d'instruments à vent sont affectés à des numéros de programme de piano, et en raison de l'augmentation des règles qui peuvent être définies, le nombre d'éléments de réglage a augmenté. Cependant, une fois le fichier de paramètres écrit, les tonalités sont attribuées aux parties vides et ajoutées à la liste des tonalités de la DAW, ce qui facilite l'ajout de nouvelles polices sonores.

en conclusion

Cette fois, parce que l'environnement DTM était endommagé, j'ai dû regarder à l'intérieur de la police sonore, ce qui a un peu approfondi ma compréhension. Depuis que l'ajout de polices sonores est devenu plus facile avec le script, j'ai introduit sinfon, que je voulais utiliser immédiatement, et tapé dans une chanson.

Une fois le périphérique FPGA USB MIDI que je fabrique terminé, j'aimerais créer une source sonore MIDI qui lit les polices sonores, afin que je puisse rechercher et écrire bientôt sur les polices sonores.

à la prochaine

Recommended Posts

Problème de mappage de la police sonore
Problème de probabilité