Csound Csound-dev Csound-tekno Search About

[Csnd] PvsRecPlay.csd

Date2019-04-28 20:41
FromAndreaS
Subject[Csnd] PvsRecPlay.csd
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