Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Pythonでライブをしよう!FoxDotを使った新時代のPython活用法 / pyconjp-2019

sin-tanaka
September 17, 2019

Pythonでライブをしよう!FoxDotを使った新時代のPython活用法 / pyconjp-2019

PyCon JP 2019 の発表資料です

sin-tanaka

September 17, 2019
Tweet

More Decks by sin-tanaka

Other Decks in Programming

Transcript

  1. <"%>גࣜձࣾ೔ຊγεςϜٕݚ +4- • ࡢ೥ʹҾ͖͖ͭͮɺࠓ೥΋1Z$PO+1εϙϯαʔ • ࠓ೥͸ͳΜͱ(PME • ௕໺ݝ௕໺ࢢͷձࣾ • 1ZUIPO%KBOHPΛ࢖༻ͨ͠8FCΞϓϦέʔγϣϯͷडୗ։ൃٴͼɺαʔόʔϨε

    ΞʔΩςΫνϟΛ࢖༻ͨ͠ϑϩϯτΤϯυҊ݅΍*P5Ҋ݅ͱ͍ͬͨϓϩμΫτ։ൃ ΋΍ͬͯ·͢ • ίϛϡχςΟεϖʔεʮ(&&,-"#/"("/0ʯͷӡӦ • ࠓ೥౓͔ΒϚείοτΩϟϥΫλʔ͕஀ੜ
 • ؔ౦ݍͷ͓٬༷Λத৺ʹϦϞʔτϫʔΫͰ͓࢓ࣄΛ΍Βͤͯ௖͍͍ͯΔ
  2. ϥΠϒίʔσΟϯάͬͯԿʁ > Live coding is a new direction in electronic

    music and video, and is getting somewhere interesting. Live coders expose and rewire the innards of software while it generates improvised music and/or visuals. All code manipulation is projected for your pleasure. ɹɹɹɹɹɹɹɹɹɹɹɹtoplap.org/about ΑΓҾ༻ w 0OUIFqZQSPHSBNNJOH w +VTUJOUJNFQSPHSBNNJOH BLB Իָө૾ΛΠϯλϥΫςΟϒʹੜ੒͢Δ ϥΠϒɾύϑΥʔϚϯε
  3. 1 Clock.bpm = 120 2 Root.default = ‘C’ 3 Scale.default

    = ‘major’ 4 5 d1 >> play(“X-O-”) 6 d2 >> play(“#”, dur=32) 7 8 p1 >> pluck([0,1,2,3,4,3,2,1], dur=1/2, amp=1.5) 9 p2 >> blip(P[0,var([2,4])], dur=1/4, oct=6) 10 11 vo >> loop(‘some/path/file.wav’, dur=4)
  4. 1 Clock.bpm = 120 2 Root.default = ‘C’ 3 Scale.default

    = ‘major’ 4 5 d1 >> play(“X-O-”) 6 d2 >> play(“#”, dur=32) 7 8 p1 >> pluck([0,1,2,3,4,3,2,1], dur=1/2, amp=1.5) 9 p2 >> blip(P[0,var([2,4])], dur=1/4, oct=6) 10 11 vo >> loop(‘some/path/file.wav’, dur=4) SynthDefs
  5. 1 Clock.bpm = 120 2 Root.default = ‘C’ 3 Scale.default

    = ‘major’ 4 5 d1 >> play(“X-O-”) 6 d2 >> play(“#”, dur=32) 7 8 p1 >> pluck([0,1,2,3,4,3,2,1], dur=1/2, amp=1.5) 9 p2 >> blip(P[0,var([2,4])], dur=1/4, oct=6) 10 11 vo >> loop(‘some/path/file.wav’, dur=4) PlayerObject SynthDefs
  6. 1 Clock.bpm = 120 2 Root.default = ‘C’ 3 Scale.default

    = ‘major’ 4 5 d1 >> play(“X-O-”) 6 d2 >> play(“#”, dur=32) 7 8 p1 >> pluck([0,1,2,3,4,3,2,1], dur=1/2, amp=1.5) 9 p2 >> blip(P[0,var([2,4])], dur=1/4, oct=6) 10 11 vo >> loop(‘some/path/file.wav’, dur=4) PatternObject PlayerObject SynthDefs
  7. 1 Clock.bpm = 120 2 Root.default = ‘C’ 3 Scale.default

    = ‘major’ 4 5 d1 >> play(“X-O-”) 6 d2 >> play(“#”, dur=32) 7 8 p1 >> pluck([0,1,2,3,4,3,2,1], dur=1/2, amp=1.5) 9 p2 >> blip(P[0,var([2,4])], dur=1/4, oct=6) 10 11 vo >> loop(‘some/path/file.wav’, dur=4) TimeDependentVar PatternObject PlayerObject SynthDefs
  8. 4ZOUI%FGT w 'PY%PUͷσϑΥϧτͰ༻ҙ͞Ε͍ͯΔԻ৭܈  QMBZʜυϥϜԻݯ w TUSPS1BUUFSO0CKFDUΛ౉͢ w ֤จࣈʹผʑͷԻݯׂ͕ΓৼΒΕ͍ͯΔ 

    MPPQʜࣗલͰ༻ҙͨ͠Ի੠ϑΝΠϧͷϧʔϓ w Ի੠ϑΝΠϧͷύεΛ౉͢  ͦΕҎ֎ʜγϯηαΠβʔͬΆ͍Ի৭ w MJTUPS1BUUFSO0CKFDUΛ౉͢
  9. 1MBZFS0CKFDU w 4ZOUI%FGTΛૢ࡞͢Δ w ଐੑΛฤू͢Δ͜ͱͰԻ৭΍Իߴɺ௕͞౳ΛมߋՄೳ 1 p9 >> pluck(dur=1) 2

    3 # 音の長さ(default: play=1/2, other=1) 4 p9.dur = 2 5 6 # 音量(default: 1) 7 p9.amp = 2 8 9 # 音高 10 p9.degree = [0,1,2,3] 11 12 # オクターブ(default: 5) 13 p9.oct = 7
  10. w ܁Γฦ͠Λදݱ͢ΔΦϒδΣΫτ w MJTUͷ಄ʹ1Λ͚ͭΔ w ࢖͍͜ͳ͢ͱ৑௕ͳίʔυΛආ͚ΒΕΔ 1 # list 2

    plain_list = [0,1,2,3] 3 4 # PatternObject 5 plain_pattern = P[0,1,2,3] 6 1BUUFSO0CKFDU
  11. w 1ZUIPOͷMJTUͱ͸ҧ͏ڍಈ w ศརͳϝιου͕ੜ͑ͯΔ 1 plain_list = [0,1,2,3] 2 plain_pattern

    = P[0,1,2,3] 3 4 # add 5 plain_list + [4,5,6,7] # [0, 1, 2, 3, 4, 5, 6, 7] 6 plain_pattern + [4,5,6,7] # P[4, 6, 8, 10] 7 8 # mul 9 plain_list * 2 # [0, 1, 2, 3, 0, 1, 2, 3] 10 plain_pattern * 2 # P[0, 1, 4, 6] 11 12 plain_pattern.reverse() # P[3,2,1,0] 13 plain_pattern.shuffle() # P[3,1,2,0] 14 plain_pattern.trim(3) # P[0,1,2] 15 1BUUFSO0CKFDU
  12. 5JNF%FQFOEFOU7BSJBCMFT w ࣌ؒͰมԽ͢Δ஋ w $MPDLʹґଘ 1 # 4拍ごとに0→1→2→3のように変化 2 time_depend_var

    = var([0,1,2,3],4) 3 4 # 4拍ごとに0→1→2→3のように徐々に変化 5 time_depend_var_linear = linvar([0,1,2,3],4) 6 7 # Clockに依存するので実行ごとに結果が変わる 8 print(time_depend_var) 9 print(time_depend_var_linear) 10
  13. 1ZUIPOͷจ๏ͰಡΈղ͘'PY%PU 1 # 何をしているのか? 2 d1 >> play(“X-O-”) 3 4

    # シフト演算子? 5 x = 0b_0001_0001 6 7 # 左シフト演算子 8 bin(x << 3) # 0b_1000_1000 9 # 右シフト演算子 10 bin(x >> 3) # 0b_10 11
  14. w ಛघϝιου w @@IPHF@@ TFMG 1 class OverrideCall: 2 """

    3 instanceを関数呼び出ししたときの挙動を上書きする 4 """ 5 def __call__(self): 6 return 'call' 7 8 foo = OverrideCall() 9 10 foo() # 'call' 1ZUIPOͷจ๏ͰಡΈղ͘'PY%PU
  15. w γϑτԋࢉࢠͷಈ͖Λ্ॻ͖ 1 foo = '' 2 3 class OverrideShift:

    4 def __rshift__(self, other): 5 return 'override shift' 6 7 bar = OverrideShift() 8 bar >> foo # override shift 9 1ZUIPOͷจ๏ͰಡΈղ͘'PY%PU
  16. w EJDUͷΑ͏ʹΞΫηεͨ͠ͱ͖ͷಈ͖Λ্ॻ͖ 1 class ExtDict: 2 def __getitem__(self, args): 3

    return args 4 5 d = ExtDict() 6 d['foo', 'bar'] # ('foo', 'bar') 7 1ZUIPOͷจ๏ͰಡΈղ͘'PY%PU
  17. ࠓ೔࿩ͨ͜͠ͱ·ͱΊ w ϥΠϒίʔσΟϯάͱ͍͏จԽ w 1ZUIPOͱ͍͑͹ʜ w σʔλ෼ੳ w 8FC w

    ϥΠϒίʔσΟϯάˡ/FX w 1ZUIPOͷಛघΫϥεͰ৭ʑมΘΔ w ԋࢉࢠͷڍಈ w ࣙॻతʹΞΫηεͨ͠ͱ͖ͷڍಈ౳ʑʜ
  18. More info… w GPYEPUPSH w UPQMBQPSH w -JWFDPEJOHͷਪਐஂମ w 1Z$PO$;

    w 3ZBO,JSLCSJEF1SPHSBNNJOH.VTJDGPS1FSGPSNBODF-JWFDPEJOH XJUI'PY%PUIUUQTXXXZPVUVCFDPNXBUDI W93/'#;M#FV*UT w 1ZUIPO-JWF$PEJOHc0,$PNQVUFS w ٕज़ॻలͰ൦෍IUUQTPLDPNQVUFSCPPUIQNJUFNT w ZPQQBPSH w ϥΠϒίʔσΟϯάͷॻ੶ग़ͨ͠ΓେֶͰߨ͍ٛͯ͠Δํͷ)1