Files
midi-playlist/lib/__pycache__/midikit.cpython-314.pyc
T

118 lines
24 KiB
Plaintext
Raw Normal View History

+
é·Òj=ãó®€Rt^RIt/R^bR^bR^bR^bR^bR^bR^bR ^ bR
^
bR ^ bR ^ bR
^
bR^bR^bR^bR^bR^b/R^bR^bR^bR^bR^bR^bR^bR^ bR^!bR^"bR^#bR^$bR^&bR ^'bR!^(bR"^(bR#^)bC/R$^*bR%^+bR&^,bR'^-bR(^.bR)^/bR*^0bR+^1bR,^2bR-^3bR.^4bR/^5bR0^=bR1^<bR2^9bR3^:bR4^AbC/R5^BbR6^CbR7^DbR8^GbR9^EbR:^FbR;^FbR<^IbR=^HbR>^JbR?^LbR@^MbRA^NbRB^ObRC^ObRD^PbRE^QbC/RF^RbRG^SbRH^TbRI^UbRJ^VbRK^WbRL^XbRM^YbRN^ZbRO^[bRP^\bRQ^]bRR^cbRS^bbRT^hbRU^ibRV^kbCRW^rRX^bRY^c/Ct/RZ^#bR[^$bR\^#bR]^%bR^^&bR_^'bR`^*bRa^,bRb^.bRc^-bRd^/bRe^2bRf^1bRg^3bRh^4bRi^6bRj^8bRk^5Rl^'Rm^F/Ct]P /Rn^$bRo^#bRp^&bRq^'bRr^*bRs^*bRt^,bRu^.bRv^-bRw^-bRx^/bRy^2bRz^1bR{^3bR|^4bR}^6bR~^8bR^%Rm^F/C4R€tR�tR‚tRƒtR„t R…t
!R†R‡4t !RˆR‰4t !RŠR‹4t
RŒtRŽR�ltR#)�uL
midikit — a dependency-free Standard MIDI File (SMF) writer + reader.
Pure Python stdlib. Written for retro game audio work: DOS/OPL-flavoured
Sound Blaster tunes, N64-era ambient, chiptune. Everything a 1993 sound
card would choke on is optional; everything it handled is here.
Why not midiutil/mido? Because this library has to run on any box with a
Python and no network. Zero imports beyond struct.
Quick start:
from midikit import MidiFile, Track, MPQN
mf = MidiFile(tpq=480)
t = Track("Lead")
t.program(0, 81) # channel 0 -> Square Lead (GM 81)
t.note(0, 62, 480, 100) # ch, pitch, duration, velocity
mf.add_track(t)
mf.add_tempo_track([MPQN(0, 500000)]) # 120 BPM
mf.write("tune.mid")
Author: Kevin Hermes (kevinhermes.retroweb.dev)
License: do what you like, credit appreciated.
Nzacoustic grandzbright acousticzelectric piano 1zelectric piano 2Ú harpsichordÚclavinetÚcelestaÚ glockenspielz music boxÚ
vibraphoneÚmarimbaÚ xylophonez
tubular bellsz
drawbar organzpercussive organz
rock organz church organzacoustic nylonzacoustic steelz
electric jazzzclean electriczmuted electricÚ overdriveÚ
distortionz
acoustic basszelectric bass fingerzelectric bass pickÚfretlessz slap bass 1z synth bass 1z synth bass 2z chorus bassÚviolinÚviolaÚcelloÚ
contrabassztremolo stringszpizzicato stringszorchestral harpÚtimpanizstring ensemble 1zstring ensemble 2zsynth strings 1zsynth strings 2z
choir aahsz
voice oohsz
synth trumpetÚhornÚtromboneÚtubaz soprano saxzalto saxz tenor saxz baritone saxÚclarinetÚoboez english hornÚbassoonÚfluteÚpiccoloÚrecorderz pan flutez blown bottleÚ
shakuhachiÚwhistleÚocarinaz square leadz
sawtooth leadz
calliope leadz
chiff leadz charang leadz
voice leadz fifths leadz bass+leadz new age padzwarm padz
polysynth padzspace voice padz glass padz sweep padzfx: rainzfx: soundtrackÚsitarÚbanjoÚkotoz calypso drumÚcrystalÚ
atmospherezacoustic bass drumz bass drum 1z bass drum 2z
side stickzacoustic snarezelectric snarez
closed hi-hatz pedal hi-hatz open hi-hatzlow tomzmid tomzhigh tomz crash cymbalz ride cymbalz china cymbalÚ
tambourineÚcowbellz ride bellÚclapÚshakerÚbass1Úbass2ÚsnareÚesnrÚhatÚ closedhatÚpedalhatÚopenhatÚlotomÚlowtomÚmidtomÚhightomÚcrashÚrideÚchinaÚtambÚcowÚstickçgÀ_@cóê€V^8d \R4h\V^,.4pV^,pV'd+VPV^,^€,4V^,pK2\\ V44#)z1Encode an int as a MIDI variable-length quantity.zdelta times cannot be negative)Ú
ValueErrorÚ bytearrayÚappendÚbytesÚreversed)ÚnÚouts& Ú+/root/midi-playlist/tests/../lib/midikit.pyÚvlqrBbs^€àˆ1„uÜÐ9Ó:Ð:Ü
�Q˜•X�JÓ
€C؈!…G€Aß
Ø �
‰
�A˜•H Õ$Ô%Ø ˆa�ŠÜ ”˜#“Ó Ðócó¶€^pW,pV^,
pV^,V^,,pV^€,'gW!3#V\V48¼gKM\R4h)z4Decode a VLQ at data[pos]; returns (value, new_pos).z
truncated VLQ)Úlenr:)ÚdataÚposÚvalueÚbs&& rAÚ parse_vlqrJnsT€à
€EØ
Ø �IˆØ ˆq�ˆØ˜!•  D¥Õ)ˆØ�4�xŒxØ�:Ð Ø ”#�d“)Ö Ü˜_Ó-Ð -rCcó*€VP4p^pV\V48d5W,P4'gW,R8Xg V^,
pKDV^,P4V^V\ WR4rCpR^R^R^R^R^R^ R ^ /V,pWSP R
4^VP R 4,,,
pWSP R 4^VP R
4,,,pV^,^ ,V,#)z1'A4', 'C#5', 'Bb3' -> MIDI note number. A4 == 69.Ú-NÚCÚDÚEÚFÚGÚAÚBÚ#ÚsrIÚf)ÚstriprEÚisdigitÚupperÚintÚcount)ÚnameÚiÚletterÚ
accidentalÚoctaveÚbases& rAÚnoterb{sê€à �:‰:‹<€DØ €AØ
Œc�$‹iŒ- ¥§¡×!2Ò!2°dµgÀ´nØ ˆQ�ŠØ!% a¥§¡£°$°q¸°)¼SÀÀbÀ»]˜€FØ ��C˜˜C  C¨¨C°°C¸¸CÀÐ DÀVÕ L€DØ× Ñ ˜SÓ ! A¨
×(8Ñ(8¸Ó(=Õ$=Õ =Õ=€DØ× Ñ ˜SÓ ! A¨
×(8Ñ(8¸Ó(=Õ$=Õ =Õ=€DØ �Q�J˜"Õ ˜tÕ #Ð#rCcód€.ROpW^ ,,\V^ ,^,
4,#)z%MIDI note number -> 'C#5' style name.) rMzC#rNzD#rOrPzF#rQzG#rRzA#rS)Ústr)ÚpÚnamess& rAÚ note_namergˆs%€â M€EØ �R•�=œ3˜q B�w¨�{Ó+Õ +Ð+rCcóDa€]tRt^ŽtoRtRtRt]R4tRt Rt
Vt R#)ÚMPQNz?A tempo change: microseconds per quarter note at absolute tick.có€WnW nR#©N©ÚtickÚmpqn)Úselfrmrns&&&rAÚ__init__Ú
MPQN.__init__’s €ØŒ ØŽ rCc óF€V!V\\RV, 444#©i‡“)rZÚround)ÚclsrmÚbpms&&&rAÚfrom_bpmÚ
MPQN.from_bpm–s€á�4œœU :°Õ#3Ó4Ó5Ó6Ð6rCcó(€RVP, #rs)rn©ros&rArvÚMPQN.bpmšs€Ø˜DŸI™IÕ%Ð%rC)rnrmNrl) Ú__name__Ú
__module__Ú __qualname__Ú__firstlineno__Ú__doc__Ú __slots__rpÚ classmethodrwrvÚ__static_attributes__Ú__classdictcell__©Ú
__classdict__s@rAririŽs0ø‡€ÙIØ €Iòðñ7óð7÷&ð&rCricó¢a€]tRt^žtoRtRRltRtRRltRRltRRlt RRlt
RR lt RR
lt RR lt
RR ltR
tRtRtRtRtRtVtR#)ÚTrackuA musical track: notes, controllers, pitch bends, meta, in absolute ticks.
All events are stored with absolute tick positions and sorted on write,
so you can compose out of order — melody first, then bass, then fix
velocities — without worrying about delta-time bookkeeping.
Ncó,€WnW n.VnR#rk)r\ÚchannelÚevents)ror\rŠs&&&rArpÚTrack.__init__¦s€ØŒ ØŒ ØˆŽ rCcó@€VPPWV34R#rk)r‹r<)rormÚorderÚpayloads&&&&rAÚ_addÚ
Track._add¬s€Ø � ‰ ×јD¨Ð1Ö2rCc ó€Vf
VPMTpVPV^\^�V,V^,\^\ V44^,.44VPW,^\^€V,V^,^.44V#)zJNote on at tick, off at tick+duration. Overlap-safe (running-status-free).)rŠr�r=ÚmaxrZ)rormÚpitchÚdurationÚvelocityrŠÚchs&&&&&& rArbÚ
Track.note°sq€à$š_ˆT�\Š\°'ˆØ � ‰ �$˜œ5 $¨¥)¨U°T­\¼3¸qÄ#ÀhÃ-Ó;PÐSWÕ;WÐ!XÓYÔZØ � ‰ �$•/ 1¤e¨T°B­Y¸À½ ÀaÐ,HÓ&IÔJ؈ rCc óD€VFwr4rVVPW4WVV4K V#)z0seq of (tick, pitch, duration, velocity) tuples.)rb)roÚseqrŠÚtreÚdÚvs&&& rAÚnotesÚ Track.notes·s%€ã‰JˆA�!Ø �I‰I�a˜A 'Ö *ñàˆ rCc óä€Vf
VPMTp\V\4'd\VP 4,pVP V^\
^ÀV,V^,.44V#rk)rŠÚ
isinstancerdÚGMÚlowerr�r=)rormÚpatchrŠr—s&&&& rAÚprogramÚ
Track.program½sU€Ø$š_ˆT�\Š\°'ˆÜ �eœS× !Ò !Ü�u—{‘{“}Õ%ˆEØ � ‰ �$˜œ5 $¨¥)¨U°T­\Ð!:Ó;Ô<؈ rCc
ó’€Vf
VPMTpVPV^\^°V,V^,V^,.44V#rk)rŠr�r=)rormÚ
controllerrHrŠr—s&&&&& rAÚccÚTrack.ccÄs?€Ø$š_ˆT�\Š\°'ˆØ � ‰ �$˜œ5 $¨¥)¨Z¸$Õ->ÀÈÅ Ð!MÓNÔO؈ rCc
 óì€Vf
VPMTp\R\R\V444R,pVP V^\ ^àV,V^,V^, ^,.44V#)zvalue -8192..8191 (0 = centre).é éÿiàÿÿ)rŠr“ÚminrZr�r=)rormrHrŠr—r�s&&&& rAÚ
pitch_bendÚTrack.pitch_bendÉs^€à$š_ˆT�\Š\°'ˆÜ �”s˜4¤ U£Ó,Ó -°Õ 4ˆØ � ‰ �$˜œ5 $¨¥)¨Q°­X¸¸Q½À$µÐ!GÓHÔI؈ rCc ó€€\R\RW$, 44pVPV\VR,4V4#)zBBend to a semitone offset (assumes pitch-bend range = range_semi).çð?r­gð¿)r“r®r¯rZ)rormÚ semitonesrŠÚ
range_semiÚfracs&&&&& rAÚbend_toÚ
Track.bend_toÐs4€ä�4œ˜S )Õ"8Ó9Ó:ˆØ�‰˜t¤S¨°­Ó%5°wÓ?Ð?rCcó(€VPV^V4#©é)r¯)rormrŠs&&&rAÚ
bend_resetÚTrack.bend_resetÕs€Ø�‰˜t Q¨Ó0Ð0rCc
ó‚€VPV^\^ÿV.4\\V44,V,4V#r¹)r�r=rBrE)rormÚ type_byterFs&&&&rAÚmetaÚ
Track.metaÙs3€Ø � ‰ �$˜œ5 $¨ Ð!2Ó3´c¼#¸d»)³nÕDÀtÕKÔL؈ rCcóF€VPV^VPR44#)éúlatin-1©r¿Úencode©rormrUs&&&rAÚtextÚ
Track.textÝó€Ø�y‰y˜˜t Q§X¡X¨iÓ%8Ó9Ð9rCcóF€VPV^VPR44#)érÃrÄrÆs&&&rAÚmarkerÚ Track.markeràrÉrCcó(€VP4^cR3#)écsÿ/)Ú _max_tickrzs&rAÚ_endÚ
Track._endäs€Ø—‘Ó  " oÐ6Ð6rCcó>€\RVP4^R7#)c3ó,"€TF
wpq!x€K R#5irk©)Ú.0r›Ú_s& rAÚ <genexpr>Ú"Track._max_tick.<locals>.<genexpr>èsé€Ð1¡[™'˜!˜Q ”A£[ùs‚)Údefault)r“r‹rzs&rArÐÚTrack._max_tickçs€ÜÑ1 T§[¢[Ó1¸1Ô=Ð=rCcó0€\VPVP4.,RR7p\4pVP'dhV\ ^4\
^ÿ^.4,\ \VP44,VPPR4,,
p^pVF'wrEpV\ WC,
4V,,
pTpK) R\P!R\V44,\
V4,#)có&€V^,V^,3#r¹rÕ)Úes&rAÚ<lambda>ÚTrack.build.<locals>.<lambda>ës€ÀAÀaÅDÈ!ÈAÍ$Á<rC©ÚkeyrÃóMTrkú>I) Úsortedr‹rÑr;r\rBr=rErÅÚstructÚpack)ror‹r@ÚlastrmÚ_orderr�s& rAÚbuildÚ Track.buildêsǀܘŸ ™  t§y¡y£{ mÕ3Ñ9OÔPˆÜ‹kˆØ �9�9ˆ9Ø ”3�q“6œE 4¨ ,Ó/Õ/´#´c¸$¿)¹)³nÓ2EÕEÈÏ É ×HXÑHXÐYbÓHcÕcÕ cˆC؈Û%+Ñ !ˆD˜'Ø ”3�t•{Ó# gÕ-Õ -ˆCØŠDñ&,𜟚 T¬3¨s«8Ó4Õ4´u¸S³zÕAÐArC)rŠr‹r\)Nrº)édNrk)Né)rC)r|r}r~rr€rpr�rbržr¥r©r¯r¶r»r¿rÇrÌrÑrÐrêrƒr„r…s@rArˆrˆžs]ø‡€ñôò 3ôôô ôô
ô@ô
1ôò:ò:ò7ò>÷ Bð BrCrˆcóPa€]tRt^ötoRtR
RltRtRtR RltRt Rt
Rt Vt R #) ÚMidiFilezŠFormat 1 multi-track SMF. A conductor track is added automatically
from the tempo map so tempo/key/time live in their own track (GM-safe).cóJ€Wn.Vn.VnRVnRVnR#rk)ÚtpqÚtracksÚtemposÚkey_sigÚtime_sig)rorñs&&rArpÚMidiFile.__init__ús#€ØŒØˆŒ ؈Œ ؈Œ ؈Ž
rCcó<€VPPV4V#rk)ròr<)roÚtracks&&rAÚ add_trackÚMidiFile.add_tracks€Ø � ‰ ×ј5Ô!؈ rCc ó&€\V4VnR#)z=Set the tempo map; build() renders it into a Conductor track.N)Úlistró)rorós&&rAÚadd_tempo_trackÚMidiFile.add_tempo_tracks