149 lines
5.2 KiB
Plaintext
149 lines
5.2 KiB
Plaintext
; REBEAT
|
|
;
|
|
; simple pedal-like looper
|
|
;
|
|
; code based on TabRecPlay example by Iain McCurdy
|
|
|
|
; (s) Severák 2019
|
|
; licensed with MIT license
|
|
<Cabbage>
|
|
form caption("REBEAT") size(300, 200), colour(58, 110, 182), pluginid("rebe")
|
|
button bounds(48, 164, 192, 27) text("REBEAT", "REBEAT") channel("rebeat") identchannel("rebeatWidget") fontcolour:0(128, 128, 128, 255)
|
|
gentable bounds(2, 6, 296, 131) identchannel("gentable") tablenumber(101.0)
|
|
label bounds(50, 144, 191, 16) text("waiting...") identchannel("statusbar")
|
|
</Cabbage>
|
|
<CsoundSynthesizer>
|
|
<CsOptions>
|
|
-n -d -+rtmidi=NULL -M0 -m0d
|
|
</CsOptions>
|
|
<CsInstruments>
|
|
; Initialize the global variables.
|
|
ksmps = 32
|
|
nchnls = 2
|
|
0dbfs = 1
|
|
|
|
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)
|
|
gkRecDur init 0
|
|
|
|
; ---
|
|
gkRecord init 0
|
|
gkPause init 0
|
|
gkPlayLoop init 0
|
|
|
|
; ---
|
|
gkInGain init 1
|
|
gkLoopBeg init 0
|
|
gkLoopEnd init 1
|
|
gkSpeed init 1
|
|
gkOutGain init 1
|
|
|
|
|
|
instr GUI
|
|
; 0 = stopped; 1 = recording; 2 = looping
|
|
kStatus init 0
|
|
kRebeat chnget "rebeat"
|
|
Scolor init ""
|
|
|
|
gitablelen = ftlen(gistorageL)
|
|
|
|
if changed:k(kRebeat)==1 then
|
|
if kStatus==0 then
|
|
chnset "text(\"recording...\")", "statusbar"
|
|
Scolor strcatk "fontcolour:0(255, 0, 0, 255), fontcolour:1(255, 0, 0, 255)", ""
|
|
kStatus = 1
|
|
event "i", "Record", 0, 23
|
|
printks "recording...\n", 0
|
|
elseif kStatus==1 then
|
|
chnset "text(\"playing...\")", "statusbar"
|
|
Scolor strcatk "fontcolour:0(0, 100, 0, 255), fontcolour:1(0, 100, 0, 255)", ""
|
|
kStatus = 2
|
|
printks "playing...\n", 0
|
|
gkPlayLoop = 1
|
|
event "i", "PlayLoop", 0, 3600
|
|
elseif kStatus==2 then
|
|
chnset "text(\"waiting...\")", "statusbar"
|
|
Scolor strcatk "fontcolour:0(128,128,128,255),fontcolour:1(128,128,128,255)", ")"
|
|
kStatus = 0
|
|
gkPlayLoop = 0
|
|
printks "waiting...\n", 0
|
|
endif
|
|
|
|
chnset Scolor, "rebeatWidget"
|
|
|
|
endif
|
|
endin
|
|
|
|
;instr setTable
|
|
; Stablenum sprintf "tablenumber(%d)", gistorageL
|
|
; printks "tablenumber(%d)", 0, gistorageL
|
|
; chnset Stablenum, "gentable"
|
|
;endin
|
|
|
|
instr Record
|
|
if gkPlayLoop == 1 then
|
|
turnoff
|
|
endif
|
|
if gkPause == 1 goto SKIP_RECORD ;IF PAUSE BUTTON IS ACTIVATED TEMPORARILY SKIP RECORDING PROCESS
|
|
;printks "rec...\n", 2
|
|
|
|
ainL,ainR ins ;READ AUDIO FROM LIVE INPUT CHANNEL 1
|
|
aRecNdx line 0,gitablelen/sr,1 ;CREATE A POINTER FOR WRITING TO TABLE - FREQUENCY OF POINTER IS DEPENDENT UPON TABLE LENGTH AND SAMPLE RATE
|
|
aRecNdx = aRecNdx*gitablelen ;RESCALE POINTER ACCORDING TO LENGTH OF FUNCTION TABLE
|
|
gkRecDur downsamp aRecNdx ;CREATE A K-RATE GLOBAL VARIABLE THAT WILL BE USED BY THE 'PLAYBACK' INSTRUMENT TO DETERMINE THE LENGTH OF RECORDED DATA
|
|
tablew ainL*gkInGain, aRecNdx, gistorageL;WRITE AUDIO TO AUDIO STORAGE TABLE
|
|
tablew ainR*gkInGain, aRecNdx, gistorageR;WRITE AUDIO TO AUDIO STORAGE TABLE
|
|
|
|
; scruber
|
|
Sscruber sprintfk "scrubberposition(%d, %d), tablenumber(%d)", k(aRecNdx), k(gistorageL), k(gistorageL)
|
|
chnset Sscruber, "gentable"
|
|
|
|
if gkRecDur>=gitablelen then ;IF MAXIMUM RECORD TIME IS REACHED...
|
|
kRecord=0
|
|
printks "limit reached!\n", 0
|
|
turnoff
|
|
endif ;END OF CONDITIONAL BRANCH
|
|
SKIP_RECORD:
|
|
endin
|
|
|
|
instr PlayLoop
|
|
if gkPlayLoop==0 then
|
|
turnoff
|
|
endif
|
|
if gkPause=1 goto SKIP_PLAY_LOOP ;IF PAUSE BUTTON IS ACTIVATED SKIP ALL RECORDING AND PLAYBACK...
|
|
|
|
|
|
kporttime linseg 0,0.001,0.05 ;PORTAMENTO TIME RAMPS UP RAPIDLY TO A HELD VALUE
|
|
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. NEW OUTPUT VARIABLE kLoopBeg.
|
|
kLoopEnd = kLoopEnd * gkRecDur ;RESCALE gkLoopEnd (RANGE 0-1) TO BE WITHIN THE RANGE 0-FILE_LENGTH. NEW OUTPUT VARIABLE kLoopEnd.
|
|
kLoopLen = kLoopEnd - kLoopBeg ;DERIVE LOOP LENGTH FROM LOOP START AND END POINTS
|
|
kPlayPhasFrq divz gkSpeed, (kLoopLen/sr), 0.00001 ;SAFELY DIVIDE, PROVIDING ALTERNATIVE VALUE INCASE DENOMINATOR IS ZERO
|
|
aPlayNdx phasor kPlayPhasFrq ;DEFINE PHASOR POINTER FOR TABLE INDEX
|
|
kLoopBeg = (kLoopBeg < kLoopEnd ? kLoopBeg : kLoopEnd) ;CHECK IF LOOP-BEGINNING AND LOOP-END SLIDERS HAVE BEEN REVERSED
|
|
aLoopLen interp abs(kLoopLen)
|
|
aLoopBeg interp kLoopBeg
|
|
aPlayNdx = (aPlayNdx*aLoopLen) + aLoopBeg ;RESCALE INDEX POINTER ACCORDING TO LOOP LENGTH AND LOOP BEGINING
|
|
|
|
; scruber
|
|
Sscruber sprintfk "scrubberposition(%d, %d), tablenumber(%d)", k(aPlayNdx), k(gistorageL), k(gistorageL)
|
|
chnset Sscruber, "gentable"
|
|
|
|
aL tablei aPlayNdx, gistorageL ;READ AUDIO FROM AUDIO STORAGE FUNCTION TABLE
|
|
aR tablei aPlayNdx, gistorageR ;READ AUDIO FROM AUDIO STORAGE FUNCTION TABLE
|
|
outs aL*gkOutGain,aR*gkOutGain ;SEND AUDIO TO OUTPUTS
|
|
|
|
SKIP_PLAY_LOOP:
|
|
endin
|
|
|
|
</CsInstruments>
|
|
<CsScore>
|
|
;causes Csound to run for about 7000 years...
|
|
f0 z
|
|
;starts instrument 1 and runs it for a week
|
|
i "GUI" 0 z
|
|
;i "setTable" 0 1
|
|
</CsScore>
|
|
</CsoundSynthesizer>
|