Contexte
Les fichiers MIDI sont assez différents des fichiers audio WAV ou MP3. Les fichiers MP3 et WAV contiennent des octets représentant un "enregistrement" de l'audio, tandis que les fichiers MIDI contiennent une série de messages MIDI stockés dans des événements MIDI informant un synthétiseur MIDI de l'instrument virtuel à jouer ou un séquenceur MIDI du tempo de lecture à utiliser. Ces messages sont stockés dans des pistes, et une collection de pistes constitue une séquence MIDI, dont les événements peuvent être analysés par un séquenceur et voir ses messages transmis du séquenceur au récepteur d'un synthétiseur.
La plupart du temps, les messages MIDI stockés dans les événements MIDI sont des messages Note On qui indiquent au synthétiseur de jouer une note particulière ou des messages Note Off qui indiquent au synthétiseur d'arrêter de jouer la note. Ces messages contiennent deux octets de données, dont le premier informe le synthétiseur de la vélocité de la note (une vélocité plus élevée donne une note plus forte), et le second indique au synthétiseur la note à jouer (c'est-à-dire le do moyen). Les événements eux-mêmes contiennent également des ticks qui servent à dire au séquenceur quand envoyer les messages.
Le défi
Le défi consiste à écrire un programme complet ou une fonction qui analyse une série de messages MIDI Note On et Note Off dans une séquence MIDI à piste unique et envoie à STDOUT un graphique indiquant quand certaines notes sont activées, lorsqu'elles sont désactivées et vitesse de ces notes. L'axe vertical du graphique représente la valeur de la note et doit être étiqueté comme décrit ci-dessous, et l'axe horizontal représente le temps en ticks MIDI (bien qu'il ne doit pas être étiqueté pour réduire la complexité et les problèmes d'espacement).
Votre entrée peut être constituée de quatre tableaux ou listes distincts, chacun contenant une série de valeurs entières; un tableau ou une liste bidimensionnelle contenant quatre sous-tableaux / sous-listes avec une série de valeurs entières; ou tout autre moyen pratique; cela représente les événements MIDI de la collection avec des messages Note On et Note Off dans la piste. Les valeurs dans le premier de ces tableaux spécifient la note, la seconde la vélocité, la troisième la coche d'événement de note et la quatrième la coche d'événement de note désactivée. Par exemple, compte tenu de quatre tableaux tels que ceux-ci:
{60, 62, 64, 65, 67}
{20, 40, 60, 80, 100}
{ 0, 4, 8, 12, 16}
{ 2, 6, 10, 14, 18}
L'analyse du premier élément de chaque tableau donne deux événements: un événement au tick 0 avec un message qui a une commande Note On, une note 60 (milieu C) et une vitesse de note de 20; et un événement au tick 2 avec un message qui a une commande Note Off avec la même note et la même vitesse.
Règles
Le graphique doit comporter les chiffres de 0 à 127 affichés dans l'ordre décroissant sur le côté gauche (représentant la valeur de la note), au début de la note, la durée de chaque note (note désactivée moins la note activée) et la vélocité de la note. Les symboles représentant les notes dépendent de leur vélocité:
- 0-15:
O
- 16-31:
=
- 32-47:
#
- 48-63:
-
- 64-79:
@
- 80-95:
+
- 96-111:
0
- 112-127:
*
Vous pouvez supposer ce qui suit:
- Les valeurs de note et de vélocité seront dans la plage [0, 127].
- Les longueurs de chacun des quatre tableaux seront toujours égales.
Voici quelques exemples:
{60, 62, 64, 65, 67}
{20, 40, 60, 80, 100}
{ 0, 4, 8, 12, 16}
{ 2, 6, 10, 14, 18}
127|
126|
125|
...
67 | 00
66 |
65 | ++
64 | --
63 |
62 | ##
61 |
60 |==
59 |
...
2 |
1 |
0 |
{60, 48, 62, 47, 64, 45, 65, 43, 67, 41, 65, 43, 64, 45, 62, 47, 60, 48}
{63, 31, 75, 90, 12, 23, 122, 104, 33, 19, 57, 42, 5, 82, 109, 86, 95, 71}
{0, 0, 2, 2, 4, 4, 6, 6, 8, 8, 10, 10, 12, 12, 14, 14, 16, 16}
{2, 2, 4, 4, 6, 6, 8, 8, 10, 10, 12, 12, 14, 14, 16, 16, 18, 18}
127|
126|
...
68 |
67 | ##
66 |
65 | ** --
64 | OO OO
63 |
62 | @@ 00
61 |
60 |-- ++
59 |
...
49 |
48 |== @@
47 | ++ ++
46 |
45 | == ++
44 |
43 | 00 ##
42 |
41 | ==
40 |
...
1 |
0 |
Voici un exemple qui affiche les premières notes d'Ode à la joie:
{48, 55, 64, 64, 65, 67, 55, 67, 65, 64, 62, 52, 55, 60, 60, 62, 64, 55, 64, 62, 62}
{45, 45, 63, 63, 63, 63, 89, 66, 66, 66, 66, 30, 30, 103, 103, 103, 103, 127, 55, 55, 55}
{ 0, 0, 0, 4, 8, 12, 16, 16, 20, 24, 28, 32, 32, 32, 36, 40, 44, 48, 48, 54, 56}
{16, 16, 2, 6, 10, 14, 32, 18, 22, 26, 30, 48, 48, 34, 38, 42, 46, 64, 50, 55, 64}
127|
...
67 | -- @@
66 |
65 | -- @@
64 |-- -- @@ 00 --
63 |
62 | @@ 00 - --------
61 |
60 | 00 00
59 |
58 |
57 |
56 |
55 |################++++++++++++++++================****************
54 |
53 |
52 | ================
51 |
50 |
49 |
48 |################
...
0 |
Vous pouvez réduire votre score de 25% si votre soumission prend une séquence MIDI réelle en entrée, analyse les messages Note On et Note Off de n'importe quelle piste de votre choix à condition qu'elle contienne au moins quatre événements avec des messages Note On et Note Off, et des sorties un tableau tel que décrit ci-dessus.
C'est le golf de code, donc le code le plus court gagne. Bonne chance!
Ruby, 106 octets
C'était amusant. Je ne sais pas pourquoi personne ne l'a essayé.
Cette fonction prend l'entrée comme quatre arguments de tableau et renvoie un tableau de chaînes, une pour chaque ligne du graphique.
Remarque: Cela suppose arbitrairement qu'il n'y aura pas plus de 10 000 ticks. Si vous l'exécutez dans votre terminal, je vous suggère de le canaliser pour
less
pouvoir faire défiler horizontalement. Vous pouvez changer1e4
si vous voulez plus de ticks,9e9
mais cela prendra un téraoctet ou deux de RAM.Voir sur repl.it: https://repl.it/Cx4I/1
la source
Python 2,
163160156 156145 octetsCe n'est pas la façon la plus golfique de le faire, mais c'était l'une des plus simples. Si je pouvais comprendre comment remplacer des parties de chaînes sans les transformer en listes, les remplacer et les reconvertir en chaînes, ce serait très utile ici. Suggestions de golf bienvenues.
Edit: 18 octets grâce à Leaky Nun. Essayez-le sur Ideone !
la source
str.sub(/(?<=.{20}).{3}/,"foo")
est équivalent àstr[20,3] = "foo"
. Bien sûr, cela signifie construire l'expression rationnelle par interpolation / concaténation de chaînes avec les variables d'index / de longueur - ce qui est bon marché en octets Ruby, mais peut-être pas en Python.Japt , 65 octets
Essayez-le en ligne!
Prend la saisie sous forme de liste de notes au format
[pitch, start_tick, end_tick, velocity]
. Si la saisie de données en tant que listes séparées est obligatoire (c'est-à-dire une liste contenant tous les pas, une contenant toutes les vitesses, etc.), cela peut être accompli au prix d' un octet .Explication:
la source