| Hi to all,
I modified PvsRecPlay.csd by Cabbage McCurdy collection, because I could
used it.
This .csd is very nice but:
In downloded version PlayOnce didn't work correctly, because after 'else'
was missing:
kPlayOnceNdx line 0,1,1
Moreover I insert this 'if' conditions:
if kLoopBeg < kLoopEnd then
kPlayNdx = (kPlayNdx*kLoopLen) + kLoopBeg
elseif kLoopBeg > kLoopEnd then
kPlayNdx = kLoopBeg-(kPlayNdx*kLoopLen) ;INVERT
else
kPlayNdx = kLoopBeg
endif
and I replaced:
kLoopBeg portk gkLoopBeg, kporttime
kLoopEnd portk gkLoopEnd, kporttime
with:
kLoopBeg = gkLoopBeg
kLoopEnd = gkLoopEnd
to avoid crash with begin and end point very close together.
I reduce stereo in to mono, but you can restore to stereo changing the lines
with *** flags.
I added play midi instr and global envelope also.
'Play Once' button blink correctly now, when it turn off.
Maybe this version can be useful to someone else.
Unfortly there is an unwanted effect:
At loop, the first time the sound is better, then it's more metallic.
Does anyone know how to avoid this?
Greetings
Andrea S. 2019
form caption("PVS Rec/Play") size(300, 500), pluginid("pvrp")
groupbox bounds( 0, 0,300, 95), text("Transport")
label bounds( 10, 75, 70, 14), text("Record")
label bounds( 80, 75, 70, 14), text("Pause")
label bounds(150, 75, 70, 14), text("Play Loop")
label bounds(220, 75, 70, 14), text("Play Once")
checkbox bounds( 10, 25, 70, 50), channel("Record"), value(0),
shape("square"), colour("red")
checkbox bounds( 80, 25, 70, 50), channel("Pause"), value(0),
shape("square"), colour("Blue")
checkbox bounds(150, 25, 70, 50), channel("PlayLoop"), value(0),
shape("square")
checkbox bounds(220, 25, 70, 50), channel("PlayOnce"), value(0),
shape("square"), colour("yellow")
hslider bounds( 0, 95, 300,50), channel("Speed"), range(-4.00, 4.00, 1) ;,
text("Speed")
label bounds(100, 135, 100,13), text("Speed") , align(centre)
hslider bounds( 0, 145, 300,50), channel("Pitch"), range(0.25, 4.00, 1) ;,
text("Pitch")
label bounds(100, 185, 100,13), text("Pitch") , align(centre)
hslider bounds( 0, 195, 300,50), channel("LoopBeg"), range(0, 1, 0) ;,
text("Loop Begin")
label bounds(100, 235, 100,13), text("Loop Begin") , align(centre)
hslider bounds( 0, 245, 300,50), channel("LoopEnd"), range(0, 1, 1) ;,
text("Loop End")
label bounds(100, 285, 100,13), text("Loop End") , align(centre)
hslider bounds( 0, 295, 300,50), channel("InGain"), range(0, 1, 1) ;,
text("Input Gain")
label bounds(100, 335, 100,13), text("Input Gain") , align(centre)
hslider bounds( 0, 345, 300,50), channel("OutGain"), range(0, 1, 1) ;,
text("Output Gain")
label bounds(100, 385, 100,13), text("Output Gain") , align(centre)
keyboard bounds(8, 410, 285, 80)
;-d -n
-dm0 -n -+rtmidi=null -M0 ;flag copati da LiveLooper.
sr = 44100
ksmps = 32
nchnls = 2
0dbfs = 1
massign 0, 3
;Author: Iain McCurdy (2012)
;***PER ATTIVARE REGISTRAZIONE STEREO RIPRISTINA RIGHE COMMENTATE CON ***
gistorageL ftgen 0,0,1048576,-7,0 ;AUDIO DATA STORAGE SPACE (ABOUT 23
SECONDS)
;gistorageR ftgen 0,0,1048576,-7,0 ;AUDIO DATA STORAGE SPACE (ABOUT 23
SECONDS) ;***SE LA REGISTRAZIONE è MONO QUESTA RIGA NON SERVE
gkRecDur init 0 ;DURATION OF THE MOST RECENTLY RECORDED BUFFER
gibuflen init 60 ;PVS BUFFER LENGTH
instr 1 ;READ IN WIDGETS AND START AND STOP THE VARIOUS RECORDING AND
PLAYBACK INSTRUMENTS
gitablelen = ftlen(gistorageL) ;DERIVE TABLE LENGTH
gkRecord chnget "Record" ;READ IN CABBAGE WIDGET CHANNELS
gkPause chnget "Pause"
gkPlayLoop chnget "PlayLoop"
gkPlayOnce chnget "PlayOnce"
gkPlayOnceTrig changed gkPlayOnce
gkSpeed chnget "Speed"
gkPitch chnget "Pitch"
gkLoopBeg chnget "LoopBeg"
gkLoopEnd chnget "LoopEnd"
gkInGain chnget "InGain"
gkOutGain chnget "OutGain"
giAtkTime init .5
giRelTime init .5
/*
;SOSTITUITO DAL 'DEFINE' SEGUENTE, PRESO DA TabRecFx.csd
#define TURN_ON(NAME)
#
i$NAME nstrnum "$NAME"
kOnTrig$NAME trigger gk$NAME,0.5,0
if kOnTrig$NAME==1 then ;IF BUTTON IS TURNED ON...
turnoff2 i$NAME,0,giRelTime ;UTILE NEL CASO IN CUI SI PREMA IL PLAY
MENTRE ANCORA è IN ESECUZIONE IL RELEASE, PER NON FAR RIMANERE 'INCANTATO'
IL BOTTONE
event "i",i$NAME,0,3600
endif
#
$TURN_ON(Record)
$TURN_ON(PlayOnce)
$TURN_ON(PlayLoop)
*/
;ALTERNATIVA A 'DEFINE'
#define TURN_ON_OFF(NAME) ;defines a macro with arguments. macro
per accendere e spegnere gli strumenti: 'Record', 'PlayOnce', 'PlayLoop'
# ;l'argomento è 'NAME'
i$NAME nstrnum "$NAME" ;Returns the number of a named
instrument. $NAME può essere lo strumento "Record' o 'PlayOnce' o
'PlayLoop', come stabilito sotto
;>>>>>>>>>>>>>>>> i$NAME cambia ad 'i' time, vedere oltre l'uso degli
opcode 'event' e 'turnoff2' <<<<<<<<<<<<<<<<<<<<<<
;serve ad accendere e spegnere gli strumenti 'Record', 'PlayOnce',
'PlayLoop'
kOnTrig$NAME trigger gk$NAME,0.5,0 ;Informs when a krate signal crosses a
threshold: ksig, kthreshold, kmode. Se è maggiore di .5 (kmode=0) o se è
minore di .5 (kmode = 1)
kOffTrig$NAME trigger gk$NAME,0.5,1 ;>>>>>>>>>>>>>>>>>>>> gk$NAME sarà
secondo i casi: gkRecord o gkPlayOnce o gkPlayLoop <<<<<<<<<<<<<<<<<<<<<
if kOnTrig$NAME==1 then ;IF BUTTON IS TURNED ON...
turnoff2 i$NAME,0,0 ;UTILE NEL CASO IN CUI SI PREMA IL PLAY MENTRE ANCORA
è IN ESECUZIONE IL RELEASE, PER NON FAR RIMANERE 'INCANTATO' IL BOTTONE
event "i",i$NAME,0,3600 ;Generates a score event from an instrument.
event_i "scorechar", iinsnum, idelay, idur, [, ip4] [, ip5] [, ...]
elseif kOffTrig$NAME==1 then ;IF BUTTON IS TURNED ON...
turnoff2 i$NAME,0,giRelTime ;spegne lo strumento generato da
'event', tempo di rilascio definito in gkRelTime
;PERCHE' c'era una VIRGOLA DOPO turnoff2 e funzionava lo stesso???
endif
#
$TURN_ON_OFF(Record) ;applica la stessa macro con tre diversi
bottoni (nomi dei canali)
$TURN_ON_OFF(PlayOnce)
$TURN_ON_OFF(PlayLoop)
endin
instr Record
if gkRecord==0 then ;IF BUTTON IS TURNED ON...
turnoff
endif
if gkPause=1 goto SKIP_RECORD ;IF PAUSE BUTTON IS ACTIVATED TEMPORARILY
SKIP RECORDING PROCESS
ainL,ainR ins ;READ AUDIO FROM LIVE INPUT CHANNEL 1
;MACRO THAT DEFINES THE CODED NEEDED TO RECORD A SINGLE CHANNEL PVS BUFFER
#define REC_BUF(CHAN)
#
iFFTsize = 1024
ioverlap = 256
iwinsize = 1024
iwintype = 1
;kPhOffset = 0
f_anal$CHAN pvsanal ain$CHAN, iFFTsize, ioverlap, iwinsize, iwintype
;ANALYSE THE LEFT CHANNEL AUDIO. OUTPUT AN F-SIGNAL.
ibuf$CHAN,ktime pvsbuffer f_anal$CHAN, gibuflen ;BUFFER FSIG
gkhandle$CHAN init ibuf$CHAN ;INITIALISE HANDLE TO BUFFER
#
;EXPAND BUFFER TWICE, ONCE FOR EACH STEREO CHANNEL
$REC_BUF(L)
;$REC_BUF(R) ;***NEL CASO DI REGISTRAZIONE MONO QUESTA RIGA NON SERVE
gkRecDur timeinsts ;DURATION OF CURRENT RECORDING
if gkRecDur>=gibuflen then ;IF BUFFER IS FULL (I.E. DO NOT OVERWRITE THE
BEGINNING OF THE BUFFER
turnoff ;TURN OFF THIS INSTRUMENT
endif ;ENDO OF THIS CONDITIONAL BRANCH
SKIP_RECORD: ;JUMP TO HERE WHEN 'PAUSE' BUTTON IS ACTIVE
endin
instr PlayLoop
;if gkPlayLoop==0 then ;IF BUTTON IS TURNED ON...
;turnoff
;endif
if gkPlayLoop==0 then ;IF 'PLAY LOOPED' BUTTON IS INACTIVE...
turnoff2 "PlayLoop",0,giRelTime ;TURN THIS INSTRUMENT OFF
endif ;END OF THIS CONDITIONAL BRANCH
if gkPause=1 goto SKIP_PLAY_LOOP ;IF PAUSE BUTTON IS ACTIVATED SKIP
PLAYBACK CODE
kporttime linseg 0,0.001,0.05 ;PORTAMENTO TIME RAMPS UP RAPIDLY TO A HELD
VALUE
kLoopBeg = gkLoopBeg
kLoopEnd = gkLoopEnd
;portk fa imballare il processo quando kLoopBeg e kLoopEnd hanno valori
uguali!!!!!! Oltre tutto sembra che non serva a nulla!!!!!!!!
;kLoopBeg portk gkLoopBeg, kporttime ;APPLY PORTAMENTO SMOOTHING TO
CHANGES OF LOOP BEGIN SLIDER
;kLoopEnd portk gkLoopEnd, kporttime ;APPLY PORTAMENTO SMOOTHING TO
CHANGES OF LOOP END SLIDER
kLoopBeg = kLoopBeg * gkRecDur ;RESCALE gkLoopBeg (RANGE 0-1) TO BE WITHIN
THE RANGE 0-FILE_LENGTH.
kLoopEnd = kLoopEnd * gkRecDur ;RESCALE gkLoopEnd (RANGE 0-1) TO BE WITHIN
THE RANGE 0-FILE_LENGTH.
kLoopLen = abs(kLoopEnd - kLoopBeg) ;DERIVE LOOP LENGTH FROM LOOP START AND
END POINTS
kPlayPhasFrq divz gkSpeed, kLoopLen, 0.00001 ;SAFELY DIVIDE, PROVIDING
ALTERNATIVE VALUE IN CASE DENOMINATOR IS ZERO
kPlayNdx phasor kPlayPhasFrq ;DEFINE PHASOR POINTER FOR BUFFER READ INDEX
;kLoopBeg = (kLoopBeg < kLoopEnd ? kLoopBeg : kLoopEnd) ;CHECK IF
LOOP-BEGINNING AND LOOP-END SLIDERS HAVE BEEN REVERSED
if kLoopBeg < kLoopEnd then
kPlayNdx = (kPlayNdx*kLoopLen) + kLoopBeg ;RESCALE INDEX POINTER ACCORDING
TO LOOP LENGTH AND LOOP BEGINING
elseif kLoopBeg > kLoopEnd then
kPlayNdx = kLoopBeg-(kPlayNdx*kLoopLen) ;INVERTE LA DIREZIONE
else
kPlayNdx = kLoopBeg
endif ;...IN TAL MODO SPEGNENDO E RIACCENDENDO
IL BOTTONE LA LETTURA RIPARTE.
f_bufL pvsbufread kPlayNdx , gkhandleL ;READ BUFFER
f_scaleL pvscale f_bufL, gkPitch ;RESCALE FREQUENCIES
aL pvsynth f_scaleL ;RESYNTHESIZE THE f-SIGNAL AS AN
AUDIO SIGNAL
;***SE LA REGISTRAZIONE è MONO LE TRE RIGHE SUCCESSIVE NON SERVONO
;f_bufR pvsbufread kPlayNdx , gkhandleR ;READ BUFFER - SE VUOI USARE
INGRESSO STEREO RIPRISTINA gkhandleR!!!!!!
;f_scaleR pvscale f_bufR, gkPitch ;RESCALE FREQUENCIES
;aR pvsynth f_scaleR ;RESYNTHESIZE THE f-SIGNAL AS AN
AUDIO SIGNAL
kEnv linsegr 0, giAtkTime, 1, giRelTime, 0 ;inviluppo globale.
Tempo di rilascio in accordo con turnoff2
;***SE LA REGISTRAZIONE è MONO SCRIVERE ALL'USCITA DUE VOLTE aL,
ALTRIMENTI aL POI aR
outs aL*gkOutGain*kEnv,aL*gkOutGain*kEnv ;SEND AUDIO TO OUTPUTS
SKIP_PLAY_LOOP: ;JUMP TO HERE WHEN 'PAUSE' BUTTON IS ACTIVE
endin
instr PlayOnce
;if gkPlayOnce==0 then ;IF BUTTON IS TURNED ON...
; turnoff ;2 "PlayOnce", 0, giRelTime
;endif
if gkPause=1 goto SKIP_PLAY_ONCE ;IF PAUSE BUTTON IS ACTIVATED SKIP
PLAYBACK
kPlayOnceNdx init 0 ;INITIALISE PLAYBACK POINTER
if kPlayOnceNdx<=gkRecDur then ;IF PLAYBACK IS NOT YET COMPLETED THEN
CONTINUE PLAYBACK
kLoopBeg = gkLoopBeg * gkRecDur ;RESCALE gkLoopBeg (RANGE 0-1) TO BE
WITHIN THE RANGE 0-FILE_LENGTH.
kLoopEnd = gkLoopEnd * gkRecDur ;RESCALE gkLoopEnd (RANGE 0-1) TO BE
WITHIN THE RANGE 0-FILE_LENGTH.
kPlayOnceNdx line 0,1,1 ;CREATE A MOVING POINTER
if kLoopEnd>kLoopBeg then ;IF LOOP END SLIDER IS AT A LATER POSITION TO
LOOP BEGIN SLIDER...
kPlayOnceNdx = (kPlayOnceNdx*gkSpeed)+kLoopBeg ;RESCALE MOVING POINTER
VALUE ACCORDING TO LOOP BEGIN POSITION AND SPEED SLIDER SETTING
if kPlayOnceNdx>=kLoopEnd then ;IF PLAY INDEX IS EQUAL TO OR GREATER
THAN THE DURATION OF THE RECORDED BUFFER (STOP PLAYBACK)...
turnoff ;TURN THIS INSTRUMENT OFF
endif ;END OF CONDITIONAL BRANCH
else ;OTHERWISE (I.E. LOOP BEGIN SLIDER IS AT A LATER POSITION THAT
LOOP END)
kPlayOnceNdx line 0,1,1 ;CREATE A MOVING POINTER ((((QUESTA RIGA
MANCAVA E 'PLAY ONCE' NON FUNZIONAVA!!!!!!!!!!!!!!!!!!!!!!!)))))
kPlayOnceNdx = kLoopBeg-(kPlayOnceNdx*gkSpeed) ;RESCALE MOVING POINTER
VALUE ACCORDING TO LOOP BEGIN POSITION AND SPEED SLIDER SETTING
if kPlayOnceNdx<=kLoopEnd then ;IF PLAY POINTER HAS REACHED THE
BEGINNING OF THE PRESCRIBED CHUNK BETWEEN LOOP BEGIN AND LOOP END (STOP
PLAYBACK)...
turnoff2 "PlayOnce", 0, giRelTime ;TURN THIS INSTRUMENT OFF
endif ;END OF CONDITIONAL BRANCH
endif ;END OF CONDITIONAL BRANCH
endif
f_bufL pvsbufread kPlayOnceNdx , gkhandleL ;READ BUFFER
f_scaleL pvscale f_bufL, gkPitch ;RESCALE FREQUENCIES
aL pvsynth f_scaleL ;RESYNTHESIZE THE f-SIGNAL AS AN
AUDIO SIGNAL
;***SE LA REGISTRAZIONE è MONO LE TRE RIGHE SUCCESSIVE NON SERVONO
;f_bufR pvsbufread kPlayOnceNdx , gkhandleR ;READ BUFFER - SE VUOI
USARE INGRESSO STEREO RIPRISTINA gkhandleR!!!!!!
;f_scaleR pvscale f_bufR, gkPitch ;RESCALE FREQUENCIES
;aR pvsynth f_scaleR ;RESYNTHESIZE THE f-SIGNAL AS AN
AUDIO SIGNAL
kEnv linsegr 0, giAtkTime, 1, giRelTime, 0 ;inviluppo globale.
Tempo di rilascio in accordo con turnoff2
;***SE LA REGISTRAZIONE è MONO SCRIVERE ALL'USCITA DUE VOLTE aL,
ALTRIMENTI aL POI aR
outs aL*gkOutGain*kEnv,aL*gkOutGain*kEnv ;SEND AUDIO TO OUTPUT
;else
; turnoff
;endif ;END OF CONDITIONAL BRANCH
SKIP_PLAY_ONCE:
krelease release
if krelease==1 then
chnset 1-krelease,"PlayOnce"
endif
endin
instr 3 ; PLayMidi, molto simile allo strumento 'PlayLoop'
kpitch = cpsmidi()/cpsmidinn(60) ; DERIVE RATIO BASED ON NOTE NUMBER
60 AS THE POINT OF UNISON (IE. RATIO=1)
ival ampmidi 1
;if gkPlayLoop==0 then ;IF BUTTON IS TURNED ON...
;turnoff
;endif
;if gkPlayLoop==0 then ;IF 'PLAY LOOPED' BUTTON IS INACTIVE...
;turnoff ;TURN THIS INSTRUMENT OFF
;endif ;END OF THIS CONDITIONAL BRANCH
if gkPause=1 goto SKIP_PLAY_LOOP ;IF PAUSE BUTTON IS ACTIVATED SKIP
PLAYBACK CODE
kporttime linseg 0,0.001,0.05 ;PORTAMENTO TIME RAMPS UP RAPIDLY TO A HELD
VALUE
kLoopBeg = gkLoopBeg
kLoopEnd = gkLoopEnd
;portk fa imballare il processo quando kLoopBeg e kLoopEnd hanno valori
uguali!!!!!! Oltre tutto sembra che non serva a nulla!!!!!!!!
;kLoopBeg portk gkLoopBeg, kporttime ;APPLY PORTAMENTO SMOOTHING TO
CHANGES OF LOOP BEGIN SLIDER
;kLoopEnd portk gkLoopEnd, kporttime ;APPLY PORTAMENTO SMOOTHING TO
CHANGES OF LOOP END SLIDER
kLoopBeg = kLoopBeg * gkRecDur ;RESCALE gkLoopBeg (RANGE 0-1) TO BE WITHIN
THE RANGE 0-FILE_LENGTH.
kLoopEnd = kLoopEnd * gkRecDur ;RESCALE gkLoopEnd (RANGE 0-1) TO BE WITHIN
THE RANGE 0-FILE_LENGTH.
kLoopLen = abs(kLoopEnd - kLoopBeg) ;DERIVE LOOP LENGTH FROM LOOP START AND
END POINTS
kPlayPhasFrq divz gkSpeed, kLoopLen, 0.00001 ;SAFELY DIVIDE, PROVIDING
ALTERNATIVE VALUE IN CASE DENOMINATOR IS ZERO
kPlayNdx phasor kPlayPhasFrq ;DEFINE PHASOR POINTER FOR BUFFER READ INDEX
;kLoopBeg = (kLoopBeg < kLoopEnd ? kLoopBeg : kLoopEnd) ;CHECK IF
LOOP-BEGINNING AND LOOP-END SLIDERS HAVE BEEN REVERSED
if kLoopBeg < kLoopEnd then
kPlayNdx = (kPlayNdx*kLoopLen) + kLoopBeg ;RESCALE INDEX POINTER ACCORDING
TO LOOP LENGTH AND LOOP BEGINING
elseif kLoopBeg > kLoopEnd then
kPlayNdx = kLoopBeg-(kPlayNdx*kLoopLen) ;INVERTE LA DIREZIONE
else
kLoopEnd = kLoopEnd-(kr/sr) ;EVITA CHE SI IMBALLI COMPLETAMENTE NEL
CASO CHE I DUE VALORI COINCIDANO...
endif ;...IN TAL MODO SPEGNENDO E RIACCENDENDO
IL BOTTONE LA LETTURA RIPARTE.
f_bufL pvsbufread kPlayNdx , gkhandleL ;READ BUFFER
f_scaleL pvscale f_bufL, gkPitch*kpitch ;RESCALE FREQUENCIES
aL pvsynth f_scaleL ;RESYNTHESIZE THE f-SIGNAL AS AN
AUDIO SIGNAL
;***SE LA REGISTRAZIONE è MONO LE TRE RIGHE SUCCESSIVE NON SERVONO
;f_bufR pvsbufread kPlayNdx , gkhandleR ;READ BUFFER - SE VUOI USARE
INGRESSO STEREO RIPRISTINA gkhandleR!!!!!!
;f_scaleR pvscale f_bufR, gkPitch*kpitch ;RESCALE FREQUENCIES
;aR pvsynth f_scaleR ;RESYNTHESIZE THE f-SIGNAL AS AN
AUDIO SIGNAL
kEnv linsegr 0, giAtkTime, ival, giRelTime, 0 ;inviluppo
globale. Tempo di rilascio in accordo con turnoff2
;***SE LA REGISTRAZIONE è MONO SCRIVERE ALL'USCITA DUE VOLTE aL,
ALTRIMENTI aL POI aR
outs aL*gkOutGain*kEnv,aL*gkOutGain*kEnv ;SEND AUDIO TO OUTPUTS
SKIP_PLAY_LOOP: ;JUMP TO HERE WHEN 'PAUSE' BUTTON IS ACTIVE
endin
i 1 0 [3600*24*7]
--
Sent from: http://csound.1045644.n5.nabble.com/Csound-General-f1093014.html
Csound mailing list
Csound@listserv.heanet.ie
https://listserv.heanet.ie/cgi-bin/wa?A0=CSOUND
Send bugs reports to
https://github.com/csound/csound/issues
Discussions of bugs and features can be posted here |