Metlivi-bloggen

Så här pausar du en modulationsposition och återupptar den baklänges vid nästa trigger i SuperCollider

Om du vill pausa en modulationsposition och återuppta den baklänges låter du dess fasgenerator fortsätta köras med inkrementet noll och ändrar sedan inkrementet till ett negativt värde vid nästa trigger. Låt fasåterställningsingången vara frånkopplad från dessa triggers, så att rörelsen fortsätter från den position där den hölls.

Den här handledningen bygger upp beteendet i SuperCollider: en stigande pitchsvepning pausas vid den första triggern och går tillbaka samma väg vid den andra. Den riktar sig till ljuddesigners som vill ha en repeterbar modulationsgest som styrs av efterföljande händelser. Samma fassignal kan senare styra en annan parameter.

29 oktober 20266 min läsningAv Metlivi Editorial Team
Avsnitt 1

Vad måste bevaras under pausen?

Se modulationen som två sammankopplade operationer: en position rör sig genom en cykel och en mappning omvandlar positionen till ett användbart parametervärde. Här rör sig positionen från noll mot ett, och mappningen omvandlar den till oscillatorfrekvens.

SuperColliders Phasor tillhandahåller positionen. Argumentet rate anger inkrementet per sampel; dess triggeringång hoppar i stället till resetPos. Det här är separata styrningar, så en trigger som används för att ändra riktning ska inte också återställa positionen. Phasor-dokumentation

Implementeringen behåller ett internt nivåvärde och adderar takten till det. Därav följer att en takt på noll håller kvar nivån, medan en negativ takt för den nedåt. Patchen nedan tillämpar detta direkt och bevarar generatorns tillstånd under hela pausen. Implementering av SuperCollider 3.14.0 TriggerUGens.cpp

Avsnitt 2

Vad ska varje efterföljande trigger göra?

Definiera händelseförloppet innan du kopplar in ljudet. I den här patchen börjar rörelsen framåt direkt. Varje efterföljande trigger går vidare ett steg i tillståndsföljden:

Mottagna triggers Tillstånd Riktningsmultiplikator
0 Rör sig framåt +1
1 Håller aktuell position 0
2 Återupptas baklänges −1
3 Håller aktuell position 0
4 Återupptas framåt +1

Den här fyratillståndscykeln skiljer de två hålltillstånden åt: det ena leder till bakåtrörelse och det andra till framåtrörelse. Det gör upprepade gester förutsägbara utan att du behöver ytterligare en riktningsknapp.

PulseCount räknas upp när dess ingång ändras från icke-positiv till positiv. Om du tar räknarvärdet modulo fyra får du de återkommande indexen 0–3. Select väljer sedan motsvarande multiplikator från [1, 0, -1, 0]. Det här är de dokumenterade funktionerna för PulseCount och Select.

Avsnitt 3

Hur bygger du hela patchen?

Använd en lokal SuperCollider-installation med fungerande ljudutgång; exemplet följer dokumentationen för 3.14.0. Det använder inbyggda enhetsgeneratorer och skapar sitt eget ljud, så inga samplingsfiler eller tillägg behövs. Kör hela kodblocket en gång och vänta på klar-meddelandet.

waitForBoot startar servern om det behövs. Definitionen skickas innan syntesen skapas, och s.sync väntar på att eventuella pågående serveråtgärder ska slutföras. Se Server-dokumentationen och SynthDef-dokumentationen.

(
s = Server.default;
s.waitForBoot({
    SynthDef(\pauseReverseMod, {
        |out = 0, t_step = 0, cycleSeconds = 8, amp = 0.08|
        var state, direction, increment, phase, frequency, sound;

        state = PulseCount.kr(t_step) % 4;
        direction = Select.kr(state, [1, 0, -1, 0]);

        // A full 0..1 traversal takes cycleSeconds seconds.
        increment = direction * SampleDur.ir
            / cycleSeconds.max(0.01);

        // State-changing triggers never reset this phase.
        phase = Phasor.ar(
            trig: 0,
            rate: increment,
            start: 0,
            end: 1,
            resetPos: 0
        );

        frequency = LinExp.ar(phase, 0, 1, 220, 880);
        sound = SinOsc.ar(frequency, 0, amp);
        Out.ar(out, sound ! 2);

        Poll.kr(Impulse.kr(2), state, "state");
        Poll.kr(Impulse.kr(2), A2K.kr(phase), "phase");
    }).add;

    s.sync;
    ~pauseReverseSynth = Synth(\pauseReverseMod);
    "Ready: evaluate ~pauseReverseSynth.set(\\t_step, 1);".postln;
});
)

Inkrementet är riktningen multiplicerad med sampelns tidslängd och dividerad med cykelns tidslängd. SampleDur returnerar inversen av serverns samplingsfrekvens, så inställningen på åtta sekunder förutsätter inte någon särskild samplingsfrekvens. SampleDur-dokumentation

Pitchmappningen sträcker sig från 220 till 880 Hz. LinExp omvandlar ett linjärt ingångsintervall till ett exponentiellt utgångsintervall; destinationsändpunkterna måste vara skilda från noll och ha samma tecken. Båda ändpunkterna uppfyller det kravet här. LinExp-dokumentation

Jag granskade SuperCollider-exemplet mot den hämtade dokumentationen. SuperCollider-miljön var inte tillgänglig i undersökningsmiljön, så jag körde inte patchen och lyssnade inte på den. En separat deterministisk aritmetisk kontroll verifierade riktningssekvensen och att ett nollinkrement håller positionen.

Avsnitt 4

Hur pausar och återupptar du rörelsen baklänges?

När klar-meddelandet har visats låter du pitchen stiga i ungefär två sekunder. Kör sedan det här interaktionskommandot en gång:

~pauseReverseSynth.set(\t_step, 1);

Tillståndet ska bli 1, och den utskrivna fasen ska stabiliseras vid ett värde. Vänta en stund och kör sedan samma kommando igen. Tillståndet ska bli 2, och fasen ska minska från den position där den hölls. En tredje körning håller den nedåtgående svepningen; en fjärde startar den framåt igen.

Prefixet t_ gör t_step till en triggerstyrning. När du ställer in den skapas en impuls på styrhastigheten, vilket gör att samma kommando kan användas upprepade gånger utan att du manuellt behöver skicka en separat nolla mellan vanliga kommandon som körs med mellanrum. Dokumentation om triggerstyrning i SynthDef

Som ett exempel på en tidsberäkning går en cykel på åtta sekunder framåt med 0,125 av sitt intervall per sekund. Om du pausar efter två sekunder hålls positionen därför vid ungefär 0,25. Efter valfri paus tar en sekunds bakåtrörelse den till ungefär 0,125. Det här är beräknade förväntade värden; den faktiska stoppunkten avgörs av när du kör kommandot manuellt.

Avsluta genom att köra kommandot för att rensa:

~pauseReverseSynth.free;
Avsnitt 5

Hur kan du kontrollera att positionen verkligen stod stilla?

Använd den utskrivna fasen som huvuddiagnostik. Under framåtrörelse ska den öka; i båda hålltillstånden ska den vara oförändrad; under bakåtrörelse ska den minska tills den når cykelgränsen.

Patchen skriver ut värdet två gånger per sekund, så visningen samplar beteendet i stället för att visa varje sampel. Observera flera avläsningar i följd under pausen och jämför sedan med de första avläsningarna när rörelsen återupptas nedåt. Poll är avsett för felsökning av värden från enhetsgeneratorer; ta bort de två avfrågningsraderna när du anpassar definitionen för vanlig användning. Poll-dokumentation

Det här testet ger mer information än att bara lyssna. Ett oförändrat ljud visar att målvärdet slutade ändras, medan en stabil fasavläsning bekräftar att även den underliggande positionen stod stilla. Om du låter mappningen vara oförändrad under hela testet blir resultatet lättare att tolka.

Avsnitt 6

Varför kan patchen starta om, hoppa eller missa en trigger?

Den startar om när du återupptar. Kontrollera om händelsen också når triggeringången på Phasor. Den ingången återställer uttryckligen positionen. I den här patchen är den kvar på noll, medan händelserna bara skickas till tillståndsräknaren. Phasor-dokumentation

Den hoppar efter att ha nått en ändpunkt. Det här exemplet loopar med avsikt. Implementeringen slår om fasen inom sitt konfigurerade intervall, även vid bakåtrörelse. När bakåtrörelsen passerar noll återgår fasen till nära den övre gränsen, vilket med den här rampmappningen ger ett pitchhopp. Testa först pausen och riktningsbytet på avstånd från den gränsen. Phasor-implementering

Flera snabba kommandon ger inte flera tillstånd. Räknaren behöver separata stigande övergångar. Triggerstyrningar arbetar med styrhastighet, så utgå inte från att flera kommandon som kommer inom ett och samma styrblock blir separata händelser. Börja med avsiktliga kommandon med mellanrum; utforma händelsekällan för tydligt åtskilda pulser om du behöver tätt tidsatta sekvenser. PulseCount-dokumentation, SynthDef-dokumentation

Ljudet ändras medan fasen hålls. Kontrollera om du också ändrar målmappningen eller någon annan ljudparameter. Låt pitchändpunkterna vara fasta under det här testet och använd den utskrivna fasen för att isolera modulationens transport.

Den färdiga gesten är framåt, håll, bakåt, håll och sedan framåt igen. När sekvensen fungerar som den ska kan du återanvända tillståndsräknaren och fasgeneratorn som en modulationskälla och ändra målmappningen så att den passar ljudet du bygger.

Avsnitt 7

Källor

Relaterad läsning

Fortsätt utforska detta ämne