diff --git a/doc/AmpSlice.rst b/doc/AmpSlice.rst index 58a7686..a2b34b3 100644 --- a/doc/AmpSlice.rst +++ b/doc/AmpSlice.rst @@ -7,7 +7,7 @@ :discussion: FluidAmpSlice is based on two envelop followers on a highpassed version of the signal: one slow that gives the trend, and one fast. Each have features that will interact. The example code below is unfolding the various possibilites in order of complexity. - The process will return an audio steam with sample-long impulses at estimated starting points of the different slices. + The process will return an audio steam with single sample impulses at estimated starting points of the different slices. :output: An audio stream with square envelopes around the slices. The latency between the input and the output is **max(minLengthAbove + lookBack, max(minLengthBelow,lookAhead))**. diff --git a/doc/BufTransientSlice.rst b/doc/BufTransientSlice.rst index 738de91..12a10e8 100644 --- a/doc/BufTransientSlice.rst +++ b/doc/BufTransientSlice.rst @@ -5,75 +5,75 @@ :see-also: TransientSlice, BufOnsetSlice, BufNoveltySlice :description: Transient-based slice extractor on buffers :discussion: - This relies on the same algorithm as BufTransients using clicks/transients/derivation/anomalies in the signal to estimate the slicing points. - The process will return a buffer which contains indices (in sample) of estimated starting points of the different slices. + BufTransientSlice identifies slice points in a buffer by implementing a "de-clicking" algorithm based on the assumption that a transient is a sample or series of samples that are anomalous when compared to surrounding samples. It creates a model of the time series of samples, so that when a given sample doesn't fit the model (its "error" or anomalous-ness goes above ``threshFwd``) it is determined to be a transient and a slice point is identified. + + The series of samples determined to be a transient will continue until the error goes below ``threshBack``, indicating that the samples are again more in-line with the model. + + The process will return an ``indices`` buffer which contains the indices (in samples) of estimated starting points of the different slices. + + The algorithm implemented is from chapter 5 of "Digital Audio Restoration" by Godsill, Simon J., Rayner, Peter J.W. with some bespoke improvements on the detection function tracking. :process: This is the method that calls for the slicing to be calculated on a given source buffer. :output: Nothing, as the destination buffer is declared in the function call. - :control source: - The index of the buffer to use as the source material to be sliced through transient identification. The different channels of multichannel buffers will be summed. + The |buffer| to use as the source material to detect transients in. The different channels of multichannel buffers will be summed. :control startFrame: - Where in the srcBuf should the slicing process start, in sample. + Where in ``source`` the process should begin, in samples. The default is 0. :control numFrames: - How many frames should be processed. + How many frames of ``source`` should be process. The default of -1 indicates to process through the end of the buffer. :control startChan: - For multichannel srcBuf, which channel should be processed. + For multichannel ``source``, which channel to begin processing from. :control numChans: - For multichannel srcBuf, how many channel should be summed. + For multichannel ``source``, how many channels to process. The default of -1 indicates to process through the last channel in the buffer. Multichannel analyses are summed to mono before processing. :control indices: - The index of the buffer where the indices (in sample) of the estimated starting points of slices will be written. The first and last points are always the boundary points of the analysis. + The buffer where the indices (in samples) of the estimated starting points of slices will be written. :control order: - The order in samples of the impulse response filter used to model the estimated continuous signal. It is how many previous samples are used by the algorithm to predict the next one as reference for the model. The higher the order, the more accurate is its spectral definition, not unlike fft, improving low frequency resolution, but it differs in that it is not conected to its temporal resolution. + The number of previous samples used by the algorithm to create the model of the signal within the ``blockSize`` window of analysis ``order`` must be less than ``blockSize``. :control blockSize: - The size in samples of frame on which it the algorithm is operating. High values are more cpu intensive, and also determines the maximum transient size, which will not be allowed to be more than half that lenght in size. + The size of audio chunk (in samples) on which the process is operating. This determines the maximum duration (in samples) of a detected transient, which cannot be more than than half of ``blockSize - order``. :control padSize: - The size of the handles on each sides of the block simply used for analysis purpose and avoid boundary issues. + The size (in samples) of analysis on each side of ``blockSize`` used to provide some historical context for analysis so that each ``blockSize`` isn't modelled completely independently of its predecessor. :control skew: - The nervousness of the bespoke detection function with values from -10 to 10. It allows to decide how peaks are amplified or smoothed before the thresholding. High values increase the sensitivity to small variations. + The nervousness of the bespoke detection function. It ranges from -10 to 10 (it has no units) representing the strength and direction of some nonlinearity applied to the detection signal which controls how peaks are amplified or smoothed before the thresholding. Positive values increase the sensitivity to small variations. :control threshFwd: - The threshold of the onset of the smoothed error function. It allows tight start of the identification of the anomaly as it proceeds forward. + The threshold applied to the smoothed forward prediction error for determining an onset. The units are roughly in standard deviations, thus can be considered how "deviant", or anomalous, the signal must be to be detected as a transient. It allows tight start of the identification of the anomaly as it proceeds forward. :control threshBack: - The threshold of the offset of the smoothed error function. As it proceeds backwards in time, it allows tight ending of the identification of the anomaly. + The threshold applied to the smoothed backward prediction error for determining an offset. The units are roughly in standard deviations, thus can be considered how "deviant", or anomalous, the signal must be to be considered transient. When the smoothed error function goes below ``threshBack`` an offset is identified. As it proceeds backwards in time, it allows tight ending of the identification of the anomaly. :control windowSize: - The averaging window of the error detection function. It needs smoothing as it is very jittery. The longer the window, the less precise, but the less false positives. + The averaging window of the error detection function. It needs smoothing as it is very jittery. The longer the window, the less precise, but the less false positive. :control clumpLength: - The window size in sample within which positive detections will be clumped together to avoid overdetecting in time. + The window size in samples within which anomalous samples will be clumped together to avoid over detecting in time. This is similar to setting a minimum slice length. :control minSliceLength: The minimum duration of a slice in samples. - -:control action: - - A Function to be evaluated once the offline process has finished and indices instance variables have been updated on the client side. The function will be passed indices as an argument. - + diff --git a/doc/BufTransients.rst b/doc/BufTransients.rst index 099370a..d342474 100644 --- a/doc/BufTransients.rst +++ b/doc/BufTransients.rst @@ -3,81 +3,78 @@ :sc-categories: Libraries>FluidDecomposition, UGens>Buffer :sc-related: Guides/FluidCorpusManipulationToolkit :see-also: Transients, BufHPSS, BufSines -:description: A transient extractor on buffers +:description: Separate Transients from a Signal in a Buffer :discussion: - It implements declicking algorithm from chapter 5 of 'Digital Audio Restoration' by Godsill, Simon J., Rayner, Peter J.W. with some bespoke improvements on the detection function tracking. - The algorithm will take a buffer in, and will divide it in two outputs: - * the transients, estimated from the signal and extracted from it; - * the remainder of the material, as estimated by the algorithm. + This implements a "de-clicking" algorithm based on the assumption that a transient is a sample or series of samples that are anomalous when compared to surrounding samples. It creates a model of the time series of samples, so that when a given sample doesn't fit the model (its "error" or anomalous-ness goes above ``threshFwd``) it is determined to be a transient. The series of samples determined to be a transient will continue until the error goes below ``threshBack``, indicating that the samples are again more in-line with the model. + + The algorithm then estimates what should have happened during the transient period if the signal had followed its non-anomalous path, and resynthesises this estimate to create the residual output. The transient output is ``input signal - residual signal``, such that summed output of the object (``transients + residual``) can still null-sum with the input. - The whole process is based on the assumption that a transient is an element that is deviating from the surrounding material, as sort of click or anomaly. The algorithm then estimates what should have happened if the signal had followed its normal path, and resynthesises this estimate, removing the anomaly which is considered as the transient. + The algorithm will return two outputs: + * the transients, estimated from the signal and extracted from it + * the residual of the material with the transients replaced with an estimate. + + The algorithm implemented is from chapter 5 of "Digital Audio Restoration" by Godsill, Simon J., Rayner, Peter J.W. with some bespoke improvements on the detection function tracking. :process: This is the method that calls for the transient extraction to be performed on a given source buffer. :output: Nothing, as the various destination buffers are declared in the function call. - :control source: - The index of the buffer to use as the source material to be decomposed through the NMF process. The different channels of multichannel buffers will be processing sequentially. + The |buffer| to use as the source material to detect transients in. The different channels of multichannel buffers will be processing sequentially. :control startFrame: - Where in the srcBuf should the NMF process start, in sample. + Where in ``source`` the process should begin, in samples. The default is 0. :control numFrames: - How many frames should be processed. + How many frames of ``source`` should be process. The default of -1 indicates to process through the end of the buffer. :control startChan: - For multichannel srcBuf, which channel should be processed first. + For multichannel ``source``, which channel to begin processing from. :control numChans: - For multichannel srcBuf, how many channel should be processed. + For multichannel ``source``, how many channels to process. The default of -1 indicates to process through the last channel in the buffer. :control transients: - The index of the buffer where the extracted transient component will be reconstructed. + The buffer where the extracted transients component will written. :control residual: - The index of the buffer where the estimated continuous component will be reconstructed. + The buffer where the residual component with the transients replaced by estimates will be written. :control order: - The order in samples of the impulse response filter used to model the estimated continuous signal. It is how many previous samples are used by the algorithm to predict the next one as reference for the model. The higher the order, the more accurate is its spectral definition, not unlike fft, improving low frequency resolution, but it differs in that it is not conected to its temporal resolution. + The number of previous samples used by the algorithm to create the model of the signal within the ``blockSize`` window of analysis ``order`` must be less than ``blockSize``. :control blockSize: - The size in samples of frame on which it the algorithm is operating. High values are more cpu intensive, and also determines the maximum transient size, which will not be allowed to be more than half that lenght in size. + The size of audio chunk (in samples) on which the process is operating. This determines the maximum duration (in samples) of a detected transient, which cannot be more than than half of ``blockSize - order``. :control padSize: - The size of the handles on each sides of the block simply used for analysis purpose and avoid boundary issues. + The size (in samples) of analysis on each side of ``blockSize`` used to provide some historical context for analysis so that each ``blockSize`` isn't modelled completely independently of its predecessor. :control skew: - The nervousness of the bespoke detection function with values from -10 to 10. It allows to decide how peaks are amplified or smoothed before the thresholding. High values increase the sensitivity to small variations. + The nervousness of the bespoke detection function. It ranges from -10 to 10 (it has no units) representing the strength and direction of some nonlinearity applied to the detection signal which controls how peaks are amplified or smoothed before the thresholding. High values increase the sensitivity to small variations. :control threshFwd: - The threshold of the onset of the smoothed error function. It allows tight start of the identification of the anomaly as it proceeds forward. + The threshold applied to the smoothed forward prediction error for determining an onset. The units are roughly in standard deviations, thus can be considered how "deviant", or anomalous, the signal must be to be detected as a transient. It allows tight start of the identification of the anomaly as it proceeds forward. :control threshBack: - The threshold of the offset of the smoothed error function. As it proceeds backwards in time, it allows tight ending of the identification of the anomaly. + The threshold applied to the smoothed backward prediction error for determining an offset. The units are roughly in standard deviations, thus can be considered how "deviant", or anomalous, the signal must be to be considered transient. When the smoothed error function goes below ``threshBack`` an offset is identified. As it proceeds backwards in time, it allows tight ending of the identification of the anomaly. :control windowSize: - The averaging window of the error detection function. It needs smoothing as it is very jittery. The longer the window, the less precise, but the less false positive. + The averaging window of the error detection function. It needs smoothing as it is very jittery. The longer the window, the less precise, but the less false positive. :control clumpLength: - The window size in sample within which positive detections will be clumped together to avoid overdetecting in time. - -:control 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 [transients, residual] as an argument. - + The window size in samples within which anomalous samples will be clumped together to avoid over detecting in time. This is like setting a minimum transient length. diff --git a/doc/NoveltySlice.rst b/doc/NoveltySlice.rst index 7faef63..fb9cf57 100644 --- a/doc/NoveltySlice.rst +++ b/doc/NoveltySlice.rst @@ -7,7 +7,7 @@ :discussion: A novelty curve is derived from running a kernel across the diagonal of the similarity matrix, and looking for peak of changes. It implements the algorithm published in 'Automatic Audio Segmentation Using a Measure of Audio Novelty' by J Foote. - The process will return an audio steam with sample-long impulses at estimated starting points of the different slices. + The process will return an audio steam with single sample impulses at estimated starting points of the different slices. :output: An audio stream with impulses at detected transients. The latency between the input and the output is hopSize * (((kernelSize+1)/2).asInteger + ((filterSize + 1) / 2).asInteger + 1) samples at maximum. diff --git a/doc/TransientSlice.rst b/doc/TransientSlice.rst index 4b6dd21..7da3278 100644 --- a/doc/TransientSlice.rst +++ b/doc/TransientSlice.rst @@ -5,13 +5,17 @@ :see-also: BufTransientSlice, AmpSlice, NoveltySlice, OnsetSlice :description: A real-time transient-based slice extractor :discussion: - This uses same algorithm as BufTransients using clicks/transients/derivation/anomaly in the signal to estimate the slicing points. - The process will return an audio steam with sample-long impulses at estimated starting points of the different slices. + TransientSlice identifies slice points in a real time signal by implementing a "de-clicking" algorithm based on the assumption that a transient is a sample or series of samples that are anomalous when compared to surrounding samples. It creates a model of the time series of samples, so that when a given sample doesn't fit the model (its "error" or anomalous-ness goes above ``threshFwd``) it is determined to be a transient and a slice point is identified. -:process: The audio rate version of the object. -:output: An audio stream with impulses at detected transients. The latency between the input and the output is (blockSize + padSize - order) samples. + The series of samples determined to be a transient will continue until the error goes below ``threshBack``, indicating that the samples are again more in-line with the model. + + The process will return an audio steam with single sample impulses at estimated starting points of the different slices. + The algorithm implemented is from chapter 5 of "Digital Audio Restoration" by Godsill, Simon J., Rayner, Peter J.W. with some bespoke improvements on the detection function tracking. + +:process: The audio rate version of the object. +:output: An audio stream with impulses at detected transients. The latency between the input and the output is ``(blockSize + padSize - order)`` samples. :control in: @@ -19,37 +23,36 @@ :control order: - The order in samples of the impulse response filter used to model the estimated continuous signal. It is how many previous samples are used by the algorithm to predict the next one as reference for the model. The higher the order, the more accurate is its spectral definition, not unlike fft, improving low frequency resolution, but it differs in that it is not connected to its temporal resolution. + The number of previous samples used by the algorithm to create the model of the signal within the ``blockSize`` window of analysis ``order`` must be less than ``blockSize``. :control blockSize: - The size in samples of frame on which it the algorithm is operating. High values are more cpu intensive, and also determines the maximum transient size, which will not be allowed to be more than half that length in size. + The size of audio chunk (in samples) on which the process is operating. This determines the maximum duration (in samples) of a detected transient, which cannot be more than than half of ``blockSize - order``. High values are more cpu intensive. :control padSize: - The size of the handles on each sides of the block simply used for analysis purpose and avoid boundary issues. + The size (in samples) of analysis on each side of ``blockSize`` used to provide some historical context for analysis so that each ``blockSize`` isn't modelled completely independently of its predecessor. :control skew: - The nervousness of the bespoke detection function with values from -10 to 10. It allows to decide how peaks are amplified or smoothed before the thresholding. High values increase the sensitivity to small variations. + The nervousness of the bespoke detection function. It ranges from -10 to 10 (it has no units) representing the strength and direction of some nonlinearity applied to the detection signal which controls how peaks are amplified or smoothed before the thresholding. High values increase the sensitivity to small variations. :control threshFwd: - The threshold of the onset of the smoothed error function. It allows tight start of the identification of the anomaly as it proceeds forward. + The threshold applied to the smoothed forward prediction error for determining an onset. The units are roughly in standard deviations, thus can be considered how "deviant", or anomalous, the signal must be to be detected as a transient. It allows tight start of the identification of the anomaly as it proceeds forward. :control threshBack: - The threshold of the offset of the smoothed error function. As it proceeds backwards in time, it allows tight ending of the identification of the anomaly. + The threshold applied to the smoothed backward prediction error for determining an offset. The units are roughly in standard deviations, thus can be considered how "deviant", or anomalous, the signal must be to be considered transient. When the smoothed error function goes below ``threshBack`` an offset is identified. As it proceeds backwards in time, it allows tight ending of the identification of the anomaly. :control windowSize: - The averaging window of the error detection function. It needs smoothing as it is very jittery. The longer the window, the less precise, but the less false positives. + The averaging window of the error detection function. It needs smoothing as it is very jittery. The longer the window, the less precise, but the less false positive. :control clumpLength: - The window size in sample within with positive detections will be clumped together to avoid overdetecting in time. + The window size in samples within which anomalous samples will be clumped together to avoid over detecting in time. This is similar to setting a minimum slice length. :control minSliceLength: The minimum duration of a slice in samples. - diff --git a/doc/Transients.rst b/doc/Transients.rst index 4bf8938..c35385e 100644 --- a/doc/Transients.rst +++ b/doc/Transients.rst @@ -3,19 +3,21 @@ :sc-categories: Libraries>FluidDecomposition :sc-related: Guides/FluidCorpusManipulationToolkit :see-also: BufTransients,Sines,HPSS -:description: A real-time transient modeller on its input. +:description: Separate transients from a signal. :discussion: - It implements declicking algorithm from chapter 5 of "Digital Audio Restoration" by Godsill, Simon J., Rayner, Peter J.W. with some bespoke improvements on the detection function tracking. - The algorithm will take an audio in, and will divide it in two outputs: - * the transients, estimated from the signal and extracted from it; - * the remainder of the material, as estimated by the algorithm. - - The whole process is based on the assumption that a transient is an element that is deviating from the surrounding material, as sort of click or anomaly. The algorithm then estimates what should have happened if the signal had followed its normal path, and resynthesises this estimate, removing the anomaly which is considered as the transient. + This implements a "de-clicking" algorithm based on the assumption that a transient is a sample or series of samples that are anomalous when compared to surrounding samples. It creates a model of the time series of samples, so that when a given sample doesn't fit the model (its "error" or anomalous-ness goes above ``threshFwd``) it is determined to be a transient. The series of samples determined to be a transient will continue until the error goes below ``threshBack``, indicating that the samples are again more in-line with the model. + + The algorithm then estimates what should have happened during the transient period if the signal had followed its non-anomalous path, and resynthesises this estimate to create the residual output. The transient output is ``input signal - residual signal``, such that summed output of the object (``transients + residual``) can still null-sum with the input. + The algorithm will take an audio in, and will divide it in two outputs: + * the transients, estimated from the signal and extracted from it + * the residual of the material with the transients replaced with an estimate. + + The algorithm implemented is from chapter 5 of "Digital Audio Restoration" by Godsill, Simon J., Rayner, Peter J.W. with some bespoke improvements on the detection function tracking. + :process: The audio rate version of the object. -:output: An array of two audio streams: [0] is the transient extracted, [1] is the rest. The latency between the input and the output is (blockSize + padSize - order) samples. - +:output: An array of two audio streams: [0] is the transient extracted, [1] is the rest. The latency between the input and the output is ``((blockSize + padSize) - order)`` samples. :control in: @@ -23,27 +25,27 @@ :control order: - The order in samples of the impulse response filter used to model the estimated continuous signal. It is how many previous samples are used by the algorithm to predict the next one as reference for the model. The higher the order, the more accurate is its spectral definition, not unlike fft, improving low frequency resolution, but it differs in that it is not conected to its temporal resolution. + The number of previous samples used by the algorithm to create the model of the signal within the ``blockSize`` window of analysis ``order`` must be less than ``blockSize``. :control blockSize: - The size in samples of frame on which it the algorithm is operating. High values are more cpu intensive, and also determines the maximum transient size, which will not be allowed to be more than half that lenght in size. + The size of audio chunk (in samples) on which the process is operating. This determines the maximum duration (in samples) of a detected transient, which cannot be more than than half of ``blockSize - order``. High values are more cpu intensive. :control padSize: - The size of the handles on each sides of the block simply used for analysis purpose and avoid boundary issues. + The size (in samples) of analysis on each side of ``blockSize`` used to provide some historical context for analysis so that each ``blockSize`` isn't modelled completely independently of its predecessor. :control skew: - The nervousness of the bespoke detection function with values from -10 to 10. It allows to decide how peaks are amplified or smoothed before the thresholding. High values increase the sensitivity to small variations. + The nervousness of the bespoke detection function. It ranges from -10 to 10 (it has no units) representing the strength and direction of some nonlinearity applied to the detection signal which controls how peaks are amplified or smoothed before the thresholding. High values increase the sensitivity to small variations. :control threshFwd: - The threshold of the onset of the smoothed error function. It allows tight start of the identification of the anomaly as it proceeds forward. + The threshold applied to the smoothed forward prediction error for determining an onset. The units are roughly in standard deviations, thus can be considered how "deviant", or anomalous, the signal must be to be detected as a transient. It allows tight start of the identification of the anomaly as it proceeds forward. :control threshBack: - The threshold of the offset of the smoothed error function. As it proceeds backwards in time, it allows tight ending of the identification of the anomaly. + The threshold applied to the smoothed backward prediction error for determining an offset. The units are roughly in standard deviations, thus can be considered how "deviant", or anomalous, the signal must be to be considered transient. When the smoothed error function goes below ``threshBack`` an offset is identified. As it proceeds backwards in time, it allows tight ending of the identification of the anomaly. :control windowSize: @@ -51,5 +53,4 @@ :control clumpLength: - The window size in sample within which positive detections will be clumped together to avoid overdetecting in time. - + The window size in samples within which anomalous samples will be clumped together to avoid over detecting in time. This is like setting a minimum transient length. diff --git a/example-code/sc/BufTransientSlice.scd b/example-code/sc/BufTransientSlice.scd index 90b3a56..b1afb1a 100644 --- a/example-code/sc/BufTransientSlice.scd +++ b/example-code/sc/BufTransientSlice.scd @@ -1,73 +1,26 @@ code:: -// load some buffers -( -b = Buffer.read(s,FluidFilesPath("Tremblay-AaS-SynthTwoVoices-M.wav")); -c = Buffer.new(s); -) - -// with basic parameters (wait for the computation time to appear) -( - Routine{ - t = Main.elapsedTime; - FluidBufTransientSlice.process(s,b, indices:c).wait; - (Main.elapsedTime - t).postln; -}.play -) - -//check the number of slices -c.query; -//loops over a splice -( -{ - BufRd.ar(1, b, - Phasor.ar(0,1, - BufRd.kr(1, c, - MouseX.kr(0, BufFrames.kr(c) - 1), 0, 1), - BufRd.kr(1, c, - MouseX.kr(1, BufFrames.kr(c)), 0, 1), - BufRd.kr(1,c, - MouseX.kr(0, BufFrames.kr(c) - 1), 0, 1)), 0, 1); - }.play; -) +~src = Buffer.read(s,FluidFilesPath("Tremblay-AaS-SynthTwoVoices-M.wav")); -// with everything changed to make it much better, at the cost of computation time (only 5 seconds are processed here, again wait for the (longer) computation time to appear) +// slice with basic parameters ( -Routine{ - t = Main.elapsedTime; - FluidBufTransientSlice.process(s,b, 0, 220500, 0, 1, c, 200, 2048, 1024, 1, 3, 1, 15, 30, 4410).wait; - (Main.elapsedTime - t).postln; -}.play +~indices = Buffer(s); +FluidBufTransientSlice.processBlocking(s,~src,indices:~indices,action:{ + "found % slice points".format(~indices.numFrames).postln; + "with an average length of % seconds per slice".format(~src.duration / ~indices.numFrames).postln; +}); ) -// play with the same player above to hear the segmentation difference -:: - -STRONG::A stereo buffer example.:: -CODE:: - -// make a stereo buffer -b = Buffer.alloc(s,88200,2); - -// add some stereo clicks and listen to them -((0..3)*22050+11025).do({|item,index| b.set(item+(index%2), 1.0)}) - -b.play - -// create a new buffer as destinations -c = Buffer.new(s); - -//run the process on them +//loops over a slice from onset to the next slice point using MouseX to choose which ( -// with basic params -Routine{ - t = Main.elapsedTime; - FluidBufTransientSlice.process(s,b, indices: c, threshFwd: 1.2).wait; - (Main.elapsedTime - t).postln; -}.play +{ + var gate_index = MouseX.kr(0,~indices.numFrames-1).poll(label:"slice index"); + var start = BufRd.kr(1,~indices,gate_index,1,1); + var end = BufRd.kr(1,~indices,gate_index+1,1,1); + var phs = Phasor.ar(0,BufRateScale.ir(~src),start,end); + BufRd.ar(1,~src,phs,1,4).dup; +}.play; ) -// list the indicies of detected attacks - the two input channels have been summed -c.getn(0,c.numFrames,{|item|(item*2).postln;}) -:: +:: \ No newline at end of file diff --git a/example-code/sc/BufTransients.scd b/example-code/sc/BufTransients.scd index 9df6c58..c88befc 100644 --- a/example-code/sc/BufTransients.scd +++ b/example-code/sc/BufTransients.scd @@ -1,68 +1,53 @@ code:: + +~src = Buffer.read(s,FluidFilesPath("Tremblay-AaS-SynthTwoVoices-M.wav")); + ( -b = Buffer.read(s,FluidFilesPath("Tremblay-AaS-SynthTwoVoices-M.wav")); -c = Buffer.new(s); -d = Buffer.new(s); +~transients = Buffer(s); +~residual = Buffer(s); +FluidBufTransients.processBlocking(s,~src,transients:~transients,residual:~residual,action:{ + "done".postln; +}); ) -// with basic params +// only transients ( -Routine{ - t = Main.elapsedTime; - FluidBufTransients.process(s,b, transients:c, residual:d).wait; - (Main.elapsedTime - t).postln; -}.play -); - -// wait for the duration to appear in the post window as a cue that the computation is finished -c.play; -d.play; - -//nullsumming tests -{(PlayBuf.ar(1,c))+(PlayBuf.ar(1,d))+(-1*PlayBuf.ar(1,b,doneAction:2))}.play - +{ + var sig = PlayBuf.ar(1,~transients,BufRateScale.ir(~transients),doneAction:2); + sig.dup; +}.play; +) -// with everything changed to make it much better, at the cost of computation time (only 5 seconds are processed here) +// juicy clicks ( -Routine{ - t = Main.elapsedTime; - FluidBufTransients.process(s,b, 0, 220500, 0, 1, c, d, 200, 2048, 1024, 1, 3, 1, 15, 30).wait; - (Main.elapsedTime - t).postln; -}.play +{ + var sig = PlayBuf.ar(1,~transients,BufRateScale.ir(~transients) * 6,doneAction:2); + sig.dup; +}.play; ) -// wait for the duration to appear in the post window as a cue that the computation is finished -c.play; -d.play; -:: - -STRONG::A stereo buffer example.:: -CODE:: - -// load two very different files +// transients removed ( -b = Buffer.read(s,FluidFilesPath("Tremblay-AaS-SynthTwoVoices-M.wav")); -c = Buffer.read(s,FluidFilesPath("Tremblay-AaS-AcousticStrums-M.wav")); +{ + var sig = PlayBuf.ar(1,~residual,BufRateScale.ir(~residual),doneAction:2); + sig.dup; +}.play; ) +:: +strong::Comparing the source to the outputs:: +code:: -// composite one on left one on right as test signals -FluidBufCompose.process(s, c, numFrames:b.numFrames, startFrame:555000, destStartChan:1, destination:b) -b.play - -// create 2 new buffers as destinations -d = Buffer.new(s); e = Buffer.new(s); +~src = Buffer.read(s,FluidFilesPath("Tremblay-AaS-SynthTwoVoices-M.wav")); -//run the process on them ( -Routine{ - t = Main.elapsedTime; - FluidBufTransients.process(s, b, transients: d, residual:e, threshFwd:1.2, clumpLength:40).wait; - (Main.elapsedTime - t).postln; -}.play +~transients = Buffer(s); +~residual = Buffer(s); +~compare = Buffer(s); +FluidBufTransients.processBlocking(s,~src,transients:~transients,residual:~residual,order:18,skew:10,threshFwd:1.1); +FluidBufCompose.processBlocking(s,~src,destination:~compare,destStartChan:0); +FluidBufCompose.processBlocking(s,~transients,destination:~compare,destStartChan:1); +FluidBufCompose.processBlocking(s,~residual,destination:~compare,destStartChan:2); +FluidWaveform(~compare,bounds:Rect(0,0,1600,1200)); ) - -//listen: stereo preserved! -d.play -e.play -:: +:: \ No newline at end of file diff --git a/example-code/sc/TransientSlice.scd b/example-code/sc/TransientSlice.scd index 7ed5a3d..19d01b9 100644 --- a/example-code/sc/TransientSlice.scd +++ b/example-code/sc/TransientSlice.scd @@ -1,23 +1,44 @@ CODE:: //load some sounds -b = Buffer.read(s,FluidFilesPath("Tremblay-AaS-SynthTwoVoices-M.wav")); +~src = Buffer.read(s,FluidFilesPath("Tremblay-AaS-SynthTwoVoices-M.wav")); // basic param (the process add a latency of (blockSize + padSize - order) samples -{var sig = PlayBuf.ar(1,b,loop:1); [FluidTransientSlice.ar(sig) * 0.5, DelayN.ar(sig, 1, ((256 + 128 - 20)/ s.sampleRate))]}.play +( +{ + var sig = PlayBuf.ar(1,~src,BufRateScale.ir(~src),loop:1); + var order = 20; // this is the default + var blockSize = 256; // this is the default + var padSize = 128; // this is the default + var slice_impulses = FluidTransientSlice.ar(sig,order,blockSize,padSize); + sig = DelayN.ar(sig, 1, ((blockSize + padSize) - order) * SampleDur.ir); // compute the latency and delay the original signal + [sig,slice_impulses * -6.dbamp]; +}.play +) // other parameters -{var sig = PlayBuf.ar(1,b,loop:1); [FluidTransientSlice.ar(sig,order:80,minSliceLength:2205) * 0.5, DelayN.ar(sig, 1, ((256 + 128 - 80)/ s.sampleRate))]}.play +( +{ + var sig = PlayBuf.ar(1,~src,BufRateScale.ir(~src),loop:1); + var order = 80; + var blockSize = 256; // this is the default + var padSize = 128; // this is the default + var slice_impulses = FluidTransientSlice.ar(sig,order,blockSize,padSize,minSliceLength:2205); + sig = DelayN.ar(sig, 1, ((blockSize + padSize) - order) * SampleDur.ir); // compute the latency and delay the original signal + [sig,slice_impulses * -6.dbamp]; +}.play +) // More musical, transient-trigged autopan ( { - var sig, trig, syncd, pan; - sig = PlayBuf.ar(1,b,loop:1); - trig = FluidTransientSlice.ar(sig,order:10,minSliceLength:4410); - syncd = DelayN.ar(sig, 1, ((256 + 128 - 20)/ s.sampleRate)); - pan = TRand.ar(-1,1,trig); - Pan2.ar(syncd,pan); + var sig = PlayBuf.ar(1,~src,BufRateScale.ir(~src),loop:1); + var order = 20; // this is the default + var blockSize = 256; // this is the default + var padSize = 128; // this is the default + var slice_impulses = FluidTransientSlice.ar(sig,order,blockSize,padSize); + sig = DelayN.ar(sig, 1, ((blockSize + padSize) - order) * SampleDur.ir); // compute the latency and delay the original signal + Pan2.ar(sig,TRand.ar(-1.0,1.0,slice_impulses).poll); }.play ) :: diff --git a/example-code/sc/Transients.scd b/example-code/sc/Transients.scd index 58396c8..fb43dca 100644 --- a/example-code/sc/Transients.scd +++ b/example-code/sc/Transients.scd @@ -1,14 +1,56 @@ CODE:: -//load some buffer -b = Buffer.read(s,FluidFilesPath("Tremblay-AaS-SynthTwoVoices-M.wav")); -// basic parameters -{FluidTransients.ar(PlayBuf.ar(1, b, loop:1))}.play +~src = Buffer.read(s,FluidFilesPath("Tremblay-AaS-SynthTwoVoices-M.wav")); -// tweaked parameters -{FluidTransients.ar(PlayBuf.ar(1, b, loop:1), 80, threshFwd:MouseX.kr(0,5), threshBack:MouseY.kr(0,2))}.play +// hear the basic parameters: transients in the L channel, residual in the R channel +( +{ + FluidTransients.ar(PlayBuf.ar(1, ~src, loop:1)); +}.play +) -// null test (the process add a latency of (blockSize + padding - order) samples -{var sig = PlayBuf.ar(1, b, loop:1); [FluidTransients.ar(sig).sum - DelayN.ar(sig, 1, ((256 + 128 - 20)/ s.sampleRate))]}.play +// tweaking parameters: listen while adjusting order and skew +( +{ + var sig = PlayBuf.ar(1, ~src, loop:1); + var order = MouseX.kr(10,80).poll(label:"order"); + var skew = MouseY.kr(-10,10).poll(label:"skew"); + FluidTransients.ar(sig,order,skew:skew)[0].dup +}.play; +) + +:: +strong::adding some FX:: +code:: +( +{ + var sig = PlayBuf.ar(1, ~src, loop:1); + var transients, residual; + # transients, residual = FluidTransients.ar(sig); + transients = Pan2.ar(transients,TRand.ar(-1.0,1.0,transients),8.dbamp); + transients = AllpassC.ar(transients,30.reciprocal,TRand.ar(100.reciprocal,30.reciprocal,transients),8); + sig = residual.dup + transients; + sig; +}.play +) +:: +strong::The transients and residual null-sum:: +code:: + +// null test (the process adds a latency of ((blockSize + padding) - order) samples) +// this should be silent! +( +{ + var sig = PlayBuf.ar(1, ~src, loop:1); + var transients, residual, summed; + var order = 20; // this is the default + var blockSize = 256; // this is the default + var padSize = 128; // this is the default; + # transients, residual = FluidTransients.ar(sig,order,blockSize,padSize); + summed = [transients, residual].sum; + sig = DelayN.ar(sig, 1, ((blockSize + padSize) - order) * SampleDur.ir); + sig - summed; +}.play +) ::