From dd157ce29de0d6d560910a92f05d6c7af31b9db8 Mon Sep 17 00:00:00 2001 From: David Huss <dh@atoav.com> Date: Fri, 2 Feb 2024 17:44:41 +0100 Subject: [PATCH] Add Performance Effects This adds three buttons in the Play Menu that can be performed live with: - Restart: Retriggers the loop, essentially jumps back to the start - Slow Down: A vinyl-style slow down as long as the button is held - Reverse: Reverse the playhead as long as the button is held --- code/daisy-looper/button_grid.h | 12 ++++---- code/daisy-looper/looper.h | 49 ++++++++++++++++++++++++++++++-- code/daisy-looper/menu.ods | Bin 20176 -> 20193 bytes code/daisy-looper/ui.h | 29 ++++++++++++++++--- 4 files changed, 78 insertions(+), 12 deletions(-) diff --git a/code/daisy-looper/button_grid.h b/code/daisy-looper/button_grid.h index 78d78ff..96395e3 100644 --- a/code/daisy-looper/button_grid.h +++ b/code/daisy-looper/button_grid.h @@ -94,12 +94,12 @@ class ButtonGrid { for (int n=0; n<6; n++) { if (!grid_buttons_[n].is_home) { // Not a home button, display help on long hold and hide on release - grid_buttons_[n].button->onLongHold([this, n](){ - grid_buttons_[n].should_render_description = true; - }); - grid_buttons_[n].button->onReleased([this, n](){ - grid_buttons_[n].should_render_description = false; - }); + // grid_buttons_[n].button->onLongHold([this, n](){ + // grid_buttons_[n].should_render_description = true; + // }); + // grid_buttons_[n].button->onReleased([this, n](){ + // grid_buttons_[n].should_render_description = false; + // }); } } } diff --git a/code/daisy-looper/looper.h b/code/daisy-looper/looper.h index a9a0575..594ae1a 100644 --- a/code/daisy-looper/looper.h +++ b/code/daisy-looper/looper.h @@ -45,13 +45,18 @@ class Head { void deactivate(); bool isActive(); void setPosition(float value); + void reset(); void setIncrement(float value); void incrementBy(float value); + void slowDown(); + void reverse(); + void speedUp(); void update(); float read(); float increment = 1.0f; float variation = 0.0f; float variation_amount = 0.0f; + float speed_multiplier = 1.0f; private: bool active = true; float position = 0.0f; @@ -69,8 +74,11 @@ void Head::deactivate() { bool Head::isActive() { return active; } +void Head::reset() { + this->position = 0.0f; +} void Head::setPosition(float value) { - this->position = value; + this->position = value * speed_multiplier; } void Head::setIncrement(float value) { this->increment = value; @@ -78,8 +86,17 @@ void Head::setIncrement(float value) { void Head::incrementBy(float value) { this->position += value; } +void Head::slowDown() { + this->speed_multiplier = max(0.0f, this->speed_multiplier - 0.0025f); +} +void Head::reverse() { + this->speed_multiplier = -abs(this->speed_multiplier ); +} +void Head::speedUp() { + this->speed_multiplier = 1.0f; +} void Head::update() { - this->position += (this->increment + (variation * variation_amount)); + this->position += (this->increment + (variation * variation_amount)) * speed_multiplier; } float Head::read() { return this->position; @@ -118,6 +135,10 @@ class Looper { void setRecModeLoopShot(); void setPlaybackSpeed(float increment); void addToPlayhead(float value); + void slowDown(); + void reverse(); + void restart(); + void speedUp(); float loop_start_f = 0.0f; float loop_length_f = 1.0f; uint8_t grain_count = 8; @@ -402,6 +423,30 @@ void Looper::addToPlayhead(float value) { } } +void Looper::slowDown() { + for (size_t i=0; i<9; i++) { + playheads[i].slowDown(); + } +} + +void Looper::reverse() { + for (size_t i=0; i<9; i++) { + playheads[i].reverse(); + } +} + +void Looper::restart() { + for (size_t i=0; i<9; i++) { + playheads[i].reset(); + } +} + +void Looper::speedUp() { + for (size_t i=0; i<9; i++) { + playheads[i].speedUp(); + } +} + float* Looper::getBuffer() { return buffer; } diff --git a/code/daisy-looper/menu.ods b/code/daisy-looper/menu.ods index b744707a290dc99f6530d3f577376ab5774bb22e..2b8391b9cf03447b0e7b7cf66da2c734faf8ed40 100644 GIT binary patch delta 4607 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 Z1_n_S13!68{_7z=d6%C6TbdV01_1l|jeGzA delta 4582 zcmaDjm+`_}MxFp~W)=|!1`Y;>cWx7Tf|%a9O-wKWlS-2nyt%lLWD}Goz7t}4=QjBn zqtfIx-aL~H7&$=PHH=D=V;IFiOpuJ74-b;A$!i!bATnkkN{-2z>7Co=XeL`m5O)@{ zO#SJ++Xe!AzH76Xg-^V4dK!mkW3@&V$Av|OjrVwFMrr3{UQ%6o<L7U$DNj^<`B*D1 z@THfPPh0)zThWw*$`aaJRt2<Zayb;<<+>XB;`q1X8H;cKa$d>Lez0-ttncmtdNxhj zO^&N{Ui;iW#bs+zp42kue0q)F1~b`CO<xc9TgOc6A1-eA>~5m%R@hp#ct+lu4L+vs z8_pCi^ItGc=*`U2HPOL$K4q^A&R?Q`rHDz$ZKA4R--$zeJr>sOzaAMP!uoMLcW8F4 zYG15Row&5-%tzX{-T!AN&YNp)SifJQqUlxYuEp1Ped*iTc#OBFV20ck!`{gTT~1Ls zk7u}AE*6XnjH*w`oOo2V(min79Lt9)S7vWfxt`#~x3=K$@3!3hJxl&=JG(#S=-)Xn z&wkAot$!qxGxz`Dc@H~pH#Rx0@vT+=#<s7jKBZT9&#{kZ=LY;u{carpHZ1c)(*|qF zzuY^NIrsj&!hN%?d*}0-#T!%AGCdwY%*i~sspqI=-(ro}<0VroPuE{o*z<4K_G`S; z)(G2t*pdBB$Z1{mQ!SCjoKF;<Hm%(xdFA)U&8*8h&dijR@h{R4`B9qm?xo3_R#9e) zyzb*t?|wA~Dz4pkc)r}4=)6CRLoz1o9cXTJZZ%N*{4h$^#r=uJ;!IBuuPW{~ozjzP zM{nKSdHUM*%H4V*;+3=3UXPsEqc(SPIJf(~-#cIL5AbH^a8%RN;9z24kYZtAfTT?h z4i1KQZkuni=CFa1j608fePr<?3xT@(@eh+$eLFit`KIp;m0%waqc;UhEYi~EZ)?$Y zFx~WY(vgXOziR(H#5Q{di;%Mozfa_=yxOd<sisd}eZF+$luS@tM`^5vxHl_nl$GHG z)17)e?B8FxKKy((KRm_8&1#LL%lw%a9<B1z(fb$9vi)e5S*wo?<2#O-fvfA?7@XIn zF$!;zx}JTcZQA+h+fP<nzTWlNDmk<+c1BU&b(7qU5hCJOl@<!;Uby^Z&Z&o!vhBXM zNU`-TUN^-nG<T6?19NHLgGZCkZ=6$PJZ*7JW#vlC&2}$m1Qfq~>z;Gqa^r5z9a|J# zi|iS$a|rTi86MLT%3642-CCBG@7q!|80)hmf8Wge`c>1Ual%214J9v%1FM(zi}KC? z9JBa>+LYf{+T;Xo8+XYXIbT<36VkbS>S)md+gdIS|LO$3!V2>oJI~YF9<3*5Y_oVP z*p{fs#@f9lNM-GY(+0au+P1uzWOl}z<KlLWZ$6h9uQi|jq|OtZA1<_Bck7K^SDKU( zE$nvIb6R@rp0=d-hJ@R-^(nunZPxznxBJAT#8MxjzJQ#(*Z1x`Z@5+IwR^+!V!`H> zQZIRzWx1?j?YShs$XVvuwzOv)m#$=YpV*wq{`iZuc+J!Ufvu|RbmsasIoPNfpDsww z@QIm}v$dmzH#f(AkM~(cF6-A}ZAG4wP3&yd^cmjDR@QqsJ^9f&Q^F}#psiT)DHFH5 zfb>fxi$LFPa{E-vP3ol2AAf(KlX1S<kB6<-#3r9}-z|F1EOTwL?M8#SO4g+cB`cMs zCo@GJx~DbEIyS)OZ|kYntcS<e^Tw?7;buFw$SvTwL;EVm(ldGMV#+z%M88KW?bX{d z;e+mRwJCNRjzlTdr~X)?cF6yF>-|RG8}ZpC?-Cq4JEnbk#S-<X!nGlt`$$B~A-5QD zcVl)D%WG?M+pj6kvFO&^USA*lYkTL7Yn+!Gs*_}9{dT<GP@K@%`M|rez;%!Ll&DKP zs~;yE>nz|}vbt~10fjl|Ps}R`;uHJ)!Me~xMZv~+ZPR&4xscq4JL)GCvCK45+bY=l zV7gV)p`uoYom=!TD#t50|4LsPWV7GEm%X0D&&X_6OYfwkQU-=XZcqJA9@KQ1yt3f> zr^t^%Yxc^%?{S=ZLuMw!>cnS;2YB8!?cQX5C;jN>Q{9EdR<}9JOr<xJhnTZ}OnbyX zYmr4m$ku}_tMuHN`wsGa-s;<0Z}vn?g)Pa9&3~SpZRVyLk*OQAgq%GNg*;vSC7^W1 zlU#x1`eSS%`@UQ9M>BdaJDWUV>vk@KSrJ;w##-D545NM>Ix5Y>a?pF}`s_+SZmyi? z7Ad<X^1pj2n03NyO~{|mXP$8>OGuttKI!xM>6X)9cdt4g`*l}>(#K^IUCWZ36O`&% z{H`+{=UREC=V{2(q#G<HO**27Hy#MTrJC@<;9%3{mG{gq$8l7Kv`w~`_~oCoC}v}& z%G(o(p&}Lsyk<>#uOXqg_ob}g%Qp?nRdU5%>{km3+h>$0n7B8a?f1giCpP61!!zDL znz3cN>|-C{M!jt;3vTRG_!sj=tnSp(KLY$OmFu4_)+*Yxd|%7<cK&ty)`%KDb-p&M zQuOnjZ~T$Y^ET9Np4!pBN{m-_k*m%O*X2JRdwi{A@hjYUR5R&0)AAiX#ay}{mtC7J zA^146^kIH52aj3ng!?f&rw4C3ZF2bB*FC2crk4l(+k4gPnMCKC#)BM5Vlr*s%J1)K z%;De+Y4!feThDkiy<>5dLe7f@shraJFZ`_L%Pq|IsO8-7#<<<r=iWuvAA43mkqCP3 zc5CvhEsVB7%XVF3?S1WZb-6*z<<eeLCD*Wpfh#`s8K&7*p5DXe%hApJY>&l{Ude{^ zfT#Z3W+cqvdMhrn|D(9Ey4VEcZ@%x}g=O9^Z3~}eUa)kn{@=3t1i9$1^_!ZX{d@j7 zV$0UgXPz*oJI(HWINj&L52HQ%_rKnI_+%cZ+^vVaD?bGtJ-RsEY{MFlC!aZ3E?vm^ z>DuU~u5{eV*?0Y+Q_(9nR7D-!b~iV>`Q2gX*LnN}=i=mlS1Zc=i`Z^|L*fme`Ejee zY4yL&Hp#De-@f+Rv13tp-#tE7pYT7sd;+KNtCH%sztmnFfA-*8c5-sXjY^TnGa2s5 zU#XrQrZQDFxnPslO+M@MqQB3I?!M9}=_|H=`^6Qn_uq(&o4<8a=+yriWm0$L-Q`|O z?@fFjt#;+-h1KTPGaW9yy<<E3#wUl}_Z?<G6a9YVa89koi@YU&%Jv%fXy&xd{Z_D{ zzQ1VamO9ar6F=rotnMi<+`<3uex|;)-`(TJ6CZ3U{J-_DnZfV$n<rYtzE5O{lfTJd zJ6%#Z)oEY-zio-zH_7_#EGa9DTf4_}*<M|7xyp5mzve%EQ5ALdisGX`dnZ3@xWUy{ z+%Z+(_+01G83(o<Wnw?Iz%#01W8k|buXLt(R*D<fzfXD=d&VdA-=9{k_epZD8_q_E z8`n&Kb^r18-^{K*vhSU++2xjYZ{wNIPP_ILFv*^_|CX@W&`$34kGF~07w*X9n$4;% z*cSY{;#xlY+4r;K`(E<jmQLQA_FU1pu3n>d#mt)z-8*tByFV<GTbF*%P~gkEefPh9 z`}nWY$oA;<x}(p+_s#BXK6`Gu!KWLuwx@somUD03+1r~dtINzSR^HmYbaK}DQ>i^4 z){8pVbLxNM_N>3~mv`y^E&s%)=Ko^{)$s@9?tfgz&cHA!619$>Y%QW&Kf_GZ$LYAh zJ|TsK+4}q6oY=--y6K5m5zn7rQ+ZROnu4<mmhTphV~Do;{_5AA)sM69*F;wRcqD1m zr?K;_sGY`6ZV#DPN=Ez7@}52R^!c6Xr{c{^%$)gjc3<JN@i?N|?sP)&kCUJJo;LwT z&P7fKJZ3WWRm^1I|Fo&#)Rp!W^R@MV{=O*6$th0h6s+8JR=4HD>7O+cZSsd6v7dVO z(`jYMspIM8&YDa0nU&x4rhiNb4YYe^{y*OB`2W7roZY8xY<&Cvy;Ja+(6YiCy8DYZ z$DV%nT8Q(7>&Bfo<obH<K3j77X*$c{=_{V{o&8;Sj-xOod4(Z|&#UKU>PJsaR~HoA z*;QXOxt{lv_W@Z8;hPHm6Sc+K7pz~mzFU3qc7<8`d{yhbD!xYi@#g<Ay<<lK=iS<9 z1Dl$Ok1Qt{<dpUtH^|vtomX^Fg}G>I2Y+k)CljW-pD(i*DcKi)Ij(t($tlpHsbOnF z;i+F!lofy4TZ+65+NJ$d`O_DHBCo!TK8N!cJ{StsTPYOpkpIn^D(HEs@x6>)@wGPz zUse3(cU0edwb6NPkm8DRw}kGX^HVh1^>1=6P;O|hy>jE?p{o~vZWm`ZXb;TW-&r^H zQfji}VKwL9sfU+|I6D-H9%PzfWZ9wI%o!`JcXaWcYiTpuWG&dwX`Q^rlQ1vg&4Gj4 zy&vEH`a=GzjcC1Q>V^Il9-2Ep#ZA1YeW}{@7qeE-rI!(*va^qGyyqoQvfF8zo`~+L z3$uh6H#{`x+Q=KRs7+7Aet+<<6fbwSRiDxxtvsKgax6IDorJMiipjV6^X==E{>X_& zI;KzlBAC^ibc*ki>t3x@ua>Vij=9FubcrdZO0L3Xc_KHH_@<nm`XftSuFc}PaQly; zfP`Si8k^Zkc?bT={?l<wI<|dD-GPa16TWWrTXbor$8zCGYtHgA)l7cXz`etNRk6ek zhSR3GQUWt0FDOob;x%O(>sPDPt+(6l*W~-Rm^0mWJ>Q|et6uFxao1<F`v<bUkMvFz zQSK4i;+OWaKKf;jb!<C(fkt2b`_w!>79N+JUsIPYYkRuucaVN(b=Gx;LWOe**Y@>? zJM-O?6;NRQ;c!9ffL}wShYs7zhuPc*8k9XF7tcGd&~H&+b~5aH&WkJ=My0E2pIn`_ z&hwbfzTvZlk7xQ#=_=vhEw5yn%T=z|J8zKl^to%iPIc$Wy9>^^t>Zq){nRhNvc8;Q zCi{cZ*~!)YES{&9EO1P*XDrQFQnQF*#+ioNznfjp{;#PMJtz3mLwBmwLccra&*w+I ztWUFd*8R8t!m0Ax$D7;EOz1iCnmI*f-I2cy7D^r4ulVr%6}$U?_m_}oi{h6(y?mkk zso4Fcd550O{-hY%&J;df(lK@I`2(LL;vBC{uCEt*mAblkrC3*&NFI-4-K42@9~83< zUU}NF{*JwCyzZHT&4UlGl0^j-%G*wDuYCP}&!!h;XTELPeXV72Us!@oRCfJ~^Z*Io zw(R}6*QSJCf73SCliynInBR}A7ZI0t-6|@tS+{j-o9UGO^WHQrlZ@khdA7~SbW3V) z$kSQ&n%9=p#~Qs__@Zv@`rTU(-I{gh_q8Rz6U3ixx3Qo5V&B?29p2eXr{3Nb-*ECl z;;LzfG~#ME%l&<}?Z}ohP3E%t*RLHAzkJem;tlTAFU999(o>qVZ{^24T^{T5TWNkD z|DBu_B3iI~P1P)Ut5-t1?{%Cm<o65yzUG++>tngPje`B#|E#pqsV_CHH(2w!e4EtI z{Q-|mdH)<NdGlyt*Lt1H@1ulmqh_b|*tfoOF@KxpS@}hZb^FiA%d2v87fh)-T$OAQ z_~qh;eK|eSOXsb8(OVU<cK2kh={szruYP<SUY}B}w4poi!#&}O_nbBSc@60qdQ9il z7*Y$0r4II+trxMKB(=<j`&~-?^*v{IJf4&K+3a)LpDvCKCXZ~x+BYAb^w3K7n_H*L z?=_rH?|zvn#qXIfnwwXg{c&OLWc9`2JxjJ!IWNyC__yFYe_x^bOU4J8{p!NeWk199 zRh~_bySnBNH>luWuhX^p4l4u08%<cj4;grHiqOd4lu@F`z)-R|UTUr$Xo%pSM+ta{ zpu`I_95MNWm(1j2UK*et;0G@k2qiN)$QvxOz(;2C3~w!v=n-!Z5Csy^@&Sv4`9MY7 zKoT!}yg`(yuLbWrH>U`AcXM);uVy$%WbeF?sb*{p3=b3-7`Paa!5LNthT@XSoYZ2y zirkz4Z$>5&1`!5G_tYr@xl-ds*2Z8p`IoPh4ajU{|MQ@zQ50cdC{8UY$;?YfF&z>< xlLP!@7|kc=`l%~`jOpn7``?g}fkB6bfk70-n1>#d`8>rZpY{`A3-toY001P9br1jm diff --git a/code/daisy-looper/ui.h b/code/daisy-looper/ui.h index 19c4720..3dcb82e 100644 --- a/code/daisy-looper/ui.h +++ b/code/daisy-looper/ui.h @@ -114,9 +114,9 @@ class Ui { GridButton("STOP\nLOOP\nMULTI\nMIDI", &button_1, false, BUTTON_TYPE_MULTITOGGLE, 1), GridButton("PLAY\nMENU", &button_2, true), GridButton("ACTIVE\nSUM\nRING", &button_3, false, BUTTON_TYPE_MULTITOGGLE, 0), - GridButton(" ", &button_4, false), - GridButton(" ", &button_5, false), - GridButton(" ", &button_6, false), + GridButton("RE\nSTART", &button_4, false), + GridButton("SLOW\nDOWN", &button_5, false), + GridButton("REV\nERSE", &button_6, false), }), ButtonGrid((int) UI_MODE_TRIGGER_MENU, { GridButton("MIDI\nTRIG.", &button_1, false), @@ -241,6 +241,7 @@ class Ui { home_button->onReleased([this, n](){ this->setMode(UI_MODE_DEFAULT); this->button_grids[n].hideAllDescriptions(); + activeLooper()->speedUp(); }); // Return pointer to the home button @@ -375,7 +376,7 @@ class Ui { // Setup button Grid Button* home_button = setupButtonGrid(n); - // Chang the way in which buffers are summed + // Change the way in which buffers are summed button_3.onPress([this, n](){ button_grids[n].grid_buttons_[2].next(); buffer_summing_mode = (BufferSummingMode) button_grids[n].grid_buttons_[2].active; @@ -387,6 +388,26 @@ class Ui { activeLooper()->playback_state = (atoav::PlaybackState) (button_grids[n].grid_buttons_[0].active); }); + // Restart + button_4.onPress([this, n](){ + activeLooper()->restart(); + }); + + // DJ-style slow-down effect + button_5.onHold([this, n](){ + activeLooper()->slowDown(); + }); + button_5.onReleased([this, n](){ + activeLooper()->speedUp(); + }); + + button_6.onHold([this, n](){ + activeLooper()->reverse(); + }); + button_6.onReleased([this, n](){ + activeLooper()->speedUp(); + }); + // Store the last ui mode, for the check on top last_ui_mode = ui_mode; } -- GitLab