Re: How do I import midi files into Mathematica?
- To: mathgroup at smc.vnet.net
- Subject: [mg125650] Re: How do I import midi files into Mathematica?
- From: Roger Bagula <roger.bagula at gmail.com>
- Date: Sun, 25 Mar 2012 00:17:04 -0500 (EST)
- Delivered-to: l-mathgroup@mail-archive0.wolfram.com
- References: <jkh5ih$jtf$1@smc.vnet.net> <jkjrkd$42s$1@smc.vnet.net>
On Mar 24, 12:03 am, markholtuk <markhol... at googlemail.com> wrote: > On Mar 23, 6:34 am, Roger Bagula <roger.bag... at gmail.com> wrote: > > Good Luck! > > Mark Mark Holtuk Thanks a lot for this: it works better than the xml tree method. With your notes array from my midi file, I was able to extract something that sounded kind of like my tune, but only when taking out 6 repeats, but I put in a four track/ channel midi to start ( no controller events). At least I'm learning. You have put in a lot of good work on this! Roger Bagula Although I can't get Musica to export in version 8 because it needs:Utilities`BinaryFiles` it still imports a version of a midi file. His method may help you with yours. >From Musica.m by the great Greek fellow: Musica had: ImportMIDI::usage = "ImportMIDI[Filename,options] returns an eventlist \ containing all the events of the format 0 MIDI file named Filename. Posible \ options are NoteConversion, ToCustomEvents and FinalFunction." ImportMIDI::format = "File in unsupported format." ImportMIDI::filetype = "Not a MIDI file." ImportMIDI::filenotfound = "File not found." Options[ImportMIDI] = {NoteConversion -> True, ToCustomEvents -> {}, FinalFunction -> Identity} ImportMIDI[filename_, options___] := Module[{l, e, b, status, t, len, type, data, format, hd, nc, tce, ff}, ({nc, tce, ff} = {If[NoteConversion, NoteOn2Note, Identity], ToCustomEvents, FinalFunction} /. {options} /. Options[ImportMIDI]); l = OpenRead[filename, DOSTextFormat -> False]; hd = {}; If[l=!=$Failed, Do[AppendTo[hd, Read[l, Byte]], {4}]; If[hd == {77, 84, 104, 100}, Skip[l, Byte, 5]; Print["Format: ", format = Read[l, Byte]]; Print["Tracks: ", 256Read[l, Byte] + Read[l, Byte]]; Print["PPQ: ", 256Read[l, Byte] + Read[l, Byte]]; Skip[l, Byte, 8]; If[format == 0, e = {}; While[(b = Read[l, Byte]) =!= EndOfFile, t = {}; len = {}= ; While[b > 128, AppendTo[t, b]; (b = Read[l, Byte])]; AppendTo[t, b]; (status = Read[l, Byte]); AppendTo[e, Which[status < 128, {FromVariableLength[t], Head[e[[-1, 2]]] @@ Join[{status}, (ReadList[l, Byte, Length[e[[-1, 2]]] - 2] /. (ReadList[l, Byte, 0] :> {})), {e[[-1, 2, -1]]}]}, 143 < status < 160, {FromVariableLength[t], NoteOn[Read[l, Byte], Read[l, Byte], status - 143]}, 175 < status < 192, {FromVariableLength[t], Controller[Read[l, Byte], Read[l, Byte], status - 175]}, 223 < status < 240, {FromVariableLength[t], PitchBend[Read[l, Byte], Read[l, Byte], status - 223]}, 207 < status < 224, {FromVariableLength[t], ChannelAftertouch[Read[l, Byte], status - 207]}, 191 < status < 208, {FromVariableLength[t], ProgramChange[Read[l, Byte], status - 191]}, 127 < status < 144, {FromVariableLength[t], NoteOff[Read[l, Byte], Read[l, Byte], status - 127]}, 159 < status < 176, {FromVariableLength[t], KeyAftertouch[Read[l, Byte], Read[l, Byte], status - 159]}, status == 255, (type = Read[l, Byte]); b = Read[l, Byte]; While[b > 128, AppendTo[len, b]; (b = Read[l, Byte])]; AppendTo[len, b]; data = (ReadList[l, Byte, FromVariableLength[ len]] /. (ReadList[l, Byte, 0] :> {})); {FromVariableLength[t], MetaEvent[type, data]}, status == 240, b = Read[l, Byte]; While[b > 128, AppendTo[len, b]; (b = Read[l, Byte])]; AppendTo[len, b]; data = ReadList[l, Byte, FromVariableLength[len]]; {FromVariableLength[t], Sysex[Prepend[data, 240]]}, status == 247, b = Read[l, Byte]; While[b > 128, AppendTo[len, b]; (b = Read[l, Byte])]; AppendTo[len, b]; data = ReadList[l, Byte, FromVariableLength[len]]; {FromVariableLength[t], Sysex[Prepend[data, 247]]} ] ]; ]; Close[l]; ff[nc[Transpose[{FromDeltaTime[e[[All, 1]]], e[[All, 2]]}] /. {PitchBend[fine_, coarse_, channel_] -> PitchBend[fine + 128coarse - 8192, channel], ProgramChange[num_, channel_] -> ProgramChange[num + 1, channel]} /. Dispatch[{MetaEvent[81, micros_] :> Tempo[N[6/Plus @@ ({65536, 256, 1}micros) 10^7]], MetaEvent[1, text_] :> TextEvent[FromCharacterCode[text]], MetaEvent[2, text_] :> Copyright[FromCharacterCode[text]], MetaEvent[3, text_] :> TrackName[FromCharacterCode[text]], MetaEvent[4, text_] :> InstrumentName[FromCharacterCode[text]], MetaEvent[5, text_] :> Lyric[FromCharacterCode[text]], MetaEvent[6, text_] :> Marker[FromCharacterCode[text]], MetaEvent[7, text_] :> CuePoint[FromCharacterCode[text]], MetaEvent[88, {n_, d_, x_, y_}] :> TimeSignature[n, 2^d, x, y], MetaEvent[47, {}] :> EndOfTrack, MetaEvent[89, {sf_, mm_}] :> KeySignature[ Which[0 <= sf <= 7, sf, sf >= 249, sf - 256], mm]}]] //. tce] , Message[ImportMIDI::format]], Message[ImportMIDI::filetype]],Message[ImportMIDI::filenotfound]]] GenerateEventList[x__ /; (Equal @@ (Prepend[Length /@ {x}, 2])), i__ /; (Equal @@ (Prepend[Length /@ {i}, 3])), PPQ_Integer: 192] := SortEventList[Flatten[Table[{x}, i], Length[{i}] + Length[{x}] - 2], PPQ] SetAttributes[GenerateEventList, HoldAll] SumList[f_, i_] := Module[{l = {}, s = 0}, Do[AppendTo[l, s]; s += = f, i]; l] SetAttributes[SumList, HoldAll] EventSequence[x_, step_, i_, PPQ_:192] := Module[{s, j}, s = SumList[step, i]; SortEventList[Transpose[{s, Flatten[Table[x, i], Length[{i}] - 1]}], PPQ]] SetAttributes[EventSequence, HoldAll] End[]