h&g      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~                                                                                                                                                                                                                                                                                       * Safe-Inferred;midi$Shift bitwise to the left and right.midi$Shift bitwise to the left and right.midi The call  toBase n x takes a given number x and "chops it up," returning its digits in base b. Its output is in the form of a big-endian list of ints. divMod is used because it gives the correct rounding for negative numbers. Ex. toBytes 1000 -> toBase 256 1000 -> (256*3) + 232 -> [ 3 , 232 ]midiGet only n of the least significant bytes of x. If it takes less than n digits to express x, then fill the extra digits with zeros.midiThe fromBase function converts a list of digits in another base into a single base-10 number.*fromBase b [x,y,z] = x*b^2 + y*b^1 + z*b^0midiLike  but for big numbers. It chops the list into blocks of tractable sizes (e.g.  maxBound::Int).midi trunc b n) takes the b least significant bits of n.midi splitAt b n; splits a number into a tuple: (before bit b, after bit b). Safe-InferredmidiHugs makes trouble here because it performs UTF-8 conversions. E.g. [255] is output as  [195,191] It would be easy to replace these routines by FastPackedString(fps).ByteList.Lazy, however this introduces a new package dependency. Safe-Inferred5 Safe-InferredTmidiThis datatype is the result of a parser. First it stores a sequence of warnings. Warnings are for corruptions of the input which can be fixed. After encountering a series of warnings, there is finally an end, either a successful one, with the result as (Right result)1 or an eventual non-fixable problem indicated by (Left errorMessage).   Safe-Inferred Safe-InferredmidiPossiblyIncomplete represents a value like a list that can be the result of an incomplete parse. The case of an incomplete parse is indicated by  Just message.It is not possible to merge this functionality in the parser monad, because then it is not possible to define monadic binding.midiEmit a warning if a value is said to be incomplete. Be careful using this function, because an incomplete value often means that subsequent parse actions will process data from the wrong position. Only use this function if you either know that the parse is complete also if the parsed value is incomplete or if there are no subsequent parse actions to run.This function cannot fail.midiThis function will never fail. If the element parser fails somewhere, a prefix of the complete list is returned along with the error message.midiParse until an element is found, which matches a condition. The terminating element is consumed by the parser but not appended to the result list. If the end of the input is reached without finding the terminating element, then an Incomplete exception (Just errorMessage) is signaled.midiThis function will never fail. It may however return a list that is shorter than requested.midi7The first parser may fail, but the second one must not. Safe-Inferred#midi# gets a single byte from the input.midigetN n- returns n characters (bytes) from the input.midi, , , and  take 1-, 2-, 3-, or 4-byte numbers from the input (respectively), convert the base-256 data into a single number, and return.midiVariable-length quantities are used often in MIDI notation. They are represented in the following way: Each byte (containing 8 bits) uses the 7 least significant bits to store information. The most significant bit is used to signal whether or not more information is coming. If it's 1", another byte is coming. If it's 0, that byte is the last one. 0 gets a variable-length quantity from the input.midiThe returned list contains only bytes with the most significant bit cleared. These are digits of a 128-ary number. Safe-Inferred$lmidiSince in case of an incomplete file read, we cannot know where the current file position is, we omit the runIncompleteHandle variant. Safe-Inferred$  Safe-Inferred$! Safe-Inferred%midiTreat errors which caused an incomplete data structure as warnings. This is reasonable, because we do not reveal the remaining unparsed data and thus further parsing is not possible.  Safe-Inferred&MmidiRead MIDI machine control commands until an F7 marker for SysEx end.    " Safe-Inferred'midiTreat errors which caused an incomplete data structure as warnings. This is reasonable, because we do not reveal the remaining unparsed data and thus further parsing is not possible.midiIn contrast to Binary.skip this one does not fail badly and it works with Int64. I hope that it is not too inefficient.# Safe-Inferred( $ Safe-Inferred(Q% Safe-Inferred*"midiThis definition should be in Message.Channel, but this results in a cyclic import.midiThe  monad parses a track of a MIDI File. In MIDI, a shortcut is used for long strings of similar MIDI events: If a stream of consecutive events all have the same type and channel, the type and channel can be omitted for all but the first event. To implement this feature, the parser must keep track of the type and channel of the most recent MIDI Event. This is done by managing a  in the parser. "#$ Safe-Inferred+S%midi%Accidentals as used in key signature.'midi:The Key Signature specifies a mode, either major or minor.(%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKL(*+%&'(),-./0123456789:;<=>?@ABCDEFGHIJKL& Safe-Inferred-namidiWe do not define a as enumeration with many constructors, because some controllers have multiple names and some are undefined. It is also more efficient this way. Thus you cannot use case2 for processing controller types, but you can use '( instead. maybe (putStrLn "unsupported controller") putStrLn $ lookup ctrl $ (portamento, "portamento") : (modulation, "modulation") : []abc Safe-Inferred-defghijklmnopqrstuvwxyz{|}~edfghijklmnopqrstuvwxyz{|}~) Safe-Inferred0midiputLengthBlock n writeBody write n1 bytes indicating the number of bytes written by  writeBody and then it runs  writeBody.midi specialised to midiNumbers of variable size are represented by sequences of 7-bit blocks tagged (in the top bit) with a bit indicating: (1) that more data follows; or (0) that this is the last block. Safe-Inferred1    Safe-Inferred1smidialso includes SMPTE type  Safe-Inferred2]midiThis function is also used in alsa-midi, we could give it the result type Parser.PossiblyIncomplete T otherwise.    Safe-Inferred2  Safe-Inferred6midiIt is not checked whether SysEx messages contain only 7-bit values.  Safe-Inferred6 Safe-Inferred8midiThere are three forms of System Exclusive Messages in MIDI files: monolithic, chopped into packets, escape form (with unrestricted binary data).Currently we only support first and last type explicitly. But we leave the trailing 0xF7 markers which can be used to detect whether the messages are actually meant as packets.Since I don't know where manufacturer information is in the packets form, I omit manufacturer handling for now.* Safe-Inferred:3midiGiven a writer that emits a status, generate a stateful writer, that decides whether to run the status emittor.midistatus can be * for files ignoring the running status or ) for files respecting the running status.      Safe-InferredA midiNoteOn with zero velocity is considered NoteOff according to MIDI specification.midiNoteOn with zero velocity is considered NoteOff according to MIDI specification.midi Convert all  NoteOn p 0 to  NoteOff p 64&. The latter one is easier to process.midi Convert all  NoteOff p 64 to  NoteOn p 0. The latter one can be encoded more efficiently using the running status.midiConvert pitch to frequency according to the default tuning given in MIDI 1.0 Detailed Specification.midiA MIDI problem is that one cannot uniquely map a MIDI key to a frequency. The frequency depends on the instrument. I don't know if the deviations are defined for General MIDI. If this applies one could add transposition information to the use patch map. For now I have chosen a value that leads to the right frequency for some piano sound in my setup.midiThe velocity of an ordinary key stroke and the maximum possible velocity.midiThe velocity of an ordinary key stroke and the maximum possible velocity.midiMIDI specification says, if velocity is simply mapped to amplitude, then this should be done by an exponential function. Thus we map  (64) to 0,  (127) to 1, and minimumVelocity> (1) to -1. That is, normally you should write something like %amplitude = 2 ** realFromVelocity vel or 3 ** realFromVelocity vel.midiMap integral MIDI controller value to floating point value. Maximum integral MIDI controller value 127 is mapped to 1. Minimum integral MIDI controller value 0 is mapped to 0.midiToDo: We have defined minBound = Velocity 0, but strictly spoken the minimum Velocity is 1, since Velocity zero means NoteOff. One can at least think of NoteOff with (Velocity 0), but I have never seen that.abcabc Safe-InferredEmidiParse an event. Note that in the case of a regular MIDI Event, the tag is the status, and we read the first byte of data before we call . In the case of a MIDIEvent with running status, we find out the status from the parser (it's been nice enough to keep track of it for us), and the tag that we've already gotten is the first byte of data.midifor internal usemidiParse a MIDI Channel message. Note that since getting the first byte is a little complex (there are issues with running status), the code, channel and first data byte must be determined by the caller. midioutput a channel + message code"#$abc"#$abc+ Safe-InferredFs  Safe-InferredF Safe-InferredJLmidiThe default SetTempo value, in microseconds per quarter note. This expresses the default of 120 beats per minute. Safe-InferredJ   Safe-InferredLbmidiEach event is preceded by the delta time: the time in ticks between the last event and the current event. Parse a time and an event, ignoring System Exclusive messages.midi'The following functions encode various ,-4 elements into the raw data of a standard MIDI file. Safe-InferredOmidi5All methods have default implementations that return  . This helps implementing event data types that support only a subset of types of events.Maybe a better approach is to provide type classes for every type of event and make  a subclass of all of them.midi=Warning: This returns note events as they are, that is, a  NoteOff p 64 might be encoded as such or as  NoteOn p 0 depending on the content of event(. For normalized results you may use .midiLike , but converts  NoteOn p 0 to  NoteOff p 64. See ./.midiLike , but converts  NoteOff p 64 to  NoteOn p 0. See .0.   Safe-InferredQzmidiAn empty MIDI file. Tempo is set to one tick per quarter note.midiApply a function to each track.midi Convert all  NoteOn p 0 to  NoteOff p 64&. The latter one is easier to process.midi Convert all  NoteOff p 64 to  NoteOn p 0. The latter one can be encoded more efficiently using the running status.midiMerge all tracks into a single track according to the MIDI file type.midiProcess and remove all SetTempo events. The result is an event list where the times are measured in seconds.midi Show the > with one event per line, suited for comparing MIDIFiles with diff. Can this be replaced by 12?midi8A hack that changes the velocities by a rational factor.midiChange the time base.midiSort MIDI note events lexicographically. This is to make MIDI files unique and robust against changes in the computation. In principle Performance.merge should handle this but due to rounding errors in Float the order of note events still depends on some internal issues. The sample rate of MIDI events should be coarse enough to assert unique results.midiOld versions of Haskore.Interface.MIDI.Write wrote 34 and  once at the beginning of a file in that order. The current version supports multiple 34s in a track and thus a 345 is set immediately before a note. Because of this a 34 is now always after a . For checking equivalence with old MIDI files we can switch this back. Safe-Inferred^)midiDirectly write to a file. Since chunks lengths are not known before writing, we need to seek in a file. Thus you cannot write to pipes with this function.midi The function " is the main function for writing  values to an actual file.midiConvert a MIDI file to a .midiConvert a MIDI file to a lazy  .midiConvert a MIDI file to a lazy  . It converts  NoteOff p 64 to  NoteOn p 0 and then uses the running MIDI status in order to compress the file.midi file name midi file name  Safe-InferredgE midiThe main load function. Warnings are written to standard error output and an error is signaled by a user exception. This function will not be appropriate in GUI applications. For these, use  instead.midiThis function ignores warnings, turns exceptions into errors, and return partial results without warnings. Use this only in testing but never in production code! midiA MIDI file is made of chunks, each of which is either a  header chunk or a  track chunk. To be correct, it must consist of one header chunk followed by any number of track chunks, but for robustness's sake we ignore any non-header chunks that come before a header chunk. The header tells us the number of tracks to come, which is passed to . midiThere are two ways to mark the end of the track: The end of the event list and the meta event  EndOfTrack3. Thus the end marker is redundant and we remove a  EndOfTrack0 at the end of the track and complain about all  EndOfTracks within the event list. midiParse a chunk, whether a header chunk, a track chunk, or otherwise. A chunk consists of a four-byte type code (a header is MThd ; a track is MTrk), four bytes for the size of the coming data, and the data itself. midiParse a Header Chunk. A header consists of a format (0, 1, or 2), the number of track chunks to come, and the smallest time division to be used in reading the rest of the file. midiThe division is implemented thus: the most significant bit is 0 if it's in ticks per quarter note; 1 if it's an SMPTE value. midiA track is a series of events. Parse a track, stopping when the size is zero.midiFunctions to show the decoded contents of a MIDI file in an easy-to-read format. This is for debugging purposes and should not be used in production code. midiThe two functions, the   and   parsers, do not combine directly into a single master parser. Rather, they should be used to chop parts of a midi file up into chunks of bytes which can be outputted separately.'Chop a MIDI file into chunks returning:list of  chunk-type-contents pairs; and;leftover slop (should be empty in correctly formatted file)5 Safe-Inferredg  6789:;<=>-?@ABCDEFGHIJKLMNOPQRSTUVWX%Y%Z%[\\]^_-?`abcdefghijklmnopqrstuvwxyz{|}~BC&&&--EQCB          -            -             B C  -                                                                                                                                                                                                                                B C  -        -      -BC-4/0BC]-?BC-BC-Y-3BC-?/0BC26--?-? -  !!9!9!-!?!!!"""-"?""##########$$$$$$$$$$$$$$$$%-%%%%%&))))9)))))))))9))))))))))**-*****?*********+++++++/+0655#midi-0.2.2.2-6ts4OUC5p5Y3iIRpwzRKyh Sound.MIDI.IOSound.MIDI.Parser.ReportSound.MIDI.MachineControlSound.MIDI.Message.ChannelSound.MIDI.KeySignature Sound.MIDI.Message.Channel.VoiceSound.MIDI.Controller"Sound.MIDI.Message.System.RealTime Sound.MIDI.Message.System.CommonSound.MIDI.Message.Channel.ModeSound.MIDI.Manufacturer#Sound.MIDI.Message.System.ExclusiveSound.MIDI.Message.System%Sound.MIDI.File.Event.SystemExclusiveSound.MIDI.GeneralSound.MIDI.File.Event.MetaSound.MIDI.MessageSound.MIDI.File.EventSound.MIDI.Message.Class.Query"Sound.MIDI.Message.Class.ConstructSound.MIDI.Message.Class.CheckSound.MIDI.FileSound.MIDI.File.SaveSound.MIDI.File.LoadSound.MIDI.BitSound.MIDI.MonoidSound.MIDI.Parser.ExceptionSound.MIDI.Parser.ClassSound.MIDI.Parser.PrimitiveSound.MIDI.Parser.FileSound.MIDI.Parser.RestrictedSound.MIDI.Parser.WarningSound.MIDI.Parser.StreamSound.MIDI.Parser.ByteStringSound.MIDI.StringSound.MIDI.UtilitySound.MIDI.Parser.StatusSound.MIDI.ControllerPrivate Data.ListlookupSound.MIDI.Writer.BasicSound.MIDI.Writer.Status Sound.MIDI.Message.Class.UtilityMIDIFileTVoiceMsgexplicitNoteOffimplicitNoteOffSound.MIDI.LoadshowFile MIDIEvent ProgramChange!Sound.MIDI.Example.ControllerRampbaseGHC.IO.StdHandlesopenBinaryFileByteListwriteBinaryFilelistCharFromBytereadBinaryFilelistByteFromChar UserMessageConswarningsresult$fShowT$fEqTCommandStopPlay DeferredPlay FastForwardRewind RecordStrobe RecordExit RecordPausePauseEjectChaseCommandErrorResetResetWaitResumesplitCommandList getCommands getCommand runParser $fShowCommandChannel fromChannel toChannel AccidentalsModeMajorMinorkeyNamecfMajorgfMajordfMajorafMajorefMajorbfMajorfMajorcMajorgMajordMajoraMajoreMajorbMajorfsMajorcsMajorafMinorefMinorbfMinorfMinorcMinorgMinordMinoraMinoreMinorbMinorfsMinorcsMinorgsMinordsMinorasMinorgettoBytes$fArbitraryMode $fRandomMode$fArbitraryAccidentals$fRandomAccidentals$fEnumAccidentals$fBoundedAccidentals $fArbitraryT$fOrdT$fShowAccidentals$fEqAccidentals$fOrdAccidentals$fIxAccidentals $fShowMode$fEqMode $fOrdMode$fIxMode $fEnumMode $fBoundedMode ControllerfromController toControllerValuefromInttoInt bankSelect modulation breathControl footControlportamentoTime dataEntryvolumebalancepanorama expressioneffectControl1effectControl2generalPurpose1generalPurpose2generalPurpose3generalPurpose4vectorXvectorYsoundVariationtimbreharmonicIntensity releaseTime attackTime brightness decayTime vibratoRate vibratoDepth vibratoDelayreverbSendLevelchorusSendLevelexternalEffectDepth tremoloDepth chorusDepth celesteDepth phaserDepth bankSelectMSB modulationMSBbreathControlMSBfootControlMSBportamentoTimeMSB dataEntryMSB volumeMSB balanceMSB panoramaMSB expressionMSBeffectControl1MSBeffectControl2MSBgeneralPurpose1MSBgeneralPurpose2MSBgeneralPurpose3MSBgeneralPurpose4MSB bankSelectLSB modulationLSBbreathControlLSBfootControlLSBportamentoTimeLSB dataEntryLSB volumeLSB balanceLSB panoramaLSB expressionLSBeffectControl1LSBeffectControl2LSBgeneralPurpose1LSBgeneralPurpose2LSBgeneralPurpose3LSBgeneralPurpose4LSBsustain portamento sustenuto softPedallegatohold2soundController1soundController2soundController3soundController4soundController5soundController6soundController7soundController8soundController9soundController10generalPurpose5generalPurpose6generalPurpose7generalPurpose8portamentoControl effect1Depth effect2Depth effect3Depth effect4Depth effect5Depth dataIncrement dataDecrementnonRegisteredParameterLSBnonRegisteredParameterMSBregisteredParameterLSBregisteredParameterMSB TimingClockStartContinue ActiveSensingput$fEnumT$fIxTTimeNibbleTypeFrameLSFrameMS SecondsLS SecondsMS MinutesLS MinutesMSHoursLSHoursMSTimeCodeQuarterFrameSongPositionPointer SongSelect TuneRequest$fEqTimeNibbleType$fOrdTimeNibbleType$fShowTimeNibbleType$fEnumTimeNibbleType$fIxTimeNibbleType AllSoundOffResetAllControllers LocalControl AllNotesOffOmniModeMonoModePolyModefromControllerValuetoControllerValue sequentialidp octavePlateaumoogpassportlexiconkurzweilfender gulbransenakgvoyce waveframeadagarfieldensoniqoberheimapple greyMatter digidesignpalmTreejlCooperlowrey adamsSmithemuharmonyartbaldwineventide inventronics keyConceptsclarity timeWarner digitalMusiciota newEnglandartisynivl southernMusic lakeButleralesisdod studerEditech perfectFretkatopcoderaneanadikmxbrenellpeavey systems360spectrummarquiszetaaxxesorbankti breakawaycaerocktron pianoDisccannonrogers blueSkyLogicencoreuptownvocecti ssResearch broderbund allenOrgan musicQuestaphexgallienKruegeribmhotzInstruments etaLightingnsiadLibrichmond microsoftsoftwareToolworks rjmgNicheintone grooveTubeseuphonix interMIDIloneWolfmusonixtaHorngeTek electrovoicemidisoft qSoundLabswestrexnVidiaess mediaTrix brooktreeotarikeyElectronics crystalakecrystalrockwellsiliconGraphicsmidimanpreSonustopaz castLightingmicrosoftConsumer fastForward headspace vanKoeveringaltechvlsichromaticResearchsapphireidrcjustonictorCompnewteksoundSculpturewalkerpavoinVision tSquareDesignnemesysdbxsyndynebitheadzcakewalkstaccatonationalSemiconductor boomTheory virtualDSPantares angelSoftwarestLouislyrruspassacsielsynthaxehohnertwistersolton jellinghaus southworthppgjensslaudioVeritriebelkadynacordviscountclaviaaudioArchitect generalMusic soundcraftwersiavabdigigramwaldorf quasimididreamstrandLightingamekdrBohmtridentrealWorldDesign yesTechnology audiomaticabontempiFarfisafbtElectronicamiditemp larkingAudiozero88lighting miconAudio forefrontkentonadb jimMarshallddabssAudio tcElectronicmedeli charlieLabblueChipbeeOHlgSemiconductortesiemagic behringeraccesssynoptic hanmesoftterratecproelibkkawairolandkorgyamahacasiokamiyaakai japanVictormesosha hoshinoGakki fujitsuElectsony nisshinOnpateacmatsushitaElecfostexzoommidorimatsushitaCommsuzuki nonCommercial nonRealTimerealTime Commercial NonCommercial NonRealTimeRealTime getIncomplete ExclusiveCommonRegularEscapeProgram fromProgramVelocity fromVelocityPitch fromPitchControllerValuePressurePitchBendRangeNoteOffNoteOnPolyAftertouchControl PitchBendMonoAftertouchisNoteisNoteOn isNoteOfftoPitch toVelocity toProgram increasePitch subtractPitchfrequencyFromPitchzeroKeynormalVelocitymaximumVelocityrealFromVelocityrealFromControllerValue mainVolume mainVolumeMSB mainVolumeLSBportaextDepth putWithStatus$fBoundedPitch $fEnumPitch$fArbitraryPitch $fRandomPitch$fBoundedVelocity$fArbitraryVelocity$fRandomVelocity$fBoundedProgram $fEnumProgram$fArbitraryProgram$fRandomProgram $fShowProgram $fEqProgram $fOrdProgram $fIxProgram$fShowVelocity $fEqVelocity $fOrdVelocity $fShowPitch $fEqPitch $fOrdPitch $fIxPitchBodyVoicemessageChannel messageBody getWithStatus decodeStatus $fShowBody$fEqBody $fOrdBodyDrumAcousticBassDrum BassDrum1 SideStick AcousticSnareHandClap ElectricSnare LowFloorTom ClosedHiHat HighFloorTom PedalHiHatLowTom OpenHiHat LowMidTomHiMidTom CrashCymbal1HighTom RideCymbal1 ChineseCymbalRideBell Tambourine SplashCymbalCowbell CrashCymbal2 Vibraslap RideCymbal2HiBongoLowBongo MuteHiConga OpenHiCongaLowConga HighTimbale LowTimbale HighAgogoLowAgogoCabasaMaracas ShortWhistle LongWhistle ShortGuiro LongGuiroClaves HiWoodBlock LowWoodBlock MuteCuica OpenCuica MuteTriangle OpenTriangle InstrumentAcousticGrandPianoBrightAcousticPianoElectricGrandPiano HonkyTonkElectricPiano1ElectricPiano2 HarpsichordClavinetCelesta GlockenspielMusicBox VibraphoneMarimba Xylophone TubularBellsDulcimer DrawbarOrganPercussiveOrgan RockOrgan ChurchOrgan ReedOrgan Accordion HarmonicaTangoAccordianAcousticGuitarNylonAcousticGuitarSteelElectricGuitarJazzElectricGuitarCleanElectricGuitarMutedOverdrivenGuitarDistortionGuitarGuitarHarmonics AcousticBassElectricBassFingerElectricBassPick FretlessBass SlapBass1 SlapBass2 SynthBass1 SynthBass2ViolinViolaCello ContrabassTremoloStringsPizzicatoStringsOrchestralHarpTimpaniStringEnsemble1StringEnsemble2 SynthStrings1 SynthStrings2 ChoirAahs VoiceOohs SynthVoice OrchestraHitTrumpetTromboneTuba MutedTrumpet FrenchHorn BrassSection SynthBrass1 SynthBrass2 SopranoSaxAltoSaxTenorSax BaritoneSaxOboe EnglishHornBassoonClarinetPiccoloFluteRecorderPanFlute BlownBottle SkakuhachiWhistleOcarina Lead1Square Lead2Sawtooth Lead3Calliope Lead4Chiff Lead5Charang Lead6Voice Lead7Fifths Lead8BassLead Pad1NewAgePad2Warm Pad3Polysynth Pad4Choir Pad5Bowed Pad6MetallicPad7Halo Pad8SweepFX1Rain FX2Soundtrack FX3Crystal FX4Atmosphere FX5Brightness FX6Goblins FX7EchoesFX8SciFiSitarBanjoShamisenKotoKalimbaBagpipeFiddleShanai TinkleBellAgogo SteelDrums Woodblock TaikoDrum MelodicTom SynthDrum ReverseCymbalGuitarFretNoise BreathNoiseSeashore BirdTweet TelephoneRing HelicopterApplauseGunshotinstrumentNameToPrograminstrumentNamesinstrumentProgramsinstrumentFromPrograminstrumentToPrograminstrumentChannels instruments drumChannel drumProgram drumMinKey drumKeyTable drumFromKey drumToKeydrums$fArbitraryInstrument$fRandomInstrument$fArbitraryDrum $fRandomDrum $fShowDrum$fEqDrum $fOrdDrum$fIxDrum $fEnumDrum $fBoundedDrum$fShowInstrument$fEqInstrument$fOrdInstrument$fIxInstrument$fEnumInstrument$fBoundedInstrument SequenceNum TextEvent Copyright TrackNameInstrumentNameLyricMarkerCuePoint MIDIPrefix EndOfTrackSetTempo SMPTEOffsetTimeSigKeySigSequencerSpecificUnknown SMPTEBits SMPTEFrames SMPTESeconds SMPTEMinutes SMPTEHoursTempo ElapsedTime toElapsedTimefromElapsedTimetoTempo fromTempo defltTempoSystemgetIncompleteWithStatusmaybeFromByteString toByteString MetaEventSystemExclusive TrackEventmapBodymaybeMIDIEventmaybeMetaEvent maybeVoicemapVoice getTrackEventCnoteprogram anyController pitchBendchannelPressuremodenoteExplicitOffnoteImplicitOffliftMidiliftFile$fCT$fCT0$fCT1 liftChannel controllerTrackDivisionTicksSMPTETypeMixedParallelSerialemptymapTrack getTracks mergeTrackssecondsFromTicksticksPerQuarterNote showLinesshowTime showEventchangeVelocity resampleTime sortEventsprogChangeBeforeSetTempo$fArbitraryDivision$fShowDivision $fEqDivision $fShowType$fEqType $fOrdType$fIxType $fEnumType $fBoundedTypetoSeekableFiletoFile toByteListtoCompressedByteStringfromFile fromByteListmaybeFromByteListshiftLshiftRtoBase someBytesfromBase replicateBigGHC.List replicatetruncsplitAttoHextoOctaltoBits fromBytesfromHex fromOctalfromBits+#+ genAppend genConcatnonEmptyConcatrungiveUptryPossiblyIncompletewarnIncomplete zeroOrMoreuntilappendIncompletePartialFragilewarngetByteskipEndCheckisEndwarnIf zeroOrMoreInc emptyListgetNget1get2get3get4getVar getVarBytes getStringgetBigN getNByteIntgetNByteCardinalgetEnummakeEnumrunIncompleteFiledeconsrunFile runHandle runFragile runIncomplete runPartialunlinesSconcatSrightSleftScentreSrightleftcentrespaces stateToReadSArbByte deconsArbByteArbChar deconsArbChar checkRangeloopM enumRandomRboundedEnumRandom chooseEnumquantityRandomRboundedQuantityRandomchooseQuantityarbitraryStringarbitraryByteListStatussetliftputLengthBlockputByteListSpec putByteListputVar SeekableFileunSeekableFile ByteString unByteString unByteListputByte runByteList runByteStringrunSeekableFilerunSeekableHandleputIntputStr putIntAsByteputLenByteListchange Uncompressed Compressed/monoid-transformer-0.0.4-61wbsytrs2FITAOtogiHSAData.Monoid.Transformer Compression initStateclear fromWritertoWritertoWriterWithStatustoWriterWithoutStatus putChannel GHC.MaybeNothingbytestring-0.11.3.1Data.ByteString.Lazy.InternalparseremoveEndOfTrackgetChunk getHeader getDivisiongetTrack getChunksexamplemain