Slide 1

Slide 1 text

2025-01-11 ୈ66ճϓϩάϥϛϯάɾγϯϙδ΢Ϝ দӜ஌໵ / ౦ژ᥁ज़େֶ ܳज़৘ใηϯλʔ ([email protected]) ϥϜμܭࢉͷ֦ுʹجͮ͘
 Իָϓϩάϥϛϯάݴޠmimium
 ͱͦͷVMͷ࣮૷

Slide 2

Slide 2 text

• দӜ ஌໵ • 2019೥ະ౿ʮϓϩάϥϚϒϧͳԻָιϑτ ΢ΣΞͷ։ൃʯʢ஛ഭPMʣ • 2019~2022೥ɹ۝भେֶେֶӃ ܳज़޻ֶ෎ म࢜ɾത࢜՝ఔ • 2022೥͔Βɹ౦ژ᥁ज़େֶ ܳज़৘ใηϯλ ʔ(AMC) ಛ೚ॿڭ • ݚڀྖҬɿԻָ౔໦޻ֶʢCivil Engineering of Musicʣ ࣗݾ঺հ

Slide 3

Slide 3 text

minimal musical medium / mimi(ࣖ👂)+medium https://github.com/mimium-org/mimium-rs mimium(2020~) https://mimium.org

Slide 4

Slide 4 text

σϞಈը

Slide 5

Slide 5 text

RustͬΆ͍γϯλοΫεͷݴޠͰɺίϯύΠϥ΋Rust੡ɺWasmͰ΋ಈ࡞͢Δ ʢͨͩϑΝΠϧIO͕ͳ͍ͨΊϥΠϒϥϦಡΈࠐΈ͕ະ࣮૷ʣ

Slide 6

Slide 6 text

എܠ • ؔ਺ܕʹܗࣜԽ͞ΕͨԻָ৴߸ॲཧݴޠ • Իָϓϩάϥϛϯάݴޠʹ͓͚ΔUnit GeneratorύϥμΠϜͱ෼ۀԽ

Slide 7

Slide 7 text

ຊ೔ͷཁ఺ɿ ԻָʷݴޠॲཧܥͰ ΍ΕΔ͜ͱ͸ ·ͩ·ͩશવ͋Δ

Slide 8

Slide 8 text

{ var snare, bdrum, hihat; var tempo = 4; tempo = Impulse.ar(tempo); // for a drunk drummer replace Impulse with Dust !!! snare = WhiteNoise.ar(Decay2.ar(PulseDivider.ar(tempo, 4, 2), 0.005, 0.5)); bdrum = SinOsc.ar(Line.ar(120,60, 1), 0, Decay2.ar(PulseDivider.ar(tempo, 4, 0), 0.005, 0.5)); hihat = HPF.ar(WhiteNoise.ar(1), 10000) * Decay2.ar(tempo, 0.005, 0.5); Out.ar(0, (snare + bdrum + hihat) * 0.4 ! 2) }.play -o dac // real-time output sr = 44100 0dbfs = 1 nchnls = 2 ksmps = 64 instr 1 iAmp = p4 iFreq = p5 iAtt, iDec, iSus, iRel = 0.1, 0.4, 0.6, 0.7 kEnv = madsr:k(iAtt,iDec,iSus,iRel) iCutoff, iRes = 5000, 0.4 aVco = vco2:a(iAmp,iFreq) aLp = moogladder:a(aVco,iCutoff*kEnv,iRes) outall(aLp*kEnv) endin i 1 0 2 0.1 440 i 1 3 2 0.2 550 i 1 7 3 0.1 550 i 1 7 3 0.1 660 Cycling'74 Max CSound SuperCollider

Slide 9

Slide 9 text

ຊݚڀͰର৅ͱ͢ΔʮԻָϓϩάϥϛϯάʯ • ຊݚڀͰѻ͏ԻָϓϩάϥϛϯάͰ͸ɺ
 Ի੠೾ܗͷ਺ྻΛܭࢉ͢Δ㲈γϯηαΠβ ʔ΍ΤϑΣΫλʔͷهड़Λओʹର৅ʹ͢Δ • Իఔ΍ϝϩσΟɺϦζϜ΍ϋʔϞχʔͱ͍ ͬͨཁૉΛݴޠϓϦϛςΟϒͱͯ͠૊Έࠐ Ή͜ͱ͸૝ఆ͍ͯ͠ͳ͍ • ࡞ͬͨݴޠ্ͷϥΠϒϥϦ/DSLͱ࣮ͯ͠ ૷͞ΕΔ͜ͱ͸͋Γ͏Δ (Mathews 1963)ΑΓ

Slide 10

Slide 10 text

1960 1970 1980 1990 2000 2010 2020 1950 MUSIC 1 MUSIC 3 (UGen Language) IRCAM 4X Realtime- Variable DSP Pure Data SuperCollider ChucK Faust mimium MUSIC 5 ʢWritten in FORTRANʣ Max/FTS FORTRAN SAMSON BOX ϊϯϦΞϧλΠϜ ܭࢉػͰͷ Ի੠೾ܗੜ੒ ςΩετϑΥʔϚοτ ͰͷϓϩάϥϜهड़ ϋʔυ΢ΣΞࢧԉͰͷ ϦΞϧλΠϜ࣮ߦ ൚༻PCͰͷ ϦΞϧλΠϜ Ի੠߹੒ ݴޠͷ෼ۀԽ ؔ਺ܕϓϩάϥϛϯάͱͷ઀ଓ

Slide 11

Slide 11 text

MUSIC-NͱUnit Generator MUSIC III(1963) by Max Mathews • ৴߸ॲཧͷجૅ୯ҐʢUnitʣΛͭͳ͍͛ͯ͘ • ΦγϨʔλʔ΍ϑΟϧλʔɺΤϯϕϩʔϓ • ϒϩοΫμΠΞάϥϜΛࢴʹॻ͘ˠςΩετܗࣜ ʹॻ͖௚͢ˠύϯνΧʔυʹଧͪࠐΉ • ଟ͘ͷԻָϓϩάϥϛϯάݴޠ͕͜ͷίϯηϓτ ΛҾ͖ܧ͙ • ϓϩάϥϛϯάݴޠʹݶΒͣɺWebAudio API
 ͳͲ΋UGenͷߟ͑ํΛԼෑ͖ʹ͢Δ

Slide 12

Slide 12 text

UGenύϥμΠϜͷ໰୊఺ • طଘͷUGenͷ૊Έ߹ΘͤͰ࡞Εͳ͍΋ͷ͸CͳͲผͷݴޠͰ࡞Βͳ͍ͱ͍͚ ͳ͍
 →ࣗݾ֦ுੑͷෆ଍ • ෳ਺ͷݴޠͰࣅͨΑ͏ͳUGenΛͦΕͧΕ࠶࣮૷
 →ϙʔλϏϦςΟɺ૬ޓӡ༻ੑͷෆ଍ • UGenࣗମΛσʔλͱͨ͠ϝλૢ࡞ʢྫ:ฒྻ΍௚ྻͷΑ͏ͳෳ੡ʣ͕೉͍͠
 →ܗࣜԽͷෆ଍

Slide 13

Slide 13 text

ؔ਺ܕͷ৴߸ॲཧ Faustʢ2002~ʣ • ϒϩοΫμΠΞάϥϜ୅਺ɿೖग़ྗΛ࣋ͭϒϩοΫΛ5ͭͷԋࢉࢠͰ߹੒ • ฒྻ(,) ௚ྻ(:) ෼ذ(<:)߹ྲྀ(:>) ϑΟʔυόοΫ(~) • جຊϒϩοΫ: ఆ਺ / جຊ਺஋ԋࢉ / ஗Ԇ / ৚݅෼ذ* *Faustͷ৚݅෼ذ͸྆ϒϥϯνΛධՁ͔ͯ͠Β৚݅ʹ౰ͯ͸·Δ݁ՌΛऔΔ

Slide 14

Slide 14 text

Faustͷྑ͍఺ɾѱ͍఺ • +1ͭͷίʔυ͔Βෳ਺ͷόοΫΤϯυ΁ίϯύΠϧͰ͖Δ C++/Rust/LLVM IR... • طଘͷ൚༻ݴޠͱͷཧ࿦తͳޓ׵ੑɾ૬ޓӡ༻ੑʹ͚ܽΔ • - C֎෦ؔ਺͸ϓϦϛςΟϒ஋͔Β஋΁ͷ७ਮͳࣸ૾͔͠औΕͳ͍ʢϙΠϯλ͸ڐ͞Εͳ͍ʣ • +- FaustΛ༷ʑͳϓϥοτϑΥʔϜʹຒΊࠐΉ͜ͱ͸Ͱ͖ͯ΋ɺFaust͔Βϗετͷؔ਺Λݺ΂ͳ͍ • BDAͱ߲ॻ͖͔͑ϚΫϩͱ͍͏2ͭͷҙຯ࿦͕ಉډ͍ͯ͠Δ • +ϚΫϩͷύλʔϯϚονʹΑͬͯෳࡶͳ৴߸ॲཧάϥϑΛදݱͰ͖Δ • - ϚΫϩͷॻ͖ํΛؒҧ͑Δͱೖग़ྗͷ਺͕Ұக͠ͳ͍BDA͕ੜ੒͞ΕΔ͕ɺΤϥʔͷݪҼ͕ಛఆͮ͠Β͍ • -ίϯύΠϧ࣌ͷఆ਺ʢ੔਺ʣͱ৴߸ॲཧͷ਺஋ܕͷ஋ͱͷ۠ผ͕Θ͔Γʹ͍͘

Slide 15

Slide 15 text

΋͏ͪΐͬͱී௨ͷؔ਺ܕݴޠͰɺ ϦΞϧλΠϜ৴߸ॲཧ͕ॻ͚ͯཉ͍͠

Slide 16

Slide 16 text

ʢ༨ஊʣͰ͸ɺ൚༻ݴޠͰ಺෦DSLΛ࡞Δͷ͸ʁ • ϓϦΤϯϓςΟϒεέδϡʔϦϯάͳOSԼͰͷϦΞϧλΠϜॲཧͷ໰୊ • ৴߸ॲཧதʹmalloc/freeݺͿͳɺmutexϩοΫ͢Δͳ • ௿ڃݴޠ or ϩοΫϑϦʔฒߦGCͳݴޠ or खಈͰGCͷλΠϛϯάܾΊΒΕΔݴޠ • DSLΛ࡞Γ΍͍͢ɺࣗݾ൓өੑͷߴ͍ݴޠ΄ͲϦΞϧλΠϜॲཧͱ৯͍߹Θ͕ͤѱ͍ • 1ඵʹ48000~ճܭࢉ͢ΔͷͰ͋Δఔ౓όοϑΝʹཷΊͯ·ͱΊͯॲཧ • →࿦ཧ࣌ؒʢॱংͷΈߟྀʣͱ࣮࣌ؒʢMIDIͳͲͷೖग़ྗ࣌ʣͷ੔߹ੑͷ໰୊

Slide 17

Slide 17 text

ํ਑: λܭࢉ + ࣌ؒૢ࡞ʹؔΘΔ࠷খݶͷϓϦϛςΟϒ

Slide 18

Slide 18 text

ํ਑: λܭࢉ + ࣌ؒૢ࡞ʹؔΘΔ࠷খݶͷϓϦϛςΟϒ ஗ԆͱϑΟʔυόοΫ

Slide 19

Slide 19 text

mimiumʹ͓͚ΔϑΟʔυόοΫͷදݱ γϯϓϧͳੵ෼ʢϩʔύεϑΟϧλʣΛྫʹ fn onepole(x,g){ x*(1.0-g) + self*g } onepole(x,g) = (1.0 - g) * x + g * _ ~ _; onepole(x,g) = self ~ _ with { self(y) = (1.0 - g) * x + g * y; }; mimium Faust ΋͘͠͸ (ඪ४ϥΠϒϥϦͷsi.smoothΛ୯७Խͨ͠΋ͷ) 1୯Ґ࣌ࠁલͷฦΓ஋Λऔಘ

Slide 20

Slide 20 text

چόʔδϣϯͷmimiumͷ໰୊఺ • ҙຯ࿦͕·ͱ΋ʹఆٛ͞Ε͍ͯͳ͔ͬͨ • ಺෦ঢ়ଶ෇͖ؔ਺: self͔delayΛίʔϧπϦʔͷͲ͔͜Ͱݺͼग़ؔ͢਺ ͱɺߴ֊ؔ਺Λ૊Έ߹ΘͤΔͱίϯύΠϧ͕௨Βͳ͘ͳΔ • = ϑΟʔυόοΫ΍஗Ԇ༻ͷ಺෦ঢ়ଶͷͨΊͷϝϞϦαΠζΛ֬ఆͰ͖ͳ͍ • ৴߸ॲཧάϥϑͷύϥϝτϦοΫͳੜ੒ʹݶք͕͋Δ • →ݴޠͱίϯύΠϥͷશ໘తͳ࠶ઃܭ΁

Slide 21

Slide 21 text

ϥϜμܭࢉϕʔεͷDSPݴޠͷઌߦྫ • Kronos[Norilo 2015] • System-FωʢܕˠܕͷϥϜμந৅͕Մೳͳߴ֊ϥϜμܭࢉͷόϦΤʔγϣϯʣΛ ϕʔεʹ͢Δ • ܕϨϕϧͷܭࢉ͕৴߸ॲཧάϥϑͷύϥϝτϦοΫͳੜ੒ʹରԠ • ܗࣜԽ͞Εͨҙຯ࿦ͷఏࣔ͸ͳ͠ʢιʔείʔυ͸ެ։ʣ • W-Calculus[Arias et al. 2021], CoqͰূ໌͕ຒΊࠐ·Ε͍ͯΔ • ߴ֊ؔ਺Λڐ͞ͳ͍ / ઢܗ࣌ෆมγεςϜʢΤίʔͱ͔ʣ͔͠ॻ͚ͳ͍ W-calculusͷ੍ݶΛ؇ΊͯϝϞϦ؅ཧͱ͔͸ϥϯλΠϜଆͰؤுͬͯ΋Β͏ => λmmm

Slide 22

Slide 22 text

ຊൃදͷείʔϓ fn onepole(x,g){ x*(1.0-g) + self*g } ιʔείʔυ AST(≒λmmm) ܕਪ࿦ ˍ MIRੜ੒ LLVM-like SSA MIR CONSTANTS:[1.0] state_size:1 fn onepole(x,g) MOVECONST 2 0 MOVE 3 1 SUBF 2 2 3 MOVE 3 0 MULF 2 2 3 GETSTATE 3 MOVE 4 1 MULF 3 3 4 ADDF 2 2 3 GETSTATE 3 SETSTATE 2 RETURN 3 1 όΠτίʔυ ੜ੒ Ծ૝ػց όΠτίʔυ φΠʔϒͳ ΠϯλϓϦλ ʢඇޮ཰ʣ 2.γϯλοΫε 3. ҙຯ࿦ 4. VM & όΠτίʔυ ͜ͷ෦෼ͷܗࣜԽ͸future work

Slide 23

Slide 23 text

ຊൃදͷείʔϓ fn onepole(x,g){ x*(1.0-g) + self*g } ιʔείʔυ AST(≒λmmm) ܕਪ࿦ ˍ MIRੜ੒ LLVM-like SSA MIR CONSTANTS:[1.0] state_size:1 fn onepole(x,g) MOVECONST 2 0 MOVE 3 1 SUBF 2 2 3 MOVE 3 0 MULF 2 2 3 GETSTATE 3 MOVE 4 1 MULF 3 3 4 ADDF 2 2 3 GETSTATE 3 SETSTATE 2 RETURN 3 1 όΠτίʔυ ੜ੒ Ծ૝ػց όΠτίʔυ φΠʔϒͳ ΠϯλϓϦλ ʢඇޮ཰ʣ 2.γϯλοΫε 3. ҙຯ࿦ 4. VM & όΠτίʔυ ͜ͷ෦෼ͷܗࣜԽ͸future work ׂѪ

Slide 24

Slide 24 text

ЕNNNͷγϯλοΫε

Slide 25

Slide 25 text

λmmm ͷγϯλοΫε (࣮ࡍʹ͸λϓϧͷΑ͏ͳ߹੒ܕ΋͋Δ͕ຊݚڀͰ͸୯७ԽͷͨΊলུʣ e ::= x x ∈ vp [value] | λx.e [lambda] | let x = e1 in e2 [let] | fix x.e [fixpoint] | e1 e2 [app] | if (ec ) et else ee [if ] | delay n e1 e2 n ∈ ℕ [delay] | feed x.e [feed] | ... τp ::= R [real] | N [nat] τ ::= τp | τ → τ [function] ஋ ߲ vp ::= r r ∈ ℝ | n n ∈ ℕ v ::= vp | cls(λx.e, E) ܕ

Slide 26

Slide 26 text

ܕ෇͚نଇ(ൈਮ) Γ, x : τa ⊢ e : τb Γ ⊢ λx.e : τa → τb [T-LAM] Γ ⊢ n : N Γ ⊢ e1 : τ Γ ⊢ e2 : R Γ ⊢ delay n e1 e2 : τ [T-DELAY] Γ, x : τp ⊢ e : τp Γ ⊢ feedx.e : τp [T-FEED] Γ ⊢ ec : R Γ ⊢ et : τ Γ ⊢ ee : τ Γ ⊢ if (ec ) et ee : τ [T-IF] "ؔ਺ΛؚΉ͋ΒΏΔܕ͔Βܕ΁ͷࣸ૾Λڐ͢" "஗Ԇ࣌ؒΛࢦఆ͢Δ߲͸࣮਺ܕ" "৚݅෼ذͷ৚݅͸࣮਺ܕ" "Feed͸ؔ਺ΛؚΉܕΛऔΕͳ͍" "࠷େ஗Ԇ࣌ؒ͸ࣗવ਺ͷఆ਺"

Slide 27

Slide 27 text

ܕ෇͚نଇ(ൈਮ) Γ, x : τa ⊢ e : τb Γ ⊢ λx.e : τa → τb [T-LAM] Γ ⊢ n : N Γ ⊢ e1 : τ Γ ⊢ e2 : R Γ ⊢ delay n e1 e2 : τ [T-DELAY] Γ, x : τp ⊢ e : τp Γ ⊢ feedx.e : τp [T-FEED] Γ ⊢ ec : R Γ ⊢ et : τ Γ ⊢ ee : τ Γ ⊢ if (ec ) et ee : τ [T-IF] ԾʹFeed͕ؔ਺ܕΛऔΔͱ͢Δͱɺ ʮ1αϯϓϧલͷؔ਺Λ࢖ͬͯ࣍ͷ࣌ࠁͷ ؔ਺Λ߹੒͢Δʯ͜ͱʹͳΔɻ →࣌ؒܦաͱͱ΋ʹ࢖༻ϝϞϦ͕૿େ ʢ㲈FRPʹ͓͚Δspace-leak໰୊ʣ

Slide 28

Slide 28 text

ЕNNNͷ φΠʔϒͳૢ࡞తҙຯ࿦

Slide 29

Slide 29 text

λmmm ͷૢ࡞తҙຯ࿦ (Ϗοάεςοϓɺൈਮ) En ⊢ e1 ⇓ v1 n > v1 En−v1 ⊢ e2 ⇓ v2 En ⊢ delay n e1 e2 ⇓ v2 [E-DELAY] En ⊢ λx.e ⇓ cls(λx.e, En) [E-LAM] En−1 ⊢ e ⇓ v1 En, x ↦ v1 ⊢ e ⇓ v2 En, x ↦ v2 ⊢ feed x e ⇓ v1 [E-FEED] En ⊢ ec ⇓ n n > 0 En ⊢ et ⇓ v En ⊢ if(ec ) et else et ⇓ v [E-IFTRUE] En ⊢ ec ⇓ n n ≦ 0 En ⊢ ee ⇓ v En ⊢ if(ec ) et else et ⇓ v [E-IFFALSE] En ⊢ e1 ⇓ cls(λxc .ec , En c )En ⊢ e2 ⇓ v2 En c , xc ↦ v2 ⊢ ec ⇓ v En ⊢ e1 e2 ⇓ v [E-APP] ࣌ࠁnʹ͓͚ΔධՁ؀ڥΛ Enͱ͢Δ n<0ͷ؀ڥ͕ࢀর͞Εͨ৔߹0 Λฦ͢ɻ ͜ͷҙຯ࿦Ͱ͸ɺ࣌ࠁnͷܭࢉ ݁ՌΛಘΔͨΊʹɺ࣌ࠁ0͔Βn ·ͰͷܭࢉΛຖճ΍Γ௚͢͜ͱ ʹͳΔɻ

Slide 30

Slide 30 text

ЕNNNΛ࣮ߦ͢ΔͨΊͷ7.

Slide 31

Slide 31 text

λmmm Λ࣮ߦ͢ΔͨΊͷVMͱόΠτίʔυ • Lua VM 5.0Λݩʹઃܭ (ϨδελϚγϯ͕ͩɺϨδελ൪߸͸୯ʹίʔϧελοΫͷ૬ ରతͳҐஔΛද͢) • Ϋϩʔδϟ͕Ωϟϓνϟͨࣗ͠༝ม਺Λ `getupvalue`໋ྩͰ࣮ߦ࣌ʹऔಘͰ͖Δ • ͜ΕΛɺ੩తܕ෇͚ݴޠ༻ʹվม • ྫɿΫϩʔδϟͷݺͼग़͠ͱී௨ͷؔ਺ݺͼग़͠ͷ໋ྩΛ෼͚Δ • Ϋϩʔδϟ͚͕ͩώʔϓΞϩέʔτ (ݱࡏ͸ࢀরΧ΢ϯτGCͰ؅ཧ) • self ͱ delay༻ͷ಺෦ঢ়ଶૢ࡞໋ྩΛ௥Ճ

Slide 32

Slide 32 text

MOVE A B R(A) := R(B) MOVECONST A B R(A) := K(B) GETUPVALUE A B R(A) := U(B) (SETUPVALUE does not exist) GETSTATE* A R(A) := SPtr[SPos] SETSTATE* A SPtr[SPos] := R(A) SHIFTSTATE* sAx SPos += sAx DELAY* A B C R(A) := update_ringbuffer(SPtr[SPos],R(B),R(C)) *(SPos,SPtr)= vm.closures[vm.statepos_stack.top()].state (if vm.statepos_stack is empty, use global state storage.) JMP sAx PC +=sAx JMPIFNEG A sBx if (R(A)<0) then PC += sBx CALL A B C R(A),...,R(A+C-2) := program.functions[R(A)](R(A+1),...,R(A+B-1)) CALLCLS A B C vm.statepos_stack.push(R(A)) R(A),...,R(A+C-2) := vm.closures[R(A)].fnproto(R(A+1),...,R(A+B-1)) vm.statepos_stack.pop() CLOSURE A Bx vm.closures.push(closure(program.functions[R(Bx)])) R(A) := vm.closures.length - 1 CLOSE A close stack variables up to R(A) RETURN A B return R(A), R(A+1)...,R(A+B-2) ADDF A B C R(A) := R(B) as float + R(C) as float SUBF A B C R(A) := R(B) as float - R(C) as float MULF A B C R(A) := R(B) as float * R(C) as float DIVF A B C R(A) := R(B) as float / R(C) as float ADDI A B C R(A) := R(B) as int + R(C) as int ...Other basic arithmetic continues for each primitive types... (࣮ࡍͷίϯύΠϥͰ͸߹੒ܕΛѻ͏ ͨΊɺଟ͘ͷ໋ྩͰϫʔυαΠζΛࣔ ͢௥ՃΦϖϥϯυ͕ಋೖ͞Ε͍ͯΔ)

Slide 33

Slide 33 text

VMͱϓϩάϥϜͷߏ଄ͷ֓ཁ Virtual Machine Program Counter State_Ptr Stack Audio Driver Call Stack ... State Storage Closure Storage Base Pointer State Position State for self 1 Ring Buffer for delay 1 State for self 2 Ring Buffer for delay 2 ... Program Function Prototype0 Static Variables ... ... Function Prototype1 OP A B C OP A B C OP A B C OP A B C OP A B C Upvalue List Program State Size Local(N1) Upvalue(N2) Open Closure Function Prototype State Storage Upvalues Open(Local(N1)) Open(Upvalue(N2)) State Position Escaped Closure Function Prototype State Storage Upvalues State Position Closed Upvalue 1 Closed Upvalue 2 Somewhere on the Heap Memory (Maybe Shared with other closures)

Slide 34

Slide 34 text

಺෦ঢ়ଶ෇͖ؔ਺Λ࢖༻͠ͳ͍৔߹ɿ Virtual Machine Program Counter Audio Driver Call Stack ... Closure Storage Base Pointer Program Function Prototype0 Static Variables ... ... Function Prototype1 OP A B C OP A B C OP A B C OP A B C OP A B C Upvalue List Program Local(N1) Upvalue(N2) Open Closure Function Prototype Upvalues Open(Local(N1)) Open(Upvalue(N2)) Escaped Closure Function Prototype Upvalues Closed Upvalue 1 Closed Upvalue 2 Somewhere on the Heap Memory (Maybe Shared with other closures)

Slide 35

Slide 35 text

ྫɿϑΟʔυόοΫ෇͖σΟϨΠΛෳ਺࢖༻͢Δ fn fbdelay(x,fb,dtime){ x + delay(1000,self,dtime)*fb } fn twodelay(x,dtime){ fbdelay(x,dtime,0.7) +fbdelay(x,dtime*2,0.8) } fn dsp(x){ twodelay(x,400)+twodelay(x,800) } "fbdelay" ؔ਺͸࠷େͰ1000αϯϓϧͷ delayͱ selfΛ࢖༻ "twodelay"͸"fbdelay"2ճ࢖༻ "dsp"͸"twodelay"Λ͞Βʹ2ճ࢖͏

Slide 36

Slide 36 text

CONSTANTS:[0.7,2,0.8,400,800,0,1] fn fbdelay(x,fb,dtime) state_size:1004 MOVE 3 0 //load x GETSTATE 4 SHIFTSTATE 1 DELAY 4 4 2 MOVE 5 1 MULF 4 4 5 ADDF 3 3 4 SHIFTSTATE -1 GETSTATE 4 SETSTATE 3 RETURN 4 1 fn twodelay(x,dtime) state_size:2008 MOVECONST 2 5 MOVE 3 0 MOVE 4 1 MOVECONST 5 0 CALL 2 3 1 SHIFTSTATE 1004 MOVECONST 3 5 MOVE 4 0 MOVECONST 5 1 //load 2 MULF 4 4 5 MOVECONST 5 0 //load 0.7 CALL 3 3 1 ADDF 3 3 4 SHIFTSTATE -1004 RETURN 3 1 fn dsp (x) state_size:4016 MOVECONST 1 6 //load twodelay MOVE 2 0 MOVECONST 3 3 //load 400 CALL 1 2 1 SHIFTSTATE 2008 MOVECONST 2 6 //load twodelay MOVE 2 3 MOVE 3 0 MOVECONST 3 4 //load 400 CALL 2 2 1 ADD 1 1 2 SHIFTSTATE -2008 RETURN 1 1 όΠτίʔυͷٙࣅίʔυදݱ

Slide 37

Slide 37 text

fn fbdelay(x,fb,dtime) state_size:1004 MOVE 3 0 //load x GETSTATE 4 SHIFTSTATE 1 DELAY 4 4 2 MOVE 5 1 MULF 4 4 5 ADDF 3 3 4 SHIFTSTATE -1 GETSTATE 4 SETSTATE 3 RETURN 4 1 State for Self Ring Buffer for Delay SPos ... ...

Slide 38

Slide 38 text

fn fbdelay(x,fb,dtime) state_size:1004 MOVE 3 0 //load x GETSTATE 4 SHIFTSTATE 1 DELAY 4 4 2 MOVE 5 1 MULF 4 4 5 ADDF 3 3 4 SHIFTSTATE -1 GETSTATE 4 SETSTATE 3 RETURN 4 1 State for Self Ring Buffer for Delay SPos "self"Λࢀর SPos͔Β1ϫʔυ෼ಡΈग़͠ɺ Ϩδελ4΁֨ೲ ... ...

Slide 39

Slide 39 text

fn fbdelay(x,fb,dtime) state_size:1004 MOVE 3 0 //load x GETSTATE 4 SHIFTSTATE 1 DELAY 4 4 2 MOVE 5 1 MULF 4 4 5 ADDF 3 3 4 SHIFTSTATE -1 GETSTATE 4 SETSTATE 3 RETURN 4 1 State for Self Ring Buffer for Delay SPos ... ... SPosͷҐஔΛ1ϫʔυ෼Φϑηοτ

Slide 40

Slide 40 text

fn fbdelay(x,fb,dtime) state_size:1004 MOVE 3 0 //load x GETSTATE 4 SHIFTSTATE 1 DELAY 4 4 2 MOVE 5 1 MULF 4 4 5 ADDF 3 3 4 SHIFTSTATE -1 GETSTATE 4 SETSTATE 3 RETURN 4 1 State for Self Ring Buffer for Delay SPos ... ... SPosͷҐஔͷϦϯάόοϑΝΛߋ৽ ೖྗ͸Ϩδελ4ɺ஗Ԇ࣌ؒ͸Ϩδελ2͔Βऔಘɺ ߋ৽ͨ͠ઌ಄ΛϨδελ4ʹॻ͖ࠐΈ

Slide 41

Slide 41 text

fn fbdelay(x,fb,dtime) state_size:1004 MOVE 3 0 //load x GETSTATE 4 SHIFTSTATE 1 DELAY 4 4 2 MOVE 5 1 MULF 4 4 5 ADDF 3 3 4 SHIFTSTATE -1 GETSTATE 4 SETSTATE 3 RETURN 4 1 State for Self Ring Buffer for Delay SPos ... ... SPosͷҐஔΛݩʹ໭͢ ʢؔ਺ͷίϯςΩετΛൈ͚Δ࣌ʹ͸ɺ
 ։࢝࣌ͱಉ͡Ґஔʹ໭͍ͬͯͳ͚Ε͹ͳΒͳ͍ʣ

Slide 42

Slide 42 text

fn fbdelay(x,fb,dtime) state_size:1004 MOVE 3 0 //load x GETSTATE 4 SHIFTSTATE 1 DELAY 4 4 2 MOVE 5 1 MULF 4 4 5 ADDF 3 3 4 SHIFTSTATE -1 GETSTATE 4 SETSTATE 3 RETURN 4 1 State for Self Ring Buffer for Delay SPos ... ... selfʹฦΓ஋Λॻ͖ࠐΉ

Slide 43

Slide 43 text

fn twodelay(x,dtime) state_size:2008 MOVECONST 2 5 MOVE 3 0 MOVE 4 1 MOVECONST 5 0 CALL 2 3 1 SHIFTSTATE 1004 MOVECONST 3 5 MOVE 4 0 MOVECONST 5 1 //load 2 MULF 4 4 5 MOVECONST 5 0 //load 0.7 CALL 3 3 1 ADDF 3 3 4 SHIFTSTATE -1004 RETURN 3 1 State for Self Ring Buffer for Delay SPos ... ... State for Self Ring Buffer for Delay 0 1 2 1ͭ໨ͷ"fbdelay"ݺͼग़͠

Slide 44

Slide 44 text

fn twodelay(x,dtime) state_size:2008 MOVECONST 2 5 MOVE 3 0 MOVE 4 1 MOVECONST 5 0 CALL 2 3 1 SHIFTSTATE 1004 MOVECONST 3 5 MOVE 4 0 MOVECONST 5 1 //load 2 MULF 4 4 5 MOVECONST 5 0 //load 0.7 CALL 3 3 1 ADDF 3 3 4 SHIFTSTATE -1004 RETURN 3 1 State for Self Ring Buffer for Delay ... ... State for Self Ring Buffer for Delay 0 1 2 SPos 3 self༻ʹ1, delay༻ʹ1000ʴಡΈग़͠Ґஔʴॻ͖ࠐΈҐஔʴαΠζ => 1004

Slide 45

Slide 45 text

fn twodelay(x,dtime) state_size:2008 MOVECONST 2 5 MOVE 3 0 MOVE 4 1 MOVECONST 5 0 CALL 2 3 1 SHIFTSTATE 1004 MOVECONST 3 5 MOVE 4 0 MOVECONST 5 1 //load 2 MULF 4 4 5 MOVECONST 5 0 //load 0.7 CALL 3 3 1 ADDF 3 3 4 SHIFTSTATE -1004 RETURN 3 1 State for Self Ring Buffer for Delay ... ... State for Self Ring Buffer for Delay 0 1 2 SPos 3 4 5 2ͭ໨ͷ "fbdelay"ͷݺͼग़͠

Slide 46

Slide 46 text

fn twodelay(x,dtime) state_size:2008 MOVECONST 2 5 MOVE 3 0 MOVE 4 1 MOVECONST 5 0 CALL 2 3 1 SHIFTSTATE 1004 MOVECONST 3 5 MOVE 4 0 MOVECONST 5 1 //load 2 MULF 4 4 5 MOVECONST 5 0 //load 0.7 CALL 3 3 1 ADDF 3 3 4 SHIFTSTATE -1004 RETURN 3 1 State for Self Ring Buffer for Delay ... ... State for Self Ring Buffer for Delay 0 1 2 SPos 3 4 5 6 SPosΛݩͷҐஔʹ໭͢

Slide 47

Slide 47 text

fn dsp (x) state_size:4016 MOVECONST 1 6 //load twodelay MOVE 2 0 MOVECONST 3 3 //load 400 CALL 1 2 1 SHIFTSTATE 2008 MOVECONST 2 6 //load twodelay MOVE 2 3 MOVE 3 0 MOVECONST 3 4 //load 400 CALL 2 2 1 ADD 1 1 2 SHIFTSTATE -2008 RETURN 1 1 State for Self Ring Buffer for Delay State for Self Ring Buffer for Delay 0 1 2 SPos 3 4 5 6 State for Self Ring Buffer for Delay State for Self 1ͭ໨ͷ"twodelay"ͷݺͼग़͠

Slide 48

Slide 48 text

fn dsp (x) state_size:4016 MOVECONST 1 6 //load twodelay MOVE 2 0 MOVECONST 3 3 //load 400 CALL 1 2 1 SHIFTSTATE 2008 MOVECONST 2 6 //load twodelay MOVE 2 3 MOVE 3 0 MOVECONST 3 4 //load 400 CALL 2 2 1 ADD 1 1 2 SHIFTSTATE -2008 RETURN 1 1 State for Self Ring Buffer for Delay State for Self Ring Buffer for Delay 0 1 2 SPos 3 4 5 6 State for Self Ring Buffer for Delay State for Self 7 2ͭ໨ͷ"twodelay"ͷݺͼग़͠

Slide 49

Slide 49 text

fn dsp (x) state_size:4016 MOVECONST 1 6 //load twodelay MOVE 2 0 MOVECONST 3 3 //load 400 CALL 1 2 1 SHIFTSTATE 2008 MOVECONST 2 6 //load twodelay MOVE 2 3 MOVE 3 0 MOVECONST 3 4 //load 400 CALL 2 2 1 ADD 1 1 2 SHIFTSTATE -2008 RETURN 1 1 State for Self Ring Buffer for Delay State for Self Ring Buffer for Delay 0 1 2 SPos 3 4 5 6 State for Self Ring Buffer for Delay State for Self 7 8 9 10 11 12 13 2ͭ໨ͷ"twodelay"ͷݺͼग़͠

Slide 50

Slide 50 text

fn dsp (x) state_size:4016 MOVECONST 1 6 //load twodelay MOVE 2 0 MOVECONST 3 3 //load 400 CALL 1 2 1 SHIFTSTATE 2008 MOVECONST 2 6 //load twodelay MOVE 2 3 MOVE 3 0 MOVECONST 3 4 //load 400 CALL 2 2 1 ADD 1 1 2 SHIFTSTATE -2008 RETURN 1 1 State for Self Ring Buffer for Delay State for Self Ring Buffer for Delay 0 1 2 SPos 3 4 5 6 State for Self Ring Buffer for Delay State for Self 7 8 9 10 11 12 13 14 SPosΛ໭͢

Slide 51

Slide 51 text

fn dsp (x) state_size:4016 MOVECONST 1 6 //load twodelay MOVE 2 0 MOVECONST 3 3 //load 400 CALL 1 2 1 SHIFTSTATE 2008 MOVECONST 2 6 //load twodelay MOVE 2 3 MOVE 3 0 MOVECONST 3 4 //load 400 CALL 2 2 1 ADD 1 1 2 SHIFTSTATE -2008 RETURN 1 1 State for Self Ring Buffer for Delay State for Self Ring Buffer for Delay 0 1 2 SPos 3 4 5 6 State for Self Ring Buffer for Delay State for Self 7 8 9 10 11 12 13 14 SPosͷҠಈΛ૬ରతͳΦϑηοτͰ දݱ͢ΔͷͰɺ֤ؔ਺ఆٛ͸ݺͼग़͠ ݩʹ͍ͭͯ஌Βͳͯ͘Α͍

Slide 52

Slide 52 text

ߴ֊ؔ਺ͱ಺෦ঢ়ଶ෇͖ؔ਺ͷ૊Έ߹Θͤ fn bandpass(x,freq){ //... } fn filterbank(n,filter_factory){ if (n>0){ let filter = filter_factory() let next = filterbank(n-1,filter_factory) |x,freq| filter(x,freq+n*100)ɹ+ next(x,freq) }else{ |x,freq| 0 } } let myfilter = filterbank(3,| | bandpass) fn dsp(){ myfilter(x,1000) }

Slide 53

Slide 53 text

ߴ֊ؔ਺ͱ಺෦ঢ়ଶ෇͖ؔ਺ͷ૊Έ߹Θͤ fn bandpass(x,freq){ //... } fn filterbank(n,filter_factory){ if (n>0){ let filter = filter_factory() let next = filterbank(n-1,filter_factory) |x,freq| filter(x,freq+n*100)ɹ+ next(x,freq) }else{ |x,freq| 0 } } let myfilter = filterbank(3,| | bandpass) fn dsp(){ myfilter(x,1000) } Ҿ਺ͱͯ͠༩͑ΒΕΔ fi lter_factoryͷ಺෦ঢ়ଶαΠζ͸ ίϯύΠϧ࣌ʹ֬ఆͰ͖ͳ͍

Slide 54

Slide 54 text

Virtual Machine Program Counter State_Ptr Stack Audio Driver Call Stack ... State Storage Closure Storage Base Pointer State Position State for self 1 Ring Buffer for delay 1 State for self 2 Ring Buffer for delay 2 ... Program Function Prototype0 Static Variables ... ... Function Prototype1 OP A B C OP A B C OP A B C OP A B C OP A B C Upvalue List Program State Size Local(N1) Upvalue(N2) Open Closure Function Prototype State Storage Upvalues Open(Local(N1)) Open(Upvalue(N2)) State Position Escaped Closure Function Prototype State Storage Upvalues State Position Closed Upvalue 1 Closed Upvalue 2 Somewhere on the Heap Memory (Maybe Shared with other closures) $-0463&໋ྩʹΑͬͯΫϩʔδϟ͕ΠϯελϯεԽ͞ΕΔ࣌ɺ Ϋϩʔδϟ্ʹ಺෦ঢ়ଶετϨʔδΛผ్֬อ͢Δ

Slide 55

Slide 55 text

Virtual Machine Program Counter State_Ptr Stack Audio Driver Call Stack ... State Storage Closure Storage Base Pointer State Position State for self 1 Ring Buffer for delay 1 State for self 2 Ring Buffer for delay 2 ... Program Function Prototype0 Static Variables ... ... Function Prototype1 OP A B C OP A B C OP A B C OP A B C OP A B C Upvalue List Program State Size Local(N1) Upvalue(N2) Open Closure Function Prototype State Storage Upvalues Open(Local(N1)) Open(Upvalue(N2)) State Position Escaped Closure Function Prototype State Storage Upvalues State Position Closed Upvalue 1 Closed Upvalue 2 Somewhere on the Heap Memory (Maybe Shared with other closures) CALLCLS ໋ྩͰΫϩʔδϟΛݺͼग़͢ͱ͖ɺGET/SET/SHIFTSTATE/DELAY໋ྩͰ ࢖༻͢Δ಺෦ঢ়ଶετϨʔδͷϙΠϯλΛઐ༻ͷελοΫʹੵΜͰ੾Γସ͑Δ

Slide 56

Slide 56 text

CONSTANTS[100,1,0,2] fn inner_then(x,freq) //upvalue: [local(4),local(3),local(2),local(1)] GETUPVALUE 3 2 //load filter MOVE 4 0 MOVE 5 1 GETUPVALUE 6 1 //load n ADDD 5 5 6 MOVECONST 6 0 MULF 5 5 6 CALLCLS 3 2 1 //call filter GETUPVALUE 4 4 //load next MOVE 5 0 MOVE 6 1 CALLCLS 4 2 1 //call next ADDF 3 3 4 RETURN 3 1 fn inner_else(x,freq) MOVECONST 2 2 RETURN 2 1 fn filterbank(n,filter_factory) MOVE 2 0 //load n MOVECONST 3 2 //load 0 SUBF 2 2 3 JMPIFNEG 2 12 MOVE 2 1 //load filter_factory CALL 2 2 0 //get filter MOVECONST 3 1 //load itself MOVE 4 0 //load n MOVECONST 5 1 //load 1 SUBF 4 4 5 MOVECONST 5 2 //load inner_then CALLCLS 3 2 1 //recursive call MOVECONST 4 2 //load inner_then CLOSURE 4 4 //load inner_lambda JMP 2 MOVECONST 4 3 //load inner_else CLOSURE 4 4 CLOSE 4 RETURN 4 1 "GET/SET/SHIFTSTATE/DELAY"͸Ҿ਺ͱͯ͠౉͞ΕΔ fi lter_factoryͷதͰ ͚ͩݺ͹Εͯɺ fi lterbankؔ਺Ͱ͸࢖༻͞Ε͍ͯͳ͍

Slide 57

Slide 57 text

ߴ֊ؔ਺ͱ಺෦ঢ়ଶ෇͖ؔ਺ͷ૊Έ߹Θͤ fn bandpass(x,freq){ //... } fn filterbank(n,filter_factory:()->(float,float)->float){ if (n>0){ let filter = filter_factory() let next = filterbank(n-1,filter_factory) |x,freq| filter(x,freq+n*100) + next(x,freq) }else{ |x,freq| 0 } } let myfilter = filterbank(3,| | bandpass) fn dsp(){ myfilter(x,1000) } ݁ہɺΦϒδΣΫτࢦ޲ϓϩάϥϛϯάʹ͓͚Δ Unit GeneratorͷίϯετϥΫλʹ૬౰͢Δ

Slide 58

Slide 58 text

ٞ࿦ • ifࣜʹΑΔ෦෼తͳ಺෦ঢ়ଶߋ৽ͷҙຯ • ֎෦ؔ਺ͷݺͼग़͠ͷྫ • ߴ֊ؔ਺࢖༻࣌ͷLetଋറͷҐஔʹΑΔҙຯͷมԽ

Slide 59

Slide 59 text

ଞݴޠͱͷൺֱ ύϥϝτϦοΫͳ
 ৴߸ॲཧάϥϑͷੜ੒ ࣮ࡍͷDSP Faust ߲ॻ͖͔͑ϚΫϩ ϒϩοΫμΠΞάϥϜ୆਺ Kronos ܕϨϕϧܭࢉ ஋Ϩϕϧܭࢉ mimium άϩʔόϧ؀ڥͷ஋ධՁ dsp ؔ਺ͷධՁ mimiumͰ͸ͲͪΒ΋ಉ͡ҙຯ࿦Ͱ஋ϨϕϧͷධՁɻ 
 ͜Ε͸ॳֶऀʹͱͬͯΘ͔Γ΍͍͢ͱ΋ݴ͑Δ͕ɺҰํͰ...

Slide 60

Slide 60 text

ಈ͔ͳ͍ίʔυͷྫ fn filterbank(n,filter){ if (n>0){ |x,freq| filter(x,freq+n*100) + filterbank(n-1,filter)(x,freq) }else{ |x,freq| 0 } } fn dsp(){ filterbank(3,bandpass)(x,1000) }

Slide 61

Slide 61 text

ಈ͔ͳ͍ίʔυͷྫ fn filterbank(n,filter){ if (n>0){ |x,freq| filter(x,freq+n*100) + filterbank(n-1,filter)(x,freq) }else{ |x,freq| 0 } } fn dsp(){ filterbank(3,bandpass)(x,1000) } ͜ͷॻ͖ํͩͱɺΫϩʔδϟ͕ຖ࣌ࠁੜ੒͞Εɺ ಺෦ঢ়ଶ͕ຖ࣌ࠁϦηοτ͞Εͯ͠·͏

Slide 62

Slide 62 text

ଟஈ֊ܭࢉΛಋೖͰ͖ͨ৔߹ɿ fn filterbank(n,filter:&(float,float)->float)->&(float,float)->float{ .< if (n>0){ |x,freq| ~filter(x,freq+n*100) + ~filterbank(n-1,filter)(x,freq) }else{ |x,freq| 0 } >. } fn dsp(){ ~filterbank(3,..)(x,1000) } *BER MetaOCamlͬΆ͍γϯλοΫεΛ࠾༻ͨ͠૝ఆͷٙࣅίʔυ

Slide 63

Slide 63 text

֎෦ͷεςʔτϑϧͳؔ਺ݺͼग़͠ • fi lterbankͷΑ͏ͳߴ֊ؔ਺ͷݺͼग़͠ˠؔ਺ݺͼग़͠͸ɺOOPʹ͓͚Δίϯ ετϥΫλͷݺͼग़͠ʹ૬౰͢ΔͱղऍͰ͖Δ • طଘͷωΠςΟϒʹ࣮૷͞ΕͨUnit Generator΋ɺബ͍ϥούΛॻ͚ͩ͘Ͱ mimium্͔Βݺͼग़͢͜ͱ͕Մೳ

Slide 64

Slide 64 text

let sampler = gen_sampler_mono("target.wav") fn counter(){ self+1.0 } fn dsp(){ sampler(counter()) }

Slide 65

Slide 65 text

fn gen_sampler_mono(machine: &mut Machine) -> ReturnCode { let abspath = {...}; let vec = load_wavfile_to_vec(abspath.to_str().unwrap()) .inspect_err(|e| { panic!("gen_sampler_mono error: {}", e); }) .unwrap(); //ಡΈࠐ·ΕͨԻ੠഑ྻ͸࣍ͷΫϩʔδϟͰΩϟϓνϟɺϜʔϒ͞ΕΔ let res = move |machine: &mut Machine| -> ReturnCode { let pos = vm::Machine::get_as::(machine.get_stack(0)); let val = interpolate_vec(&vec, pos); machine.set_stack(0, Machine::to_value(val)); 1 }; let ty = function!(vec![numeric!()], numeric!()); //mimium্ͷܕγάωνϟ let idx = machine.wrap_extern_cls(("sampler_mono".to_symbol(), ɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹRc::new(RefCell::new(res)), ty)); machine.set_stack(0, Machine::to_value(idx)); 1 } Rust্Ͱ͸LuaͰͷόΠϯσΟϯάͷΑ͏ʹɺVMͷίʔϧελοΫ౳Λ௚઀ૢ࡞

Slide 66

Slide 66 text

fn gen_sampler_mono(machine: &mut Machine) -> ReturnCode { //return higher order closure let abspath = { ... }; let vec = load_wavfile_to_vec(abspath.to_str().unwrap()) .inspect_err(|e| { panic!("gen_sampler_mono error: {}", e); }) .unwrap(); //the generated vector is moved into the closure let res = move |machine: &mut Machine| -> ReturnCode { let pos = vm::Machine::get_as::(machine.get_stack(0)); let val = interpolate_vec(&vec, pos); machine.set_stack(0, Machine::to_value(val)); 1 }; let ty = function!(vec![numeric!()], numeric!()); //mimium্ͷܕγάωνϟ let idx = machine.wrap_extern_cls(("sampler_mono".to_symbol(), Rc::new(RefCell::new(res)), ty)); machine.set_stack(0, Machine::to_value(idx)); 1 } Rust্Ͱ͸LuaͷόΠϯσΟϯάͷΑ͏ʹɺVMͷίʔϧελοΫ౳Λ௚઀ૢ࡞

Slide 67

Slide 67 text

impl Plugin for SamplerPlugin { fn get_ext_functions(&self) -> Vec { let t = function!(vec![string_t!()], function!(vec![numeric!()], numeric!())); let sig = ( "gen_sampler_mono".to_symbol(), gen_sampler_mono as ExtFunType, t, ); vec![sig] } } PluginτϨΠτΛ௨ͯ͡mimium͔Βݺͼग़ͨ͢Ίͷ໊લͱܕ৘ใɺ࣮ࡍʹݺͼग़͞ΕΔؔ਺ΛΤΫεϙʔτ ʢࠓޙ͸खଓ͖ϚΫϩͰόΠϯσΟϯάੜ੒ΛࣗಈԽ͍ͨ͠ʣ

Slide 68

Slide 68 text

࣮ࡍɺݱঢ়ͷmimiumͰ͸MIDIೖྗ΍೾ܗඳըͳͲͷ֎෦IO΋ߴ֊ؔ਺ͷύλʔϯͰ࣮૷͞Ε͍ͯΔ ʢ͜ΕΒ͸ɺVMॳظԽ࣌΍άϩʔόϧ؀ڥධՁޙɺdspؔ਺ͷ֤࣌ࠁͷ࣮ߦલޙͳͲͰ
 άϩʔόϧͳΠϯελϯεΛૢ࡞͢ΔίʔϧόοΫΛࠩ͠ࠐΊΔSystemPluginτϨΠτΛ࣮૷͍ͯ͠Δʣ

Slide 69

Slide 69 text

·ͱΊ • λmmm: ஋ݺͼ୯७ܕ෇͖ϥϜμܭࢉσΟϨΠͱϑΟʔυόοΫΛ௥Ճͨ͠ମܥ • ͦΕΛ࣮ߦ͢ΔͨΊͷVMͱ໋ྩηοτͷઃܭ • GET/SET/SHIFTSTATE/DELAYͰσΟϨΠͱϑΟʔυόοΫΛऔΓѻ͏ • ߴ֊ؔ਺Ͱ಺෦ঢ়ଶΛऔΓѻ͏ͨΊʹɺΫϩʔδϟͷΠϯελϯε͕಺෦ঢ়ଶετϨʔδΛ࣋ͭ • ύϥϝτϦοΫͳ৴߸ॲཧੜ੒ͱɺ࣮ࡍͷॲཧͷ࣮ߦΛಉ͡ҙຯ࿦Ͱ࣮ߦͰ͖Δ • ҙຯ࿦Λֶश͠΍͘͢͸͋Δ͕ɺϢʔβʔ͸ίʔυ͕άϩʔόϧධՁͱDSPධՁͲͪΒͰߦΘΕ Δ͔Λ஫ҙ͠ͳ͚Ε͹ͳΒͳ͍ • Իָͱ͍͏υϝΠϯʹಛԽͯ͠͸͍Δ͕ɺ൚༻ੑɺࣗݾ֦ுੑɺ૬ޓӡ༻ੑΛอͬͨݴޠ

Slide 70

Slide 70 text

͝ਗ਼ௌ͋Γ͕ͱ͏͍͟͝·ͨ͠ɻ email: [email protected] mastodon: social.matsuuratomoya.com/@tomoya https://github.com/mimium-org/mimium-rs mimium v2։ൃϦϙδτϦ(RustͰॻ͍ͯ·͢) https://mimium.org/ja