12
votes

Événements de tir à la résolution microseconde pour le séquenceur MIDI

Y a-t-il un moyen de tirer des événements en C # à une résolution de quelques microsecondes?

Je construis un séquenceur MIDI, et il faut que un événement soit viré chaque coche MIDI, qui jouera ensuite n'importe quelle note enregistrée à cette époque.

À 120 battements par minute et à une résolution de 120 ppqn (impulsions par battement / trimestre), cet événement devrait tirer tous les 4,166666 millisecondes. Les séquenceurs modernes ont des résolutions plus élevées telles que 768PQN, ce qui obligerait cet événement à tirer tous les 651 microsecondes.

La meilleure résolution pour les événements à court terme que j'ai trouvés est de 1 milliseconde. Comment puis-je aller au-delà de cela?

Ce problème doit déjà avoir été résolu par n'importe quel séquenceur C # MIDI ou lecteur de fichiers MIDI. Peut-être que je ne regarde pas le problème à travers l'angle droit.

Merci pour votre aide.


4 commentaires

Je ne suivez pas vos maths. Si 120ppqn = 41.6666ms, sûrement 768ppqn! = 651Microsec, mais 768PPQn = 1000 * 41.6666 * 120/768 = 6510 Microsec?


120 BPM = 1 battement tous les 500 ms, 120 tique par battement = 500ms / 120 = 4.166ms et 768 tique par temps = 500ms / 768 = 0,651ms Il y a bien une faute de frappe dans mon premier numéro, je vais le corriger maintenant. Merci.


Merci à tous d'avoir pris le temps de m'aider. Chaque réponse m'a appris quelque chose d'intéressant. La solution est en effet d'abandonner les millisecondes et des microsecondes et d'utiliser des échantillons. Comme 1 échantillon d'audio 44100KHz est égal à 1/44100 d'une seconde, une précision de 22,67 microsecondes peut être obtenue.


@Brice: Je sais, ce questin est vieux, mais avez-vous trouvé une solution et qu'est-ce que c'est? Mon problème est essentiellement la même chose. Par exemple, un événement pour une note de 1/64 à 120 BPM doit être joué toutes les 31,25 millisecondes ou pour une note de 1/32 toutes les 62,5 millisecondes. Comment mesurez-vous à moitié et à quart de millisecondes? Avez-vous utilisé une minuterie ou une chronomètre? Comment mesurez-vous des échantillons?


4 Réponses :



4
votes

Je pense que vous êtes peu probable d'obtenir exactement la résolution correcte d'une minuterie. Une meilleure approche serait d'utiliser la minuterie précise de 1 ms et lorsqu'elle tire, de vérifier quels événements MIDI sont en attente et de les tirer.

Ainsi, les événements MIDI vont dans une file d'attente triée, vous allongez le premier et définissez la minuterie au feu aussi près que possible de cette époque. Lorsque la minuterie incendie, consommez tous les événements de la file d'attente qui se sont écoulés, jusqu'à ce que vous rencontriez un événement futur. Calculer le temps à cet événement. Reporter la minuterie.

Bien sûr, si vous émettez à votre carte son, l'approche est fondamentalement différente et vous devez compter des échantillons pour tous vos horaires.


0 commentaires


2
votes

Il n'est pas possible d'avoir des événements virés avec précision sur des intervalles de microseconde dans .NET.

En fait, car Windows elle-même n'est pas un système d'exploitation en temps réel, effectuant quelque chose avec une précision de 100% à certaines microsecondes, dans le mode de mode utilisateur, est presque impossible.

Pour plus d'informations sur la raison pour laquelle cela est si difficile, voir l'article MSDN Magazine: Implémentez une mise à jour en permanence, un fournisseur de temps haute résolution pour Windows . Bien qu'il parle de Windows NT, cela s'applique toujours généralement aux versions ultérieures de Windows.

La conclusion de cet article résume bien:

Si vous pensez maintenant que vous pouvez obtenir le temps système avec un presque précision arbitraire ici, juste un léger avertissement: n'oubliez pas le préempteur d'un multitâche système tel que Windows NT. Dans le meilleur cas, l'horodatage que vous obtiendrez est éteint par le temps qu'il faut pour lire le Compteur de performance et transformez ceci lire dans un temps absolu. Dans le les pires cas, le temps écoulé pourrait facilement être dans l'ordre des dizaines de millisecondes.

Bien que cela puisse indiquer que vous avez traversé tout cela Pour rien, soyez assuré que vous N'a pas. Même exécuter l'appel au Win32 API GetSystemTimeasFileTime (ou GettimeOdday sous Unix) est sujet à les mêmes conditions, vous êtes donc réellement ne pas pire que ça. Dans une majorité des cas, vous aurez bons résultats. Juste ne pas jouer tout ce qui nécessite un temps réel prévisibilité sur la base du temps Timbres dans Windows NT.


1 commentaires

Cela devrait dire "en mode utilisateur", pas "dans le logiciel", car les pilotes de noyau sont également logiciels et sont certainement capables de calmer / latence sous-microseconde.