From 83829d6ef525cbe711341791895bfb6d078428cf Mon Sep 17 00:00:00 2001 From: OpenCode Agent Date: Sun, 12 Apr 2026 16:31:31 -0300 Subject: [PATCH] feat(Agente 1): Implement FX Creator MCP Tools (T031-T035) - Add 5 new MCP tools to server.py: * create_riser (T031) - Pre-drop buildup effect * create_downlifter (T032) - Post-drop energy release * create_impact (T033) - Hit, crash, sub_drop, noise impacts * create_silence (T034) - Break/silence effects * create_fx_section (T035) - Complete FX sections - Add 5 handlers to __init__.py for Remote Script execution - Update skill_produccion_audio.md with FX tools documentation All tools exposed and ready for professional FX generation. Closes Agente 1 of 20 - FX Creator implementation --- __init__.py | 137 +++++++++++++ __pycache__/__init__.cpython-314.pyc | Bin 324442 -> 345242 bytes docs/skill_produccion_audio.md | 59 +++++- mcp_server/__pycache__/server.cpython-314.pyc | Bin 235586 -> 241302 bytes mcp_server/server.py | 182 ++++++++++++++++++ 5 files changed, 377 insertions(+), 1 deletion(-) diff --git a/__init__.py b/__init__.py index e349e7b..3c5e1c9 100644 --- a/__init__.py +++ b/__init__.py @@ -1385,6 +1385,143 @@ class _AbletonMCP(ControlSurface): "note": "Automation envelope planned; direct parameter automation is limited in this API context", } + # ------------------------------------------------------------------ + # FX CREATOR HANDLERS (T031-T035) - Professional FX generation + # ------------------------------------------------------------------ + + def _cmd_create_riser(self, track_index, start_bar, duration=8, intensity=0.8, + pitch_range=None, **kw): + """T031: Create a riser/buildup effect.""" + try: + from .mcp_server.engines.arrangement_engine import FXCreator + fx_creator = FXCreator() + if pitch_range is None: + pitch_range = (36, 84) + clip = fx_creator.create_riser( + track_index=int(track_index), + start_bar=int(start_bar), + duration=int(duration), + intensity=float(intensity), + pitch_range=tuple(pitch_range) + ) + return { + "success": True, + "clip_name": clip.name, + "track_index": clip.track_index, + "start_time": clip.start_time, + "duration": clip.duration, + "note_count": len(clip.notes) if clip.notes else 0, + } + except Exception as e: + self.log_message("Error creating riser: " + str(e)) + return {"success": False, "error": str(e)} + + def _cmd_create_downlifter(self, track_index, start_bar, duration=4, intensity=0.7, + pitch_range=None, **kw): + """T032: Create a downlifter effect.""" + try: + from .mcp_server.engines.arrangement_engine import FXCreator + fx_creator = FXCreator() + if pitch_range is None: + pitch_range = (72, 36) + clip = fx_creator.create_downlifter( + track_index=int(track_index), + start_bar=int(start_bar), + duration=int(duration), + intensity=float(intensity), + pitch_range=tuple(pitch_range) + ) + return { + "success": True, + "clip_name": clip.name, + "track_index": clip.track_index, + "start_time": clip.start_time, + "duration": clip.duration, + "note_count": len(clip.notes) if clip.notes else 0, + } + except Exception as e: + self.log_message("Error creating downlifter: " + str(e)) + return {"success": False, "error": str(e)} + + def _cmd_create_impact(self, track_index, position, intensity=1.0, impact_type="hit", **kw): + """T033: Create an impact FX.""" + try: + from .mcp_server.engines.arrangement_engine import FXCreator + fx_creator = FXCreator() + clip = fx_creator.create_impact( + track_index=int(track_index), + position=float(position), + intensity=float(intensity), + impact_type=str(impact_type) + ) + return { + "success": True, + "clip_name": clip.name, + "track_index": clip.track_index, + "start_time": clip.start_time, + "duration": clip.duration, + "impact_type": impact_type, + } + except Exception as e: + self.log_message("Error creating impact: " + str(e)) + return {"success": False, "error": str(e)} + + def _cmd_create_silence(self, track_index, start_bar, duration=1, **kw): + """T034: Create silence/break effect.""" + try: + from .mcp_server.engines.arrangement_engine import FXCreator + fx_creator = FXCreator() + clip = fx_creator.create_silence( + track_index=int(track_index), + start_bar=int(start_bar), + duration=int(duration) + ) + return { + "success": True, + "clip_name": clip.name, + "track_index": clip.track_index, + "start_time": clip.start_time, + "duration": clip.duration, + } + except Exception as e: + self.log_message("Error creating silence: " + str(e)) + return {"success": False, "error": str(e)} + + def _cmd_create_fx_section(self, section_type, start_bar, duration=8, track_indices=None, **kw): + """T035: Create complete FX section.""" + try: + from .mcp_server.engines.arrangement_engine import FXCreator + fx_creator = FXCreator() + section_type = str(section_type).lower() + start_bar = int(start_bar) + duration = int(duration) + created_clips = [] + if section_type in ["pre_drop", "build"]: + riser = fx_creator.create_riser(track_index=0, start_bar=start_bar, + duration=duration-1, intensity=0.8) + impact = fx_creator.create_impact(track_index=0, position=start_bar+duration-1, + intensity=1.0, impact_type="hit") + created_clips = [riser.name, impact.name] + elif section_type == "post_drop": + downlifter = fx_creator.create_downlifter(track_index=0, start_bar=start_bar, + duration=duration, intensity=0.7) + created_clips = [downlifter.name] + elif section_type == "transition": + silence = fx_creator.create_silence(track_index=0, start_bar=start_bar, duration=1) + impact = fx_creator.create_impact(track_index=0, position=start_bar+1, + intensity=1.0, impact_type="crash") + created_clips = [silence.name, impact.name] + return { + "success": True, + "section_type": section_type, + "start_bar": start_bar, + "duration": duration, + "created_clips": created_clips, + } + except Exception as e: + self.log_message("Error creating FX section: " + str(e)) + return {"success": False, "error": str(e)} + # ------------------------------------------------------------------ # MIXING HANDLERS (T016-T020) - Real mixing workflow # ------------------------------------------------------------------ diff --git a/__pycache__/__init__.cpython-314.pyc b/__pycache__/__init__.cpython-314.pyc index cf82ea34c4813f1976af126720e5b9c598faf118..f4c928746d3125ff2802ed7ebb17ebb0f216ecf8 100644 GIT binary patch delta 34946 zcmeFad3aPs);Qc%_jY%>J4+|&?45LHBMI3TAcQ4^EbJj(LRbuhkOT;1<95Olm$-}T zpsiL=XAFu0E+YuqxQv3LMn}gENla*P#9ds2;<(Mo@0_}wbb~nW`+J`6`M!U?exOqK z)^_UDIj2sYQ@6_XY4E)_h4`oX`{`Bi`{BD2jrE`J_kUL;*V#W2GYGSr)RRfKyXp~N`U8a zQX+&&(*4pn{x(@kg69cgx#_W-rq^@kpl`Hi~IXo>-+9~Do z*aRsLQYK0hAeiWcx;-qTbjya z)1^JqG#)FIrbAsbq(TUbq#0fCXQosHVKD$PlV>TBis89b+AEdt=Q61jo@YsqN@e_c zwloW#)1}!EW=M}obNJgiQnxgh$L31&AZ4C3AHw<4|8HCHEt>g(XK4#^>H;;~KAA!##@ZI+&uw(!^%={adD zk8PDYp@vTBG6*k|E{E`P=?Vz1ke-*WgpmLeyi$5WQes`w-=wSfyQ_eRuI90;A$ARq zT_ar!1+SH^gYY`(dI+zVZh-Ix=|%`|lwPb-c^4KlXZDGq)?YBy|Lx$TVCjE)Oz8zxQdF)Tn@Ett19eRBykKG~JA@`lqVd*aZ zY=_);^VnU|J?(c_soL+6{Nq(AM-EKX?Yx1AY~(&-3J4Wcs;g8hRT7z_YEwrsvXX|| z_if8%d)^oP*v&;mAEm9gO2{Khtj(uNTWw(JL1Y{=22(ZL_n4>&2~ZMMDv6F} zTu0cER2mvorA><*O;xGdbX7W5^c6L+eQ{J5Y*wkvs_Nj;bV;ZVVe5rZM(aWj=7-spWV9yf6o@m zKSIN@FO0MNFviwk>|Tgf%B2vN$uYD4>B_D|~)Rkdhc_fNe zeHaCGM)*liELS;-G2Lw$hVfk=+IM zu5GhV28DI&`-9@Q6_03C#_;=dyE}#~nSGYb{-~^hfUJ|DR%dKMf9MpaamuOi=%MiB zzVPHd;e+8h+vW@hn}>oE;h!@&@noo_%W2Iyxad&$ffa++nf;-~PGj*|s4{GOJL|lo z(-}W=D4_UQK=H8A#PoOQhm84s#{5Gez3~Iaa{lg4eRu9%0Z=45p{LZDI{m1&SKYhW zxpaB|j7#4&S8p#l85Yys-cvmkmNO8Rb22LC{*Io?-8DOF`YjU<34@ldDg9AX54FD= zRXm)KzNdZPio^4qm#lEstairN9W&RR(W;_XkP*EqBCcn`o+M{(y)&%AX>2$Z9;-aB za)#A9jkQ0091wn1MG$w<-5ot^AGhtxer%I7c;cY%#9v1QNchDz4MyRHnd;I6)yuv! z1K`h5Yf@=Og6dUY9Xz}ms>Lt{(_c+6l=%p+X8M;2!mHB=#9tHC5Z0;Lh)hkPB@td? zPs7C@Y16XcN5$*?e5wu54*ym8u!kQNEyTxu>g`Z=;!)90?Xyyq7RmNc5o6d$5AiWc z>a@|^@VClmB}t342gb&*(#OP?h>mT1TnyvFie)}7W(#_dEOn2Ili7w9RA+y~=6f8u^RLbvO|8;NzIi~m_)Aj$s7gsaNF%eVN>!0RguXFNP$2t5R)-V)DPERF%GMM#;Y|u*z5!=#7H5AQ0`fFA$TtN)Ks4qe8YVxGH$G zsrsF4*?uvdOtOD)Z=|WsRAm}VnarmGgMH`GVAi`|^c74}0IT&E!$<)8cE1=OYyym! zs)Ac!&QN|;{v1DH7s1bHR|I3Vn*HT%7&Dwu^nkd3z*xEaDFk{a=0oBc1*@fW!M*39 z%ybcyftdE7jJ=soeTjlA%Xg!=TJjI*l&W5tCj3+?=zy+bik)N!r|PTY$GYKx-#sw@ zUt)~?vkXY*k+;RrF_iUrp)AZBWfK8qXWb|x3vAWtV_nio5fT|AfY7SYQqr*cJcL>5 z1f6J6DfDG3C?#bxE{ZmPL>tU}VbTQP49L?K?lm-_RpD&o-6RZDHOPjPSp~FtK2>^w z1=&YOGFHWDbQI%ZRbgY4$j8f~S|HAw>E<#|+K1SQD3uooVNz5cjZ=C)Rz(IUW)Ihe zRZKxjht!?F)I%!lvNuZmyC}0j%MKLl5yZ>=fr)e_- zvy|X-p!qxvGP)|7-BC|W_6k28+dd+w#j5CvIri8C<{)S##%pMzB@@RtX5ehcg|DV9 zrb=5e*M4fc$zQU1iMmWKI1^(>Nn~s^K}Q5F)iat{Z}F32Itx!0gU40rs>~PVW}qYd zfqr_i=Kio3vjJZgFQNrrI`1j&qIzrv;4s(=#$YL)b4Da^M)g7k5{P-EPH=_&Oh7QI zwd`cIpr=*7Y~fbHoG&GK>9+Ghw@qxbR0g+20z*(7@hZz0ULaz|^oTKuI?h`>_*$Uv zrDVaaW64S0$!t}DpeD*#^3{MY0qgS~D_`NiW6oy|%w4{Gbi8FxvSb;PJywt&iB-Cm zlu;A_^Nu0GL;aO@G9|>n1@%t;tBkH#0wfhZ3P6mM;-M6fG}cP5Dl5+?NR8m8M^=3u z(HB&nH-PYT@c{(w+Is*iM+Z>N2hhIpsbG5kkQs6vpR*iV=@qQE3&SI63qd=zXkSL&r4FTKrwbd;prN`I(x#eOkG zk)v$k0Wo@#&%C87)#$p(3iKJRD%H-Hlywv=%f<)*mSwP_fMr?87z%^VL*bDFVh9OF z4JDL)eL%FbeMN%0IHWM7)CVyKq6p%iHJZCE&HU^CS8av=&uukeTiSVR{>)gpy&%@aM3Q;AsCu@kNqJS!u)ZgjqpZ=`N8Ks)A?sc zpU(pVI2zC&JBI!=FOU$z&6C#$cH4t@Z<%_ z)U|iW4SIc9ZBx@~SRq^M*44slJ{kVE%Jr~{2g^a5+_0uWZfL1%NGZ@~XIS}CI-{}0 z)*!dnc&+$X}qx5^vVG_`KlPxxI{fERk+*s|8TW)vq-tk%|Ul^blWa=X6#7j|tFVOh}7zOJ?2nqBZeVgECz1%AdEE@JIW z@vdmJ3hSc9#l=7#*4lO}7(p7*Kx6I99Lw4TjgIA&8-PAq8tSd(tt}1bmq;Ef;a#At zXwLl7lJjx`cC434mbU4U0ZME&|F4}|Ki}&DS zIL-9}Xbhe*`7U60#U3_ht^4fWE^fx#TUdF~M)NM-Xufx^irU*7n%mmFXl{Zvd5kAg z&Kp>;zsb#R)8QM1@&c8rOLftPCtSSYXzzyIBsam`+X8E+$vfE%m$ft4+91myzr3ke zz88_Orq;UJCL6n=Mhx$Y_p+Mu zdiP^y-XJ%fDtLghE_GY2+-{Q@R^f+&uxV36JtuGA?52iV5D_(FNOt**MqPfZf$MEG zfWVs7weqMGaOYhHlE)^$gZ1kHRWO@iZkK^uWt$pW*0!&6`82fD^Vi%!>$cdo)HXM8 zTdf?80Qrng3ob1m_g0y`><}|%B2~D2ZOT-@Wsb|A*A3vx_zhIEkO#Pn|csc|XYhT-`1eTKpKDcwG&ED1xF zseP8IhgS5?buL}iZ>jAT-;c6<+?AZVr{u}Gd*<$&`B=bE^0dC>Y5mEC-E-czB%h2Q z=S<4)kDq*~Xdr&taMt8Q#ZLzujX&JbTl;F`D;a}X6+LrCs1Tb1Nj)XI=74EBI%CM3 z*JsW9E;4WKQcdr#aJ?4qUp@S+lnP(shIB>)tgtp5jSeJZubohe)cKyHI;S2iPT9mp;3?Q~vR z*PmOz$LIaj+~aB4X9QJR-Wfkt+C1`OsLGl=B8ssoCzCSvY&jG@lr-~L(#)fqd$+vP z^+uO-)rO&2O~+<64VPT9$LGm_y#WKsMQ8P@^sIfNL%&adh(5M(D6Ob3t*Ae(xJUPX zeA>yR@y^t#{YldflYyk7;jTP@=jnw<>v|KN(xSIhUTGQ3tK6dlx=KtR&M(^I^SB?- zRcy|XHNVfA|3b*2Ezes9taFB~2}9PbJ}VG^^#C{z>NfP(G!14q4OyGNO9Y6|#H-R~ zld}~>m5}aCpFR{{ct^l?^>A?1KycP^llfGnWxICR62ILST^ZKIo=YCsvVGPFT}jxl z&x&zf!%+!CQR(o{8I?Y4P8>34_nET?%((zca$2|V$*8!V$RRXO_5IZw28%cJ7dAOtZSNM^hO@gS^!N{F=Jxm=wS=y3c>Ouy~*EaKZF_+TpCcp{yBwSu>nPO#`j6 z({@>Z>*a$*mk(rJaXf3nnE+MxMluqr3Xh0ZDCmKJGtCsp`Nx@p$`p0yB(~&v(WXDs zD5w%}fziK?OeL`?u7u=Yffvn*kcKib+^l#8 zohge3s+KvIukNp^8%(Klu30~rvVNes&ACzTZ?+Al*oMN}`@`GOj|Rnl9U1rE>+1Ty zsw|BpW}isT`gO$LUF%2?NlbSor~QhYm;#`J81o{sB?HS>I9IOeU%qxQeXVmnP7nhd z+npVo`Zpq34Vkxe^_#aKtWfUPkt>P2wh{ekWUT%eAStLHXwXZ1R17St0(R+NR5O@e zGh|(L%(@CIgG{5i(}pB_p{@{Sz_sofFr~t|Xx(5}%DRCKEzZ`>{TsFnrfhLu)-{;Y z1s;xKT1H1ys#$b4{T`p@&>vK)@pC97Ma-omRE&rnwv2y#&135ZEE5k+9-6WM{yC>C z7`CPiSts;aCk$98{X9ZRMC@_1^%nqPlqT*A_;n-zp!)S}0%9x-P!{VlTM-4Zzn%?M z86(cBL|qUY$q>T3PWYOKeT_rD=00C@_p+hr>|@c{{n5DtzInsGfxnLEAmcB#BcP(( zToSoar#hM#gkioF!dD}T!r{+rIgx88(bs(q5PvyM2-Oksqu^u=rx2*(qp1|*(}N)Xu~83Ie{A)` zFvGmDOQ-t8kOdE)OpR`vL_duviiU^JCK=Xg)t^%l;-6~>#K>fL|1~B(| zkfAYF{dshLqgj1AL<^~>&1!gaIu>)DPN0n`>eJ&ifU(nQhV@g_rzhpFpQ!#K6LWqs zQ4Mdtm?B{NUreVPMD3RJj}1UUe2MgnMCux=zU4CBez z{z#@83XJ4o`y-PK8#U@P6ys;q1mk=J&*%)YML1(B(#Vm*cads%r~_;B*w06$I`G2X zX;gqElKo4zOwCtB_W9i@nrA>~mmT)Yx@UzP$LQGd#id?@i*Wm3_a=ImaA3iX%LTQ( z2eR1Ty8rfqFCpSm+uFA_HOOCKIW@k}!5XcD8^)A+KE{+UFhy$vYZk0p~GVF>A<&I|9_*1t*9)@QZe}+X{y-hxcjcd5E&&II`8)9nfWtV;LV`Uy> zn!Dr^SS5#zuT^;;{)6wZ26++&zu_Zan_A&9#pt!D?m+e}Sn!`%@O=zULEsV< z$S|trkhwJW?T>G!F5!Ugi5Gmxp#8O{$NTf8v3sG{P;d8tCPl+>`s0CV&uk<*H^u?~ zu&s#vWPjU{t011Qs4rMA^MY=~Cmc$g#v$da=3fv#?;(Ik4)Y33c$LGr2FDF-AZ=~( z%kaY9edt>HZ{a}nv!80B_)3}6fy}Gg4H@KNEc>`U;cyqZ+rI1Y0&N(`X*ry-o`*@O z-T%ndbf$RVjw4^H$&dCcUSE~Tk^ME6%)^q`W56+vrb0Ou3&&%CrUm&&!fJ;}xILkF za*+HY0w~~$Tf`-`{IY#x?>f3tJaD4-9MxK|kd@j$`1_68D}ljm6)O9w-h~HVd}|T~ z$o}<@7J7qtV9h%l2$^U<=A2Kv#RJy9H9D%L_HC|N)Q8&pTv61I+P`rNUu@+?0>4R({}I}*lowzd}<~$SQgNBq8t(;~5*O@lDpV)8P6>h)kyL2k44?OwZ-Gq(@ zsLuXMSE=pAKhzKnBdOGs^=~M26>Kb6NpM5vY}k{8ZsS-LA`gGC?NYr41OWJ3{oB-4 zK6a92Vpn}f4EBF))3GZ~z=q1x!_>gOx=z&DH!U+Id-=rFV?Hrq5_FeWr;|iUEorKB zc5>7tN?M3){2N4k+}krn*psBQpSjXRCB1#;yijzuYrzBtzP&K}j(OwaGBxqAdlW

<2!t=MvZ01o=&=?m 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 T{+|WDe*V6EiX1sco%;U(YXe9R diff --git a/docs/skill_produccion_audio.md b/docs/skill_produccion_audio.md index aabe33a..3f275d1 100644 --- a/docs/skill_produccion_audio.md +++ b/docs/skill_produccion_audio.md @@ -67,7 +67,64 @@ ableton-live-mcp_create_arrangement_audio_pattern( ) ``` -### Paso 5: Verificación Visual +### Paso 5: FX y Transiciones Profesionales (T031-T035) + +#### Crear Riser/Buildup (T031) +```python +# Riser de 8 compases antes del drop +ableton-live-mcp_create_riser( + track_index=7, + start_bar=24, # Empezar en compás 24 + duration=8, # 8 compases de duración + intensity=0.8, # Intensidad 80% + pitch_min=36, # C2 + pitch_max=84 # C6 +) +``` + +#### Crear Downlifter (T032) +```python +# Downlifter post-drop +ableton-live-mcp_create_downlifter( + track_index=7, + start_bar=32, # Después del drop + duration=4, + intensity=0.7 +) +``` + +#### Crear Impact FX (T033) +```python +# Impact en el drop +ableton-live-mcp_create_impact( + track_index=7, + position=32, # Compás 32 + intensity=1.0, + impact_type="hit" # Options: "hit", "crash", "sub_drop", "noise" +) +``` + +#### Crear Sección FX Completa (T035) +```python +# Sección completa con riser + impact +ableton-live-mcp_create_fx_section( + section_type="pre_drop", # "pre_drop", "post_drop", "transition", "build" + start_bar=24, + duration=8 +) +``` + +#### Silence/Break Effect (T034) +```python +# Break de 1 compás para tensión +ableton-live-mcp_create_silence( + track_index=0, + start_bar=31, + duration=1 +) +``` + +### Paso 6: Verificación Visual ```python # Confirmar clips en Arrangement View ableton-live-mcp_get_arrangement_status diff --git a/mcp_server/__pycache__/server.cpython-314.pyc b/mcp_server/__pycache__/server.cpython-314.pyc index b32a7528b1015f31b875fc2510782bd6fc60843e..b0f3758a2b6c7dde8304148bcd712a06a7b3b0a2 100644 GIT binary patch delta 8087 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 delta 4045 zcmai0eO#2q7T$Aa*~RzWWkH1n76d^ETtzayC@YrSG%ZCmQ_B3dn~MkJO*0S^i9~cD2;Zy7!uz-Z`^KNq@9|JnznV&Uxm{%$f7P z6(>V>R)vIkL!5?1{dU!Tl^=ArEF==wCswB%vcfz3y0s&`yD>eeEx_`PLv0HIR`8$g z`LL1?4bFg-8!LiG0j%QJo8-f4KH8{+mE~pztl^y$uH_Rnu2Q&;e`7ul@9|7WKCI{O zIx=7b|62X8;ys-CP|d5H8Sp+o@2rH4d}hdP*u-bLGGH^`>dJ>2o*Y^UlJ5-7fDia} zgN>Qf3=n-;=WKDwC?KH^IiZsT7o{Fp~J_rZ2PK;aI) zK;cflPhlMo4)>|t9#r@VpP}$mzE$Bael5IEEvO*Er<7MHT+Yu#6vA#k!0m(2_yTt! z?BN*cGc(@3frgnhc*95fafvM zULDn2Tl+MM;yRZc&GjXY&x`iLeqI~x3-7P3kCL?^mkOQBe%{{WGY4vZkd7+xj4+?j zf7D?d~o@ADj1p)YEu(ne0}`8Vz)=S+pA9H zU&8p339;hV57=3B^I{)ZCgyuFvdO(fzO7Vv%fXYNlSpoZpF}TH<04Q>$^L1iH{uRt z2y0t>54y_t+u|;OELq$R-GI40ntHkVL1Ve6NRD89W@B?S_Y+01!;q{yMk_nR^@x?d@o4*F6x6T>tLtlotVOD3)C2+TF|?5c*9@_~4=%tj0{KC(IP@5X zi{c!-(E4sI|CfzL@=1iiF6Q*bHQ*K*xmcr$?Q*VKa)hw=!)*{NclES+reQmSl}TzCfhE;2LR5g#Kh1gn1@$Q`N0zG0B}KET8e%XtZFp`Lrqz*4Ci--PNMB=s9MJuBHJrj(JupYM0yT7Mc;=Nbi9hKalAvSKBbz&IEVQAPq-3G95V4| z?9cEfTiB0z#7iy~Zr-HxCYa`s@Ba_yfFp>KEv7_HF}|aJ3w*;N3x2_k2-bzUEY@iY zv^edyN9^c=iKdl82o^cy;#dbM+CbBtz`!{ zi$vQrvX_YdQ7q-o{~1xtZOkA$L8@F9#gYJga(6VVM)O4?N(p9)(pc6i^>+qk4XjA@ zsyp3e7P%5+%7d}APkB!1iep(ect!L{V)v=X3rQ^6e2x4F207)5B*p+|TlKNecFMiU ztT+hfitcS#TKrt)^M_gHQ#8RVPQlx-O(>nRS6lWZ{GqhV$&;YQDYmDv1-Qd0`?q6V zfL?^@EY4P;xb04{DV^QGLrz(JFT3S}MWU)3yKGylxPwmlZZ-?D!eX(e2fGg^hsaYs zSgbwtEmFQob@MD8&tl=oVgFKIS8`aksY!xKAu_8kdlj)RMDFRwh6F`dQrw#ay(#W< zQmCb&TfA^qy-@N7vF1=Co*l$IAjRxK>bPq~%RE(?I*4Frh|JAn9|7JBk*+7yB5ZZa zdLu-37|w!Gy_vE`veByVygia-Lbg0Pk_mfW9nJPBO|*+(H^FBFd-RalHk6BgV}SY! zNDU5LxjzXM`wCbbbX$3`Kpo-&m%RK8^9JF3m-G~}vw$DEBowi+RyZKWO<@DE)+KjM zVMo^qHl0gj5PB`h)Q7^QQZ;7fuNRS`So7fVzvol(Sj zmuxqkeGU*QZ_i*p#B)|LZWfCPW`V5FiQ%OzE$F;*bxU5#TmWhEotaF1QGF{q&thrz zf0O)09hGRmNQ2!_F`Pw+^|P2K=&~}j6$fUqDR{vu4*rOv#oCuyXXq)gUeV6s_|E4tWO;He+h_8QpcwxuLnj3 z9U=Ics3>Rmkn_joEF$$c)rm@afRf!oQ`~JYcpNHppbIbZ<9hQB|m{~^}1D4`_!FMw>;g@bnnuQN_QXKIdogl zw_9IaKiyD2T}8jXRr(fCz5Aafd8!5fc`JR+(vhiM7Y_;MHQhlLi`oH8QBj1PCfKM@ Paby*Xk(I01jiCPnGE6 str: + """Create a riser/buildup effect (T031). + + Generates a pre-drop riser with ascending pitch and tension. + Perfect for build-ups before choruses or drops. + + Args: + track_index: Index of the target track + start_bar: Start bar for the riser + duration: Duration in bars (default 8) + intensity: Intensity 0.0-1.0 (default 0.8) + pitch_min: Minimum MIDI pitch (default 36 = C2) + pitch_max: Maximum MIDI pitch (default 84 = C6) + + Returns: + JSON with riser creation status and clip info. + """ + return _proxy_ableton_command( + "create_riser", + { + "track_index": track_index, + "start_bar": start_bar, + "duration": duration, + "intensity": intensity, + "pitch_range": [pitch_min, pitch_max], + }, + timeout=30.0, + defaults={ + "track_index": track_index, + "start_bar": start_bar, + "duration": duration, + "intensity": intensity, + }, + ) + + +@mcp.tool() +def create_downlifter(ctx: Context, track_index: int, start_bar: int, + duration: int = 4, intensity: float = 0.7, + pitch_start: int = 72, pitch_end: int = 36) -> str: + """Create a downlifter effect (T032). + + Generates a post-drop downlifter with descending pitch. + Perfect for energy release after drops or impacts. + + Args: + track_index: Index of the target track + start_bar: Start bar for the downlifter + duration: Duration in bars (default 4) + intensity: Intensity 0.0-1.0 (default 0.7) + pitch_start: Starting MIDI pitch (default 72 = C5) + pitch_end: Ending MIDI pitch (default 36 = C2) + + Returns: + JSON with downlifter creation status and clip info. + """ + return _proxy_ableton_command( + "create_downlifter", + { + "track_index": track_index, + "start_bar": start_bar, + "duration": duration, + "intensity": intensity, + "pitch_range": [pitch_start, pitch_end], + }, + timeout=30.0, + defaults={ + "track_index": track_index, + "start_bar": start_bar, + "duration": duration, + "intensity": intensity, + }, + ) + + +@mcp.tool() +def create_impact(ctx: Context, track_index: int, position: float, + intensity: float = 1.0, impact_type: str = "hit") -> str: + """Create an impact FX (T033). + + Generates impact effects (hit, crash, sub drop, noise). + Perfect for emphasizing drops, transitions, or beats. + + Args: + track_index: Index of the target track + position: Position in bars (int) or beats (float) + intensity: Intensity 0.0-1.0 (default 1.0) + impact_type: Type of impact - "hit", "crash", "sub_drop", "noise" + + Returns: + JSON with impact creation status and clip info. + """ + return _proxy_ableton_command( + "create_impact", + { + "track_index": track_index, + "position": position, + "intensity": intensity, + "impact_type": impact_type, + }, + timeout=30.0, + defaults={ + "track_index": track_index, + "position": position, + "intensity": intensity, + "impact_type": impact_type, + }, + ) + + +@mcp.tool() +def create_silence(ctx: Context, track_index: int, start_bar: int, + duration: int = 1) -> str: + """Create silence/break effect (T034). + + Generates a moment of silence for dramatic effect. + Perfect for creating tension before drops. + + Args: + track_index: Index of the target track (for context) + start_bar: Start bar for the silence + duration: Duration in bars (default 1) + + Returns: + JSON with silence creation status. + """ + return _proxy_ableton_command( + "create_silence", + { + "track_index": track_index, + "start_bar": start_bar, + "duration": duration, + }, + timeout=30.0, + defaults={ + "track_index": track_index, + "start_bar": start_bar, + "duration": duration, + }, + ) + + +@mcp.tool() +def create_fx_section(ctx: Context, section_type: str, start_bar: int, + duration: int = 8, track_indices: list = None) -> str: + """Create complete FX section (T035). + + Generates a complete FX section with risers, impacts, and transitions. + + Args: + section_type: Type - "pre_drop", "post_drop", "transition", "build" + start_bar: Start bar for the section + duration: Duration in bars (default 8) + track_indices: List of track indices to apply FX (optional) + + Returns: + JSON with FX section creation status. + """ + return _proxy_ableton_command( + "create_fx_section", + { + "section_type": section_type, + "start_bar": start_bar, + "duration": duration, + "track_indices": track_indices or [], + }, + timeout=30.0, + defaults={ + "section_type": section_type, + "start_bar": start_bar, + "duration": duration, + }, + ) + + # ================================================================== # FASE 3: INTELIGENCIA MUSICAL (T041-T060) # ==================================================================