One of the first languages I tried to write was a MIDI-file assembly language. You'd define tempo and instrument bank and then lots of note lines (Note-name, starting-beat-of-the-current-measure, duration, optional accent), punctuated by bar lines ("meas\n"), and dynamics (ppp,pp,p,mp,mf,f,ff,fff).
It wasn't really usable without a macro language to repeat sequences, change channels, and lay down new tracks. That required my first hash table, and a tricksy cross-your-fingers call to qsort to interleave the channels by time-sequence (implicitly carried by each Note-On/Note-Off event).
When I came back to it a year later, it had fallen victim to bit-rot. After no small struggle I rediscovered that the sort-and-output-everything function was triggered by an explicit EOF code. A macro-expanded song was easily 20,000 lines with that crucial EOF line having, therefore, 1/20000th of a chance to be spotted when trying to figure out just what in the heck is going wrong!
I am somewhat pleased that all the evidence is safely tucked away in a dead CPU underneath the microwave cart. The horrors!!
Edit: Upon further reflection there are some interesting things about the MIDI format. It has a variable-length integer type (IIRC using the sign bit to signal the last byte). It's byte-oriented, being designed to run over 9 parallel wires; and it has some crazy time-synchronization thing I never understood. But all I cared about was that the Windows95 media player could interpret the output (it could even use the 8bit General MIDI tone bank built into the sound card; the cymbals were gloriously distorted).