g1<P      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~                                  ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _ ` a b c d e f g h i j k l m n o p q r s t u v w x y z { | } ~                                                                 !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNO' Safe-Infered)This 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) 0or an eventual non-fixable problem indicated by (Left errorMessage).  Safe-InferedPQRSPQRSPQRS Safe-InferedTUVTUVTUV Safe-Infered?Hugs makes trouble here because it performs UTF-8 conversions. E.g. [255] is output as [195,191] SIt would be easy to replace these routines by FastPackedString(fps).ByteList.Lazy, 2however this introduces a new package dependency.       Safe-InferedWXYZ[\]^_`abcdefghijklmnopqrWXYZ[\]^_`abcdefghijklmnopWXYZ[\]^_`abcdefghijklmnopqr Safe-Infereds%Shift bitwise to the left and right. t%Shift bitwise to the left and right. u 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 Fbig-endian list of ints. divMod is used because it gives the correct Grounding for negative numbers. Ex. toBytes 1000 -> toBase 256 1000 -> (256*3) + 232 -> [ 3 , 232 ] vGGet 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. wGThe 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^0 xLike y but for big numbers. 7It chops the list into blocks of tractable sizes (e.g.  maxBound::Int). z trunc b n* takes the b least significant bits of n. { splitAt b n< splits a number into a tuple: (before bit b, after bit b). stu|}~vwxz{stu|}~vwxz{stu|}~vwxz{ Safe-Infered We do not define  ( as enumeration with many constructors, Ebecause some controllers have multiple names and some are undefined. $It is also more efficient this way. Thus you cannot use case" for processing controller types, but you can use  instead. 6 maybe (putStrLn "unsupported controller") putStrLn $  lookup ctrl $ ! (portamento, "portamento") : ! (modulation, "modulation") :  []        Safe-Inferedg !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstg !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstg! "43210/.-,+*)('&%$#Unmlkjihgfedcba`_^]\[ZYXWV5DCBA@?>=<;:9876ETSRQPONMLKJIHGFotsrqpg !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrst Safe-Infered Safe-InferedputLengthBlock n writeBody  write n1 bytes indicating the number of bytes written by  writeBody  and then it runs  writeBody.  specialised to  FNumbers 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-InferedPossiblyIncomplete represents a value like a list /that can be the result of an incomplete parse. 0The case of an incomplete parse is indicated by  Just message. DIt is not possible to merge this functionality in the parser monad, ;because then it is not possible to define monadic binding. 4Emit a warning if a value is said to be incomplete.  Be careful using this function, (because an incomplete value often means Ithat subsequent parse actions will process data from the wrong position. Only use this function if you Neither know that the parse is complete also if the parsed value is incomplete 4or if there are no subsequent parse actions to run. This function cannot fail. This function will never fail. 'If the element parser fails somewhere, *a prefix of the complete list is returned along with the error message. <Parse until an element is found, which matches a condition. 2The terminating element is consumed by the parser %but not appended to the result list. LIf the end of the input is reached without finding the terminating element, >then an Incomplete exception (Just errorMessage) is signaled. This function will never fail. =It may however return a list that is shorter than requested. RS ! Safe-Infered " Safe-InferedDTreat errors which caused an incomplete data structure as warnings. IThis is reasonable, because we do not reveal the remaining unparsed data *and thus further parsing is not possible. # Safe-InferedDTreat errors which caused an incomplete data structure as warnings. IThis is reasonable, because we do not reveal the remaining unparsed data *and thus further parsing is not possible.   $ Safe-Infered*Since in case of an incomplete file read, 3we cannot know where the current file position is,  we omit the runIncompleteHandle variant.  Safe-Infered uvwxyz{|} uvwxyz{|} u{zyxwv|}u{zyxwv|}% Safe-Infered~.This definition should be in Message.Channel, %but this results in a cyclic import. The & monad parses a track of a MIDI File. EIn MIDI, a shortcut is used for long strings of similar MIDI events: FIf a stream of consecutive events all have the same type and channel, Athe type and channel can be omitted for all but the first event. To implement this feature, Rthe 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-InferedThe ReaderT Bool handles Fwhether running status should be respected (True) or ignored (False). @Given a writer that emits a status, generate a stateful writer, 0that decides whether to run the status emittor.   ' Safe-Infered$ gets a single byte from the input. getN n. returns n characters (bytes) from the input. , , , and  take 1-, 2-, 3-, or H4-byte numbers from the input (respectively), convert the base-256 data "into a single number, and return. Variable-length quantities" are used often in MIDI notation. +They are represented in the following way: VEach byte (containing 8 bits) uses the 7 least significant bits to store information. VThe 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. 1 gets a variable-length quantity from the input. MThe returned list contains only bytes with the most significant bit cleared. &These are digits of a 128-ary number.  Safe-Infered&Accidentals as used in key signature. ;The Key Signature specifies a mode, either major or minor. 0   ((,    Safe-Infered)This function is also used in alsa-midi, !we could give it the result type Parser.PossiblyIncomplete T otherwise.    Safe-Inferedalso includes SMPTE type   Safe-Infered      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~PONMLKJIHGFEDCBA@?>=<;:9876543210/.-,+*)('&%$#"!      Q~}|{zyxwvutsrqponmlkjihgfedcba`_^]\[ZYXWVUTSR      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~  Safe-InferedDIt is not checked whether SysEx messages contain only 7-bit values.   Safe-Infered  Safe-InferedBThere are three forms of System Exclusive Messages in MIDI files: Omonolithic, 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 Pwhich 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-Infered       Safe-Infered QNoteOn with zero velocity is considered NoteOff according to MIDI specification. QNoteOn with zero velocity is considered NoteOff according to MIDI specification.  Convert all  NoteOn p 0 to  NoteOff p 64. %The latter one is easier to process.  Convert all  NoteOff p 64 to  NoteOn p 0. IThe latter one can be encoded more efficiently using the running status. Convert pitch to frequency  according to the default tuning *given in MIDI 1.0 Detailed Specification. /A MIDI problem is that one cannot uniquely map a MIDI key to a frequency. )The frequency depends on the instrument. I don'7t know if the deviations are defined for General MIDI. 8If 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. +The velocity of an ordinary key stroke and the maximum possible velocity. +The velocity of an ordinary key stroke and the maximum possible velocity. MIDI specification says, +if velocity is simply mapped to amplitude, 5then this should be done by an exponential function.  Thus we map  (64) to 0,  (127) to 1, and minimumVelocity (1) to -1. 2That is, normally you should write something like %amplitude = 2 ** realFromVelocity vel or 3 ** realFromVelocity vel. <Map integral MIDI controller value to floating point value. ;Maximum integral MIDI controller value 127 is mapped to 1. 9Minimum integral MIDI controller value 0 is mapped to 0. ToDo: 'We have defined minBound = Velocity 0, /but strictly spoken the minimum Velocity is 1, #since Velocity zero means NoteOff. 5One can at least think of NoteOff with (Velocity 0), but I have never seen that. o      !"f      j      e      !" Safe-Infered#Parse an event. FNote that in the case of a regular MIDI Event, the tag is the status, 2and we read the first byte of data before we call %. 0In the case of a MIDIEvent with running status, 'we find out the status from the parser (it'0s been nice enough to keep track of it for us), and the tag that we'-ve already gotten is the first byte of data. $for internal use %Parse 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.  !"#$%&'# ~ !"#$%&'  !"%#&'~ $ !"#$%&'# Safe-Infered ()*+,-./01 ()*+,-./01 (*)+,-/0.1(*)+,-./01 Safe-InferedN>The default SetTempo value, in microseconds per quarter note. 4This expresses the default of 120 beats per minute. 23456789:;<=>?@ABCDEFGHIJKLMNOP$23456789:;<=>?@ABCDEFGHIJKLMNOP2BA@?>=<;:9876543IKJHMLNGFEDCOP2BA@?>=<;:9876543CDEFGHIJKLMNOP$ Safe-Infered\HEach event is preceded by the delta time: the time in ticks between the Glast event and the current event. Parse a time and an event, ignoring System Exclusive messages. ]'The following functions encode various )* elements +into the raw data of a standard MIDI file. QRSTUVWXYZ[\]%IJKQRSTUVWXYZ[\]QTSR[]U\IKJVWXYZ QTSRUVWXYZ[\]% Safe-Infered^5All methods have default implementations that return &. )This helps implementing event data types /that support only a subset of types of events. 3Maybe a better approach is to provide type classes for every type of event  and make ^ a subclass of all of them. ^_`abcdef'( ^_`abcdef ^_`abcdef^_`abcdef'( Safe-Inferedg5All methods have default implementations that return &. )This helps implementing event data types /that support only a subset of types of events. 3Maybe a better approach is to provide type classes for every type of event  and make g a subclass of all of them. ghijklmn)*ghijklmnghijklmnghijklmn)* Safe-Inferedopqrstuvwxyz{|}~      !"#$%&'()*+,-+,-.opqrstuvwxyz{|}~      !"#$%&'()*+,- !"#$%&     '()*+,-o~}|{zyxwvutsrqpo/~}|{zyxwvutsrqp      !"#$%&'()*+,-+,-. Safe-Infered 6-The datatypes for MIDI Files and MIDI Events 8An empty MIDI file. +Tempo is set to one tick per quarter note. 9 Convert all  NoteOn p 0 to  NoteOff p 64. %The latter one is easier to process. : Convert all  NoteOff p 64 to  NoteOn p 0. IThe latter one can be encoded more efficiently using the running status. <%Merge all tracks into a single track !according to the MIDI file type. =Process and remove all SetTempo events. EThe result is an event list where the times are measured in seconds. ? Show the 6 with one event per line, $suited for comparing MIDIFiles with diff. Can this be replaced by +,? B9A hack that changes the velocities by a rational factor. CChange the time base. D)Sort MIDI note events lexicographically. "This is to make MIDI files unique /and robust against changes in the computation. 2In principle Performance.merge should handle this $but due to rounding errors in Float @the order of note events still depends on some internal issues. 7The sample rate of MIDI events should be coarse enough to assert unique results. EOld versions of Haskore.Interface.MIDI.Write wrote -. and 8 /once at the beginning of a file in that order. &The current version supports multiple -.s in a track and thus a -.# is set immediately before a note. Because of this a -. is now always after a 8. FFor checking equivalence with old MIDI files we can switch this back. ./0123456789:;<=>?@ABCDE/0HIJKLM./0123456789:;<=>?@ABCDE67/10.25438IKJHML9:;<=>?BCA@DE./1025436789:;<=>?@ABCDE/0 Safe-InferedFThe 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 I instead. G>This function ignores warnings, turns exceptions into errors, -and return partial results without warnings. 7Use this only in testing but never in production code! JQFunctions to show the decoded contents of a MIDI file in an easy-to-read format. JThis is for debugging purposes and should not be used in production code. FGHIJFGHIJFGHIJFGHIJ Safe-InferedKDirectly write to a file. 3Since chunks lengths are not known before writing, we need to seek in a file. 3Thus you cannot write to pipes with this function. L The function L is the main function  for writing 6 values to an actual file. MConvert a MIDI file to a . NConvert a MIDI file to a lazy 1. OConvert a MIDI file to a lazy 1.  It converts  NoteOff p 64 to  NoteOn p 0 Eand then uses the running MIDI status in order to compress the file. K file name L file name MNOKLMNOKLMNOKLMNO/ Safe-Infered23232340123*456789:;<=>?*@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~*%%%*4*          *     *                                  ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _ ` a b c d e f g h i j k l m n o p q r s t u v w x y z { | } ~                                                                         *      *     *   *.BCDEFGIJKNOPQRSefghijlmnqrstuvwxyz|}~abcd*4**     *- !"#$%&'()*+,$%&'()*,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~*4,* *       !"#$%&'()*0+,-./012345<6789:;<=>?@7ABBCDDE7F$GHIJKLMNOPQRSTU V W X Y , Z [ $ \ ]  ^ _ ` a b c!*!4!d!!e!f!g!h!i"j"*"4"d""f"g"i#j#7#7#*#4#d#k##f#g#l#i$m$*$4$d$n$o$f$g$i%*%p%q%%%r%s%t&*&u&4&d&p&v&w&x&y&z&f&{|}r'\'~''''''''''''((((((((((0ffD//midi-0.2 Sound.MIDI.IOSound.MIDI.Parser.Report Sound.MIDI.Message.Channel.VoiceSound.MIDI.Controller"Sound.MIDI.Message.System.RealTimeSound.MIDI.Message.ChannelSound.MIDI.KeySignatureSound.MIDI.Message.Channel.Mode Sound.MIDI.Message.System.CommonSound.MIDI.Manufacturer#Sound.MIDI.Message.System.ExclusiveSound.MIDI.Message.System%Sound.MIDI.File.Event.SystemExclusiveSound.MIDI.MessageSound.MIDI.File.Event.MetaSound.MIDI.File.EventSound.MIDI.Message.Class.CheckSound.MIDI.Message.Class.QuerySound.MIDI.GeneralSound.MIDI.FileSound.MIDI.File.LoadSound.MIDI.File.SaveSound.MIDI.Parser.ExceptionSound.MIDI.Parser.WarningSound.MIDI.UtilitySound.MIDI.BitSound.MIDI.ControllerPrivate Data.ListlookupSound.MIDI.MonoidSound.MIDI.Writer.BasicSound.MIDI.Parser.ClassSound.MIDI.Parser.RestrictedSound.MIDI.Parser.ByteStringSound.MIDI.Parser.StreamSound.MIDI.Parser.FileSound.MIDI.Parser.StatusSound.MIDI.Writer.StatusSound.MIDI.Parser.PrimitiveSound.MIDI.StringMIDIFileTSound.MIDI.LoadshowFile MIDIEvent ProgramChange!Sound.MIDI.Example.ControllerRampbaseGHC.IO.Handle.FDopenBinaryFile UserMessageConswarningsresultByteListwriteBinaryFilelistCharFromBytereadBinaryFilelistByteFromChar 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 dataDecrementnonRegisteredParameterLSBnonRegisteredParameterMSBregisteredParameterLSBregisteredParameterMSBReset ActiveSensingStopContinueStart TimingClockgetputChannel fromChannel toChannel AccidentalsModeMinorMajorkeyNamecfMajorgfMajordfMajorafMajorefMajorbfMajorfMajorcMajorgMajordMajoraMajoreMajorbMajorfsMajorcsMajorafMinorefMinorbfMinorfMinorcMinorgMinordMinoraMinoreMinorbMinorfsMinorcsMinorgsMinordsMinorasMinortoBytesPolyModeMonoModeOmniMode AllNotesOff LocalControlResetAllControllers AllSoundOfffromControllerValuetoControllerValueTimeNibbleTypeHoursMSHoursLS MinutesMS MinutesLS SecondsMS SecondsLSFrameMSFrameLS TuneRequest SongSelectSongPositionPointerTimeCodeQuarterFrame 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 nonRealTimerealTimeRealTime NonRealTime NonCommercial Commercial getIncompleteCommon ExclusiveEscapeRegularProgram fromProgramVelocity fromVelocityPitch fromPitchControllerValuePressurePitchBendRangeMonoAftertouch PitchBendControlPolyAftertouchNoteOnNoteOffisNoteisNoteOn isNoteOffexplicitNoteOffimplicitNoteOfftoPitch toVelocity toProgram increasePitch subtractPitchfrequencyFromPitchzeroKeynormalVelocitymaximumVelocityrealFromVelocityrealFromControllerValue mainVolume mainVolumeMSB mainVolumeLSBportaextDepth putWithStatusBodyVoicemessageChannel messageBody getWithStatus decodeStatusSystemgetIncompleteWithStatusmaybeFromByteString toByteStringUnknownSequencerSpecificKeySigTimeSig SMPTEOffsetSetTempo EndOfTrack MIDIPrefixCuePointMarkerLyricInstrumentName TrackName Copyright TextEvent SequenceNum SMPTEBits SMPTEFrames SMPTESeconds SMPTEMinutes SMPTEHoursTempo ElapsedTime toElapsedTimefromElapsedTimetoTempo fromTempo defltTempoSystemExclusive MetaEvent TrackEventmapBodymaybeMIDIEventmaybeMetaEvent maybeVoicemapVoice getTrackEventCnoteprogram anyController pitchBendchannelPressuremode controllerliftMidiDrum OpenTriangle MuteTriangle OpenCuica MuteCuica LowWoodBlock HiWoodBlockClaves LongGuiro ShortGuiro LongWhistle ShortWhistleMaracasCabasaLowAgogo HighAgogo LowTimbale HighTimbaleLowConga OpenHiConga MuteHiCongaLowBongoHiBongo RideCymbal2 Vibraslap CrashCymbal2Cowbell SplashCymbal TambourineRideBell ChineseCymbal RideCymbal1HighTom CrashCymbal1HiMidTom LowMidTom OpenHiHatLowTom PedalHiHat HighFloorTom ClosedHiHat LowFloorTom ElectricSnareHandClap AcousticSnare SideStick BassDrum1AcousticBassDrum InstrumentGunshotApplause Helicopter TelephoneRing BirdTweetSeashore BreathNoiseGuitarFretNoise ReverseCymbal SynthDrum MelodicTom TaikoDrum Woodblock SteelDrumsAgogo TinkleBellShanaiFiddleBagpipeKalimbaKotoShamisenBanjoSitarFX8SciFi FX7Echoes FX6Goblins FX5Brightness FX4Atmosphere FX3Crystal FX2SoundtrackFX1Rain Pad8SweepPad7Halo Pad6Metallic Pad5Bowed Pad4Choir Pad3PolysynthPad2Warm Pad1NewAge Lead8BassLead Lead7Fifths Lead6Voice Lead5Charang Lead4Chiff Lead3Calliope Lead2Sawtooth Lead1SquareOcarinaWhistle Skakuhachi BlownBottlePanFluteRecorderFlutePiccoloClarinetBassoon EnglishHornOboe BaritoneSaxTenorSaxAltoSax SopranoSax SynthBrass2 SynthBrass1 BrassSection FrenchHorn MutedTrumpetTubaTromboneTrumpet OrchestraHit SynthVoice VoiceOohs ChoirAahs SynthStrings2 SynthStrings1StringEnsemble2StringEnsemble1TimpaniOrchestralHarpPizzicatoStringsTremoloStrings ContrabassCelloViolaViolin SynthBass2 SynthBass1 SlapBass2 SlapBass1 FretlessBassElectricBassPickElectricBassFinger AcousticBassGuitarHarmonicsDistortionGuitarOverdrivenGuitarElectricGuitarMutedElectricGuitarCleanElectricGuitarJazzAcousticGuitarSteelAcousticGuitarNylonTangoAccordian Harmonica Accordion ReedOrgan ChurchOrgan RockOrganPercussiveOrgan DrawbarOrganDulcimer TubularBells XylophoneMarimba VibraphoneMusicBox GlockenspielCelestaClavinet HarpsichordElectricPiano2ElectricPiano1 HonkyTonkElectricGrandPianoBrightAcousticPianoAcousticGrandPianoinstrumentNameToPrograminstrumentNamesinstrumentProgramsinstrumentFromPrograminstrumentToPrograminstrumentChannels instruments drumChannel drumProgram drumMinKey drumKeyTable drumFromKey drumToKeydrumsTrackDivisionSMPTETicksTypeSerialParallelMixedempty getTracks mergeTrackssecondsFromTicksticksPerQuarterNote showLinesshowTime showEventchangeVelocity resampleTime sortEventsprogChangeBeforeSetTempofromFile fromByteListmaybeFromByteListtoSeekableFiletoFile toByteListtoCompressedByteStringrungiveUptrywarnArbByte deconsArbByteArbChar deconsArbCharmapFstmapSndfst3snd3thd3toMaybeswap checkRangeviewR dropMatchuntilMloopM enumRandomRboundedEnumRandom chooseEnumquantityRandomRboundedQuantityRandomchooseQuantityarbitraryStringarbitraryByteList$fArbitraryArbByte$fArbitraryArbCharshiftLshiftRtoBase someBytesfromBase replicateBigGHC.List replicatetruncsplitAttoHextoOctaltoBits fromBytesfromHex fromOctalfromBits$fBoundedController$fEnumController$fArbitraryController$fRandomController+#+ genAppend genConcat concatMapputLengthBlockputByteListSpec putByteListputVar SeekableFileunSeekableFile ByteString unByteString unByteListputByte runByteList runByteStringrunSeekableFilerunSeekableHandleputIntputStr putIntAsByteputLenByteList$fCSeekableFile$fMonoidSeekableFile $fCByteString$fMonoidByteString $fCByteList$fMonoidByteListPossiblyIncompletewarnIncomplete zeroOrMoreuntilPartialFalliblegetByteskipEndCheckisEndwarnIf zeroOrMoreInc emptyList$fEndCheckStateTdecons runFallible$fCT $fEndCheckT $fMonadTransT$fMonadT runIncomplete runPartial$fByteStreamByteListrunIncompleteFilerunFile runHandleStatussetlift$fBoundedChannel $fEnumChannelchangeclear fromWritertoWritertoWriterWithStatustoWriterWithoutStatus $fMonoidTmonoid-transformer-0.0.2Data.Monoid.TransformergetNget1get2get3get4getVar getVarBytes getStringgetBigN getNByteIntgetNByteCardinalgetEnummakeEnum$fArbitraryAccidentals$fRandomAccidentals$fEnumAccidentals$fBoundedAccidentals$fArbitraryMode $fRandomMode $fArbitraryT$fShowTunlinesSconcatSrightSleftScentreSrightleftcentrespaces stateToReadS$fBoundedVelocity$fBoundedProgram$fBoundedPitch $fEnumProgram $fEnumPitch$fArbitraryProgram$fRandomProgram$fArbitraryVelocity$fRandomVelocity$fArbitraryPitch $fRandomPitch Data.MaybeNothing$fCT0$fArbitraryDrum $fRandomDrum$fArbitraryInstrument$fRandomInstrument$fArbitraryDivisionbytestring-0.9.2.1Data.ByteString.Lazy.Internalexamplemain