Hintergrund
MIDI-Dateien unterscheiden sich erheblich von WAV- oder MP3-Audiodateien. MP3- und WAV-Dateien enthalten Bytes, die eine "Aufnahme" des Audios darstellen, während MIDI-Dateien eine Reihe von MIDI-Meldungen enthalten, die in MIDI-Ereignissen gespeichert sind und einen MIDI-Synthesizer darüber informieren, welches virtuelle Instrument oder ein MIDI-Sequenzer das Wiedergabetempo spielen soll, das verwendet werden soll. Diese Meldungen sind in Spuren gespeichert, und eine Sammlung von Spuren bildet eine MIDI-Sequenz, deren Ereignisse von einem Sequenzer analysiert werden können und deren Meldungen vom Sequenzer an den Empfänger eines Synthesizers übertragen werden.
In den meisten Fällen handelt es sich bei den in MIDI-Events gespeicherten MIDI-Meldungen um Note-On-Meldungen, die den Synthesizer anweisen, eine bestimmte Note zu spielen, oder um Note-Off-Meldungen, die den Synthesizer anweisen, die Note zu stoppen. Diese Nachrichten enthalten zwei Datenbytes, von denen das erste dem Synthesizer die Anschlagstärke der Note mitteilt (höhere Anschlagstärke führt zu einer lauteren Note) und das zweite dem Synthesizer mitteilt, welche Note zu spielen ist (dh mittleres C). Die Ereignisse selbst enthalten auch Häkchen, die dazu dienen, dem Sequenzer mitzuteilen, wann er die Nachrichten senden soll.
Die Herausforderung
Die Herausforderung besteht darin, ein vollständiges Programm oder eine Funktion zu schreiben, die eine Reihe von Note-On- und Note-Off-MIDI-Meldungen in einer einspurigen MIDI-Sequenz analysiert und eine Tabelle an STDOUT ausgibt, in der angezeigt wird, wann bestimmte Noten an sind, wann sie aus sind, und die Geschwindigkeit dieser Noten. Die vertikale Achse des Diagramms stellt den Notenwert dar und sollte wie unten beschrieben beschriftet werden, und die horizontale Achse stellt die Zeit in MIDI-Ticks dar (sollte jedoch unbeschriftet bleiben, um Komplexitäts- und Abstandsprobleme zu verringern).
Ihre Eingabe kann aus vier separaten Arrays oder Listen bestehen, die jeweils eine Reihe von Ganzzahlwerten enthalten. ein zweidimensionales Array oder eine zweidimensionale Liste, die vier Unterarrays / Unterlisten mit einer Reihe von ganzzahligen Werten enthält; oder irgendein anderes geeignetes Mittel; Dies repräsentiert die Sammlung von MIDI-Events mit Note On- und Note Off-Meldungen in der Spur. Der Wert im ersten dieser Arrays gibt die Note an, der zweite die Velocity, der dritte den Note-On-Event-Tick und der vierte den Note-Off-Event-Tick. Zum Beispiel bei vier Arrays wie diesen:
{60, 62, 64, 65, 67}
{20, 40, 60, 80, 100}
{ 0, 4, 8, 12, 16}
{ 2, 6, 10, 14, 18}
Das Analysieren des ersten Elements jedes Arrays ergibt zwei Ereignisse: Ein Ereignis bei Tick 0 mit einer Nachricht, die einen Note-On-Befehl, Note 60 (Mitte C) und eine Note-Velocity von 20 hat; und ein Ereignis bei Tick 2 mit einer Nachricht, die einen Note-Off-Befehl mit derselben Note und Anschlagstärke enthält.
Regeln
In der Tabelle sollten die Zahlen 0 bis 127 in absteigender Reihenfolge auf der linken Seite (die den Notenwert darstellt), die Dauer jeder Note (Note aus Häkchen minus Note an Häkchen) und die Anschlagstärke der Note angezeigt werden. Die Symbole, die die Noten darstellen, hängen von ihrer Geschwindigkeit ab:
- 0-15:
O
- 16-31:
=
- 32-47:
#
- 48-63:
-
- 64-79:
@
- 80-95:
+
- 96-111:
0
- 112-127:
*
Sie können folgendes annehmen:
- Die Werte für Note und Velocity liegen im Bereich [0, 127].
- Die Längen der vier Arrays sind immer gleich.
Hier einige Beispiele:
{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 |
Hier ist ein Beispiel, das die ersten Noten von Ode an die Freude zeigt:
{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 |
Sie können Ihre Partitur um 25% reduzieren, wenn Ihre Einreichung eine tatsächliche MIDI-Sequenz als Eingabe verwendet, die Note-On- und Note-Off-Meldungen einer beliebigen Spur analysiert, sofern sie mindestens vier Ereignisse mit Note-On- und Note-Off-Meldungen sowie Ausgängen enthält ein Diagramm wie oben beschrieben.
Dies ist Codegolf, also gewinnt der kürzeste Code. Viel Glück!
Rubin, 106 Bytes
Das hat Spaß gemacht. Ich bin mir nicht sicher, warum es niemand versucht hat.
Diese Funktion nimmt Eingaben als vier Array-Argumente entgegen und gibt ein Array von Zeichenfolgen zurück, eine für jede Zeile des Diagramms.
Hinweis: Dies setzt willkürlich voraus, dass es nicht mehr als 10.000 Ticks geben wird. Wenn Sie es in Ihrem Terminal ausführen, empfehle ich es weiterzuleiten,
less
damit Sie horizontal scrollen können. Sie können ändern,1e4
ob Sie mehr Ticks möchten, bis zu9e9
, aber das benötigt ein oder zwei Terabyte RAM.Siehe es auf repl.it: https://repl.it/Cx4I/1
quelle
Python 2,
163160156145 BytesDies ist nicht die Golfspielweise, aber eine der einfachsten. Wenn ich herausfinden könnte, wie Teile von Zeichenfolgen ersetzt werden können, ohne sie in Listen umzuwandeln, zu ersetzen und wieder in Zeichenfolgen umzuwandeln, wäre dies hier sehr hilfreich. Golfvorschläge sind willkommen.
Edit: 18 Bytes dank Leaky Nun. Probieren Sie es auf Ideone !
quelle
str.sub(/(?<=.{20}).{3}/,"foo")
gleichbedeutend mitstr[20,3] = "foo"
. Dies bedeutet natürlich, dass der reguläre Ausdruck durch Zeichenfolgeninterpolation / -verkettung mit den Index- / Längenvariablen erstellt wird - was in Ruby-Bytes billig ist, in Python jedoch möglicherweise nicht.Japt , 65 Bytes
Probieren Sie es online!
Übernimmt die Eingabe als Liste von Notizen im Format
[pitch, start_tick, end_tick, velocity]
. Wenn die Eingabe als separate Listen obligatorisch ist (dh eine Liste mit allen Tonhöhen, eine Liste mit allen Geschwindigkeiten usw.), kann dies auf Kosten von 1 Byte durchgeführt werden .Erläuterung:
quelle