From 80cce5d085d7996b52fa392c07f56fc07bad5206 Mon Sep 17 00:00:00 2001 From: Pierre Alexandre Tremblay Date: Thu, 28 Mar 2019 18:06:52 +0000 Subject: [PATCH] all buf* classes have a 'action' argument now and sync properly. --- release-packaging/Classes/FluidBufCompose.sc | 10 ++++++++-- release-packaging/Classes/FluidBufHPSS.sc | 17 +++++++++++++---- release-packaging/Classes/FluidBufNMF.sc | 12 ++++++++++-- .../Classes/FluidBufNoveltySlice.sc | 9 +++++++-- release-packaging/Classes/FluidBufOnsetSlice.sc | 11 ++++++++--- release-packaging/Classes/FluidBufSines.sc | 13 +++++++++---- .../Classes/FluidBufTransientSlice.sc | 9 +++++++-- release-packaging/Classes/FluidBufTransients.sc | 10 ++++++++-- .../HelpSource/Classes/FluidBufCompose.schelp | 3 +++ .../HelpSource/Classes/FluidBufHPSS.schelp | 4 +++- .../HelpSource/Classes/FluidBufNMF.schelp | 3 +++ .../Classes/FluidBufNoveltySlice.schelp | 3 +++ .../HelpSource/Classes/FluidBufSines.schelp | 3 +++ .../Classes/FluidBufTransientSlice.schelp | 3 +++ .../Classes/FluidBufTransients.schelp | 3 +++ 15 files changed, 91 insertions(+), 22 deletions(-) diff --git a/release-packaging/Classes/FluidBufCompose.sc b/release-packaging/Classes/FluidBufCompose.sc index 47fe4cb..cdb11d9 100644 --- a/release-packaging/Classes/FluidBufCompose.sc +++ b/release-packaging/Classes/FluidBufCompose.sc @@ -1,5 +1,5 @@ FluidBufCompose{ - *process { arg server, srcBufNum, startAt = 0, nFrames = -1, startChan = 0, nChans = -1, srcGain = 1, dstBufNum, dstStartAt = 0, dstStartChan = 0, dstGain = 0; + *process { arg server, srcBufNum, startAt = 0, nFrames = -1, startChan = 0, nChans = -1, srcGain = 1, dstBufNum, dstStartAt = 0, dstStartChan = 0, dstGain = 0, action; srcBufNum = srcBufNum.asUGenInput; dstBufNum = dstBufNum.asUGenInput; @@ -8,6 +8,12 @@ FluidBufCompose{ if(dstBufNum.isNil) {Error("Invalid Buffer").format(thisMethod.name, this.class.name).throw}; server = server ? Server.default; - server.sendMsg(\cmd, \BufCompose, srcBufNum, startAt, nFrames, startChan, nChans, srcGain, dstBufNum, dstStartAt, dstStartChan, dstGain); + + forkIfNeeded{ + server.sendMsg(\cmd, \BufCompose, srcBufNum, startAt, nFrames, startChan, nChans, srcGain, dstBufNum, dstStartAt, dstStartChan, dstGain); + server.sync; + dstBufNum = server.cachedBufferAt(dstBufNum); dstBufNum.updateInfo; server.sync; + action.value(dstBufNum); + }; } } diff --git a/release-packaging/Classes/FluidBufHPSS.sc b/release-packaging/Classes/FluidBufHPSS.sc index b28f343..acef5b6 100644 --- a/release-packaging/Classes/FluidBufHPSS.sc +++ b/release-packaging/Classes/FluidBufHPSS.sc @@ -1,5 +1,5 @@ FluidBufHPSS{ - *process { arg server, srcBufNum, startAt = 0, nFrames = -1, startChan = 0, nChans = -1, harmBufNum, percBufNum, resBufNum, hFiltSize = 17, pFiltSize = 31, modeFlag, htf1 = 0.1, hta1 = 0, htf2 = 0.5, hta2 = 0, ptf1 = 0.1, pta1 = 0, ptf2 = 0.5, pta2 = 0, winSize = 1024, hopSize = -1, fftSize = -1; + *process { arg server, srcBufNum, startAt = 0, nFrames = -1, startChan = 0, nChans = -1, harmBufNum, percBufNum, resBufNum, hFiltSize = 17, pFiltSize = 31, modeFlag, htf1 = 0.1, hta1 = 0, htf2 = 0.5, hta2 = 0, ptf1 = 0.1, pta1 = 0, ptf2 = 0.5, pta2 = 0, winSize = 1024, hopSize = -1, fftSize = -1, action; var maxFFTSize = if (fftSize == -1) {winSize.nextPowerOfTwo} {fftSize}; @@ -13,9 +13,18 @@ FluidBufHPSS{ server = server ? Server.default; harmBufNum = harmBufNum ? -1; percBufNum = percBufNum ? -1; + resBufNum = resBufNum ? -1; - //For wrapped RT clients, send maximal param values as aliases of the ones that are passed + //NB For wrapped versions of NRT classes, we set the params for maxima to + //whatever has been passed in language-side (e.g maxFFTSize still exists as a parameter for the server plugin, but makes less sense here: it just needs to be set to a legal value) - server.sendMsg(\cmd, \BufHPSS, srcBufNum, startAt, nFrames, startChan, nChans, harmBufNum, percBufNum, resBufNum, hFiltSize, pFiltSize, modeFlag, htf1, hta1, htf2, hta2, ptf1, pta1, ptf2, pta2, winSize, hopSize, fftSize, maxFFTSize, hFiltSize, pFiltSize); -} + forkIfNeeded{ + server.sendMsg(\cmd, \BufHPSS, srcBufNum, startAt, nFrames, startChan, nChans, harmBufNum, percBufNum, resBufNum, hFiltSize, pFiltSize, modeFlag, htf1, hta1, htf2, hta2, ptf1, pta1, ptf2, pta2, winSize, hopSize, fftSize, maxFFTSize, hFiltSize, pFiltSize); + server.sync; + if (harmBufNum != -1) {harmBufNum = server.cachedBufferAt(harmBufNum); harmBufNum.updateInfo; server.sync;} {harmBufNum = nil}; + if (percBufNum != -1) {percBufNum = server.cachedBufferAt(percBufNum); percBufNum.updateInfo; server.sync;} {percBufNum = nil}; + if (resBufNum != -1) {resBufNum = server.cachedBufferAt(resBufNum); resBufNum.updateInfo;server.sync;} {resBufNum = nil}; + action.value(harmBufNum, percBufNum, resBufNum); + }; + } } diff --git a/release-packaging/Classes/FluidBufNMF.sc b/release-packaging/Classes/FluidBufNMF.sc index 48a4168..596e0d7 100644 --- a/release-packaging/Classes/FluidBufNMF.sc +++ b/release-packaging/Classes/FluidBufNMF.sc @@ -1,5 +1,5 @@ FluidBufNMF { - *process { arg server, srcBufNum, startAt = 0, nFrames = -1, startChan = 0, nChans = -1, dstBufNum, dictBufNum, dictFlag = 0, actBufNum, actFlag = 0, rank = 1, nIter = 100, sortFlag = 0, winSize = 1024, hopSize = -1, fftSize = -1, winType = 0, randSeed = -1; + *process { arg server, srcBufNum, startAt = 0, nFrames = -1, startChan = 0, nChans = -1, dstBufNum, dictBufNum, dictFlag = 0, actBufNum, actFlag = 0, rank = 1, nIter = 100, sortFlag = 0, winSize = 1024, hopSize = -1, fftSize = -1, winType = 0, randSeed = -1, action; srcBufNum = srcBufNum.asUGenInput; @@ -10,10 +10,18 @@ FluidBufNMF { if(srcBufNum.isNil) { Error("Invalid buffer").format(thisMethod.name, this.class.name).throw}; server = server ? Server.default; + dstBufNum = dstBufNum ? -1; dictBufNum = dictBufNum ? -1; actBufNum = actBufNum ? -1; - server.sendMsg(\cmd, \BufNMF, srcBufNum, startAt, nFrames, startChan, nChans, dstBufNum, dictBufNum, dictFlag, actBufNum, actFlag, rank, nIter, winSize, hopSize, fftSize); + forkIfNeeded{ + server.sendMsg(\cmd, \BufNMF, srcBufNum, startAt, nFrames, startChan, nChans, dstBufNum, dictBufNum, dictFlag, actBufNum, actFlag, rank, nIter, winSize, hopSize, fftSize); + server.sync; + if (dstBufNum != -1) {dstBufNum = server.cachedBufferAt(dstBufNum); dstBufNum.updateInfo; server.sync;} {dstBufNum = nil}; + if (dictBufNum != -1) {dictBufNum = server.cachedBufferAt(dictBufNum); dictBufNum.updateInfo;server.sync;} {dictBufNum = nil}; + if (actBufNum != -1) {actBufNum = server.cachedBufferAt(actBufNum); actBufNum.updateInfo;server.sync;} {actBufNum = nil}; + action.value(dstBufNum,dictBufNum,actBufNum); + }; } } diff --git a/release-packaging/Classes/FluidBufNoveltySlice.sc b/release-packaging/Classes/FluidBufNoveltySlice.sc index 49ae3cd..fcb60a9 100644 --- a/release-packaging/Classes/FluidBufNoveltySlice.sc +++ b/release-packaging/Classes/FluidBufNoveltySlice.sc @@ -1,5 +1,5 @@ FluidBufNoveltySlice{ - *process { arg server, srcBufNum, startAt = 0, nFrames = -1, startChan = 0, nChans = -1, indBufNum, kernSize = 3, thresh = 0.8, filtSize = 1, winSize = 1024, hopSize = -1, fftSize = -1; + *process { arg server, srcBufNum, startAt = 0, nFrames = -1, startChan = 0, nChans = -1, indBufNum, kernSize = 3, thresh = 0.8, filtSize = 1, winSize = 1024, hopSize = -1, fftSize = -1, action; //var maxFFTSize = if (fftSize == -1) {winSize.nextPowerOfTwo} {fftSize}; //ready for when we need it from the RT wrapper @@ -11,6 +11,11 @@ FluidBufNoveltySlice{ server = server ? Server.default; - server.sendMsg(\cmd, \BufNoveltySlice, srcBufNum, startAt, nFrames, startChan, nChans, indBufNum, kernSize, thresh, filtSize, winSize, hopSize, fftSize); + forkIfNeeded{ + server.sendMsg(\cmd, \BufNoveltySlice, srcBufNum, startAt, nFrames, startChan, nChans, indBufNum, kernSize, thresh, filtSize, winSize, hopSize, fftSize); + server.sync; + indBufNum = server.cachedBufferAt(indBufNum); indBufNum.updateInfo; server.sync; + action.value(indBufNum); + }; } } diff --git a/release-packaging/Classes/FluidBufOnsetSlice.sc b/release-packaging/Classes/FluidBufOnsetSlice.sc index 9d45cc0..2aa02eb 100644 --- a/release-packaging/Classes/FluidBufOnsetSlice.sc +++ b/release-packaging/Classes/FluidBufOnsetSlice.sc @@ -1,5 +1,5 @@ FluidBufOnsetSlice{ - *process { arg server, srcBufNum, startAt = 0, nFrames = -1, startChan = 0, nChans = -1, indBufNum, function = 0, threshold = 0.1, debounce = 2, filterSize = 5, frameDelta = 0, winSize = 1024, hopSize = -1, fftSize = -1; + *process { arg server, srcBufNum, startAt = 0, nFrames = -1, startChan = 0, nChans = -1, indBufNum, function = 0, threshold = 0.1, debounce = 2, filterSize = 5, frameDelta = 0, winSize = 1024, hopSize = -1, fftSize = -1, action; var maxFFTSize = if (fftSize == -1) {winSize.nextPowerOfTwo} {fftSize}; @@ -14,6 +14,11 @@ FluidBufOnsetSlice{ //NB For wrapped versions of NRT classes, we set the params for maxima to //whatever has been passed in language-side (e.g maxFFTSize still exists as a parameter for the server plugin, but makes less sense here: it just needs to be set to a legal value) - server.sendMsg(\cmd, \BufOnsetSlice, srcBufNum, startAt, nFrames, startChan, nChans, indBufNum, function, threshold, debounce, filterSize, frameDelta, winSize, hopSize, fftSize, maxFFTSize); -} + forkIfNeeded{ + server.sendMsg(\cmd, \BufOnsetSlice, srcBufNum, startAt, nFrames, startChan, nChans, indBufNum, function, threshold, debounce, filterSize, frameDelta, winSize, hopSize, fftSize, maxFFTSize); + server.sync; + indBufNum = server.cachedBufferAt(indBufNum); indBufNum.updateInfo; server.sync; + action.value(indBufNum); + }; + } } diff --git a/release-packaging/Classes/FluidBufSines.sc b/release-packaging/Classes/FluidBufSines.sc index d3e6f5e..dd6a96e 100644 --- a/release-packaging/Classes/FluidBufSines.sc +++ b/release-packaging/Classes/FluidBufSines.sc @@ -1,5 +1,5 @@ FluidBufSines{ - *process { arg server, srcBufNum, startAt = 0, nFrames = -1, startChan = 0, nChans = -1, sineBufNum, resBufNum, bw = 76, thresh = 0.7, minTrackLen = 15, magWeight = 0.1, freqWeight = 1, winSize = 1024, hopSize = -1, fftSize = -1; + *process { arg server, srcBufNum, startAt = 0, nFrames = -1, startChan = 0, nChans = -1, sineBufNum, resBufNum, bw = 76, thresh = 0.7, minTrackLen = 15, magWeight = 0.1, freqWeight = 1, winSize = 1024, hopSize = -1, fftSize = -1, action; var maxFFTSize = if (fftSize == -1) {winSize.nextPowerOfTwo} {fftSize}; @@ -13,10 +13,15 @@ FluidBufSines{ sineBufNum = sineBufNum ? -1; resBufNum = resBufNum ? -1; - //NB For wrapped versions of NRT classes, we set the params for maxima to //whatever has been passed in language-side (e.g maxFFTSize still exists as a parameter for the server plugin, but makes less sense here: it just needs to be set to a legal value) - server.sendMsg(\cmd, \BufSines, srcBufNum, startAt, nFrames, startChan, nChans, sineBufNum, resBufNum, bw, thresh, minTrackLen, magWeight, freqWeight, winSize, hopSize, fftSize, maxFFTSize); -} + forkIfNeeded{ + server.sendMsg(\cmd, \BufSines, srcBufNum, startAt, nFrames, startChan, nChans, sineBufNum, resBufNum, bw, thresh, minTrackLen, magWeight, freqWeight, winSize, hopSize, fftSize, maxFFTSize); + server.sync; + if (sineBufNum != -1) {sineBufNum = server.cachedBufferAt(sineBufNum); sineBufNum.updateInfo; server.sync;} {sineBufNum = nil}; + if (resBufNum != -1) {resBufNum = server.cachedBufferAt(resBufNum); resBufNum.updateInfo;server.sync;} {resBufNum = nil}; + action.value(sineBufNum,resBufNum); + }; + } } diff --git a/release-packaging/Classes/FluidBufTransientSlice.sc b/release-packaging/Classes/FluidBufTransientSlice.sc index e7879b9..42f8007 100644 --- a/release-packaging/Classes/FluidBufTransientSlice.sc +++ b/release-packaging/Classes/FluidBufTransientSlice.sc @@ -1,5 +1,5 @@ FluidBufTransientSlice{ - *process { arg server, srcBufNum, startAt = 0, nFrames = -1, startChan = 0, nChans = -1, indBufNum, order = 20, blockSize = 256, padSize = 128, skew = 0, threshFwd = 2, threshBack = 1.1, winSize = 14, debounce = 25, minSlice = 1000; + *process { arg server, srcBufNum, startAt = 0, nFrames = -1, startChan = 0, nChans = -1, indBufNum, order = 20, blockSize = 256, padSize = 128, skew = 0, threshFwd = 2, threshBack = 1.1, winSize = 14, debounce = 25, minSlice = 1000, action; srcBufNum = srcBufNum.asUGenInput; indBufNum = indBufNum.asUGenInput; @@ -9,6 +9,11 @@ FluidBufTransientSlice{ server = server ? Server.default; - server.sendMsg(\cmd, \BufTransientSlice, srcBufNum, startAt, nFrames, startChan, nChans, indBufNum, order, blockSize, padSize, skew, threshFwd, threshBack, winSize, debounce, minSlice); + forkIfNeeded{ + server.sendMsg(\cmd, \BufTransientSlice, srcBufNum, startAt, nFrames, startChan, nChans, indBufNum, order, blockSize, padSize, skew, threshFwd, threshBack, winSize, debounce, minSlice); + server.sync; + indBufNum = server.cachedBufferAt(indBufNum); indBufNum.updateInfo; server.sync; + action.value(indBufNum); + }; } } diff --git a/release-packaging/Classes/FluidBufTransients.sc b/release-packaging/Classes/FluidBufTransients.sc index 37dfbad..9c6bf7f 100644 --- a/release-packaging/Classes/FluidBufTransients.sc +++ b/release-packaging/Classes/FluidBufTransients.sc @@ -1,5 +1,5 @@ FluidBufTransients { - *process { arg server, srcBufNum, startAt = 0, nFrames = -1, startChan = 0, nChans = -1, transBufNum, resBufNum, order = 20, blockSize = 256, padSize = 128, skew = 0, threshFwd = 2, threshBack = 1.1, winSize = 14, debounce = 25; + *process { arg server, srcBufNum, startAt = 0, nFrames = -1, startChan = 0, nChans = -1, transBufNum, resBufNum, order = 20, blockSize = 256, padSize = 128, skew = 0, threshFwd = 2, threshBack = 1.1, winSize = 14, debounce = 25, action; srcBufNum = srcBufNum.asUGenInput; transBufNum = transBufNum.asUGenInput; @@ -11,6 +11,12 @@ FluidBufTransients { transBufNum = transBufNum ? -1; resBufNum = resBufNum ? -1; - server.sendMsg(\cmd, \BufTransients, srcBufNum, startAt, nFrames, startChan, nChans, transBufNum, resBufNum, order, blockSize, padSize, skew, threshFwd, threshBack, winSize, debounce); + forkIfNeeded{ + server.sendMsg(\cmd, \BufTransients, srcBufNum, startAt, nFrames, startChan, nChans, transBufNum, resBufNum, order, blockSize, padSize, skew, threshFwd, threshBack, winSize, debounce); + server.sync; + if (transBufNum != -1) {transBufNum = server.cachedBufferAt(transBufNum); transBufNum.updateInfo; server.sync;} {transBufNum = nil}; + if (resBufNum != -1) {resBufNum = server.cachedBufferAt(resBufNum); resBufNum.updateInfo;server.sync;} {resBufNum = nil}; + action.value(transBufNum,resBufNum); + }; } } diff --git a/release-packaging/HelpSource/Classes/FluidBufCompose.schelp b/release-packaging/HelpSource/Classes/FluidBufCompose.schelp index 3d82808..873efd1 100644 --- a/release-packaging/HelpSource/Classes/FluidBufCompose.schelp +++ b/release-packaging/HelpSource/Classes/FluidBufCompose.schelp @@ -53,6 +53,9 @@ ARGUMENT:: dstStartChan ARGUMENT:: dstGain The gain applied to the samples in the region of the destination buffer over which the source is to be copied. The default value of 0. would overwrite completely, and a value of 1.0 would sum the source to the material that was present. +ARGUMENT:: action + A Function to be evaluated once the offline process has finished and dstBufNum instance variables have been updated on the client side. The function will be passed dstBufNum as an argument. + RETURNS:: Nothing, as the various destination buffers are declared in the function call. diff --git a/release-packaging/HelpSource/Classes/FluidBufHPSS.schelp b/release-packaging/HelpSource/Classes/FluidBufHPSS.schelp index 786f9fe..20db545 100644 --- a/release-packaging/HelpSource/Classes/FluidBufHPSS.schelp +++ b/release-packaging/HelpSource/Classes/FluidBufHPSS.schelp @@ -103,10 +103,12 @@ ARGUMENT:: hopSize ARGUMENT:: fftSize The inner FFT/IFFT size. It should be at least 4 samples long; at least the size of the window; and a power of 2. Making it larger than the window size provides interpolation in frequency. +ARGUMENT:: action + A Function to be evaluated once the offline process has finished and all Buffer's instance variables have been updated on the client side. The function will be passed [harmBufNum, percBufNum, resBufNum] as an argument. + RETURNS:: Nothing, as the various destination buffers are declared in the function call. - Discussion:: HPSS works by using median filters on the spectral magnitudes of a sound. It hinges on a simple modelling assumption that tonal components will tend to yield concentrations of energy across time, spread out in frequency, and percussive components will manifest as concentrations of energy across frequency, spread out in time. By using median filters across time and frequency respectively, we get initial esitmates of the tonal-ness / transient-ness of a point in time and frequency. These are then combined into 'masks' that are applied to the orginal spectral data in order to produce a separation. diff --git a/release-packaging/HelpSource/Classes/FluidBufNMF.schelp b/release-packaging/HelpSource/Classes/FluidBufNMF.schelp index b5e60bf..4a84616 100644 --- a/release-packaging/HelpSource/Classes/FluidBufNMF.schelp +++ b/release-packaging/HelpSource/Classes/FluidBufNMF.schelp @@ -105,6 +105,9 @@ ARGUMENT:: winType ARGUMENT:: randSeed The NMF process needs to seed its starting point. If specified, the same values will be used. The default of -1 will randomly assign them. (not implemented yet) +ARGUMENT:: action + A Function to be evaluated once the offline process has finished and all Buffer's instance variables have been updated on the client side. The function will be passed [dstBufNum, dictBufNum, actBufNum] as an argument. + RETURNS:: Nothing, as the various destination buffers are declared in the function call. diff --git a/release-packaging/HelpSource/Classes/FluidBufNoveltySlice.schelp b/release-packaging/HelpSource/Classes/FluidBufNoveltySlice.schelp index b9ac84f..4d992b3 100644 --- a/release-packaging/HelpSource/Classes/FluidBufNoveltySlice.schelp +++ b/release-packaging/HelpSource/Classes/FluidBufNoveltySlice.schelp @@ -54,6 +54,9 @@ ARGUMENT:: hopSize ARGUMENT:: fftSize The inner FFT/IFFT size. It should be at least 4 samples long, at least the size of the window, and a power of 2. Making it larger allows an oversampling of the spectral precision. +ARGUMENT:: action + A Function to be evaluated once the offline process has finished and indBufNum instance variables have been updated on the client side. The function will be passed indBufNum as an argument. + RETURNS:: Nothing, as the various destination buffers are declared in the function call. diff --git a/release-packaging/HelpSource/Classes/FluidBufSines.schelp b/release-packaging/HelpSource/Classes/FluidBufSines.schelp index 80cf39e..812787a 100644 --- a/release-packaging/HelpSource/Classes/FluidBufSines.schelp +++ b/release-packaging/HelpSource/Classes/FluidBufSines.schelp @@ -66,6 +66,9 @@ ARGUMENT:: hopSize ARGUMENT:: fftSize The inner FFT/IFFT size. It should be at least 4 samples long, at least the size of the window, and a power of 2. Making it larger allows an oversampling of the spectral precision. +ARGUMENT:: action + A Function to be evaluated once the offline process has finished and all Buffer's instance variables have been updated on the client side. The function will be passed [sineBufNum, resBufNum] as an argument. + RETURNS:: Nothing, as the various destination buffers are declared in the function call. diff --git a/release-packaging/HelpSource/Classes/FluidBufTransientSlice.schelp b/release-packaging/HelpSource/Classes/FluidBufTransientSlice.schelp index 87a4a51..869b062 100644 --- a/release-packaging/HelpSource/Classes/FluidBufTransientSlice.schelp +++ b/release-packaging/HelpSource/Classes/FluidBufTransientSlice.schelp @@ -63,6 +63,9 @@ ARGUMENT:: debounce ARGUMENT:: minSlice The minimum duration of a slice in samples. +ARGUMENT:: action + A Function to be evaluated once the offline process has finished and indBufNum instance variables have been updated on the client side. The function will be passed indBufNum as an argument. + RETURNS:: Nothing, as the destination buffer is declared in the function call. diff --git a/release-packaging/HelpSource/Classes/FluidBufTransients.schelp b/release-packaging/HelpSource/Classes/FluidBufTransients.schelp index ad43671..c0ebc2d 100644 --- a/release-packaging/HelpSource/Classes/FluidBufTransients.schelp +++ b/release-packaging/HelpSource/Classes/FluidBufTransients.schelp @@ -68,6 +68,9 @@ ARGUMENT:: winSize ARGUMENT:: debounce The window size in sample within which positive detections will be clumped together to avoid overdetecting in time. +ARGUMENT:: action + A Function to be evaluated once the offline process has finished and all Buffer's instance variables have been updated on the client side. The function will be passed [transBufNum, resBufNum] as an argument. + RETURNS:: Nothing, as the various destination buffers are declared in the function call.