diff --git a/fdNMF/tests.scd b/fdNMF/tests.scd index f42996b..0005add 100644 --- a/fdNMF/tests.scd +++ b/fdNMF/tests.scd @@ -1,61 +1,41 @@ - s.reboot //////////////////////////// // test for efficiency ( -b = Buffer.read(s,"/Users/owen/Desktop/denoise_stn/sources/01-mix.wav", numFrames:88200); -// s.sync; -~fft_size = 2048; -~frame_size = 1024; +b = Buffer.read(s,"/Users/pa/Documents/documents@hudd/research/projects/fluid corpus navigation/research/denoise_stn/sources/01-mix.wav"); +c = Buffer.new(s); +x = Buffer.new(s); +y = Buffer.new(s); +~fft_size = 1024; +~frame_size = 512; ~hop_size = 256; ~which_rank = 0; ) -// ( -// c = Buffer.alloc(s,b.numFrames,5); -// x = Buffer.alloc(s,(~fft_size / 2 +1),5); -// y = Buffer.alloc(s,(b.numFrames / ~hop_size + 1) ,5); -// ) - -( -c = Buffer.new(s, numFrames:0, numChannels:1); -x = Buffer.new(s,numFrames:0,numChannels:1); -y = Buffer.new(s,numFrames:0,numChannels:1); -) - - ( // without sources r = Routine{ t = Main.elapsedTime; - FDNMF.nmf(s,b,0,-1,0,-1,c,x,0,y,0,5,100,~frame_size,~hop_size,~fft_size); + FDNMF.nmf(s,b,0,-1,0,-1,nil,x,0,y,0,5,100,~frame_size,~hop_size,~fft_size); s.sync; - u = Main.elapsedTime; - (u-t).postln; + (Main.elapsedTime - t).postln; }.play ); - -c.query -x.query - // with sources ( r = Routine{ t = Main.elapsedTime; - FDNMF.nmf(s,b, 0,-1,0,-1,c,x,0,y,0,5,100,~frame_size,~hop_size,~fft_size); + FDNMF.nmf(s,b, 0,-1,0,-1,c,nil,0,nil,0,5,100,~frame_size,~hop_size,~fft_size); s.sync; - u = Main.elapsedTime; - (u-t).postln; + (Main.elapsedTime - t).postln; }.play ) //look at the dictionaries and activations -x.plot; y.plot; -d.plot; -c.plot; +c.plot;x.plot; y.plot; //null test of the sum of sources {(PlayBuf.ar(5,c.bufnum,doneAction:2).sum)+(-1*PlayBuf.ar(1,b.bufnum,doneAction:2))}.play @@ -82,40 +62,42 @@ c.plot; //play noise through an activation {WhiteNoise.ar(BufRd.kr(5,y.bufnum,Phasor.ar(1,1/~hop_size,0,(b.numFrames / ~hop_size + 1)),0,1)[~which_rank] * 0.01)}.play - //play noise through both activation and filter ( { var chain; - chain = FFT(LocalBuf(~fft_size), WhiteNoise.ar(BufRd.kr(5,d.bufnum,Phasor.ar(1,1/~hop_size,0,(b.numFrames / ~hop_size + 1)),0,1)[~which_rank]*0.15),0.25,1); + chain = FFT(LocalBuf(~fft_size), WhiteNoise.ar(BufRd.kr(5,y.bufnum,Phasor.ar(1,1/~hop_size,0,(b.numFrames / ~hop_size + 1)),0,1)[~which_rank]*0.15),0.25,1); chain = chain.pvcollect(~fft_size, {|mag, phase, index| - [mag * BufRd.kr(5,c.bufnum,DC.kr(index),0,1)[~which_rank]]; + [mag * BufRd.kr(5,x.bufnum,DC.kr(index),0,1)[~which_rank]]; }); [0,IFFT(chain)]; }.play ) - // test with stereo input Buffer.freeAll(s) ( b = Buffer.read(s,"/Users/pa/Desktop/verystereo.wav"); +c = Buffer.new(s); +x = Buffer.new(s); +y = Buffer.new(s); ~fft_size = 1024; ~frame_size = 512; ~hop_size = 256; ) ( -c = Buffer.alloc(s,b.numFrames,10); -x = Buffer.alloc(s,(~fft_size / 2 +1),10); -y = Buffer.alloc(s,(b.numFrames / ~hop_size + 1) ,10); +r = Routine{ + t = Main.elapsedTime; + FDNMF.nmf(s,b,0,-1,0,-1,c,x,0,y,0,5,100,~frame_size,~hop_size,~fft_size); + s.sync; + (Main.elapsedTime - t).postln; +}.play ) -d = Main.elapsedTime; b.fdNMF(c, x, y, 5, 100, ~fft_size,~frame_size,~hop_size,{e = Main.elapsedTime; (e-d).postln}) - -{PlayBuf.ar(10,c.bufnum,doneAction:2)[5].dup}.play +{PlayBuf.ar(10,c.bufnum,doneAction:2)[2].dup}.play c.getn(0, 10, {|x|x.postln}) diff --git a/release-packaging/fdGain/HelpSource/Classes/FDGain.schelp b/release-packaging/fdGain/HelpSource/Classes/FDGain.schelp index 0124754..d930062 100644 --- a/release-packaging/fdGain/HelpSource/Classes/FDGain.schelp +++ b/release-packaging/fdGain/HelpSource/Classes/FDGain.schelp @@ -1,4 +1,46 @@ -//Ar modulator -{FDGain.ar(WhiteNoise.ar,64,SinOsc.ar(2))}.play -//Kr modulator -{FDGain.ar(WhiteNoise.ar,64,SinOsc.kr(2))}.play \ No newline at end of file +class:: FDGain +summary:: Real-Time Gain Changer +categories:: UGens>Algebraic +related::Classes/UnaryOpFunction + +DESCRIPTION:: +A sanity test for the FluCoMa Real-Time Client Wrapper footnote::This was made possible thanks to the FluCoMa project (http://www.flucoma.org/) funded by the European Research Council (https://erc.europa.eu/) under the European Union’s Horizon 2020 research and innovation programme (grant agreement No 725899).:: + +CLASSMETHODS:: + +METHOD:: ar + The audio rate version of the object. + +ARGUMENT:: in + The input to be processed + +ARGUMENT:: frameSize + The size of the real-time i/o buffer. It will add that much latency to the signal. + +ARGUMENT:: gain + Audio or control rate change of the gain. + +returns:: nothing + +INSTANCEMETHODS:: + +METHOD:: checkInputs + This makes sure the value and phase inputs are both at audio rate. + +returns:: + A slap on the wrist, should it not be the case. + + +EXAMPLES:: + Summing with the inverse (gain of -1) with a delay of the latency gives us CPU-expensive silence. + code:: + { var source = PinkNoise.ar(0.1); DelayN.ar(source,delaytime:1000/s.sampleRate) + FDGain.ar(source,1000,-1); }.play + :: + Varying the gain at audio rate. + code:: + { FDGain.ar(PinkNoise.ar(0.1), gain:LFSaw.ar(1)) }.play + :: + Varying the gain at comtrol rate. + code:: + { FDGain.ar(PinkNoise.ar(0.1), gain:LFSaw.kr(0.5)) }.play + :: \ No newline at end of file diff --git a/release-packaging/fdGain/classes/fdGain.sc b/release-packaging/fdGain/classes/fdGain.sc index 8b8358d..938ecf4 100644 --- a/release-packaging/fdGain/classes/fdGain.sc +++ b/release-packaging/fdGain/classes/fdGain.sc @@ -1,6 +1,6 @@ FDGain : UGen { - *ar { arg in = 0, framesize=64, gain=1.0; - ^this.multiNew('audio', in.asAudioRateInput(this),framesize, gain) + *ar { arg in = 0, frameSize=64, gain=1.0; + ^this.multiNew('audio', in.asAudioRateInput(this),frameSize, gain) } } diff --git a/release-packaging/fdNMF/HelpSource/Classes/Buffer.ext.schelp b/release-packaging/fdNMF/HelpSource/Classes/Buffer.ext.schelp deleted file mode 100644 index af3c23c..0000000 --- a/release-packaging/fdNMF/HelpSource/Classes/Buffer.ext.schelp +++ /dev/null @@ -1,27 +0,0 @@ -INSTANCEMETHODS:: - -SUBSECTION:: Fluid Decomposition - -METHOD:: fdNMF -This method does the same as Buffer.waveSetCopyTo - -ARGUMENT:: an arg -The amount by which the values will be multiplied. - -ARGUMENT:: another arg -The amount by which the values will be multiplied. - -DISCUSSION:: - -strong:: Didactic examples::: - -CODE:: -s.boot; - -:: - -strong:: More musical examples::: - -CODE:: -s.boot; -:: \ No newline at end of file diff --git a/release-packaging/fdNMF/HelpSource/Classes/FDNMF.schelp b/release-packaging/fdNMF/HelpSource/Classes/FDNMF.schelp new file mode 100644 index 0000000..7f6eb54 --- /dev/null +++ b/release-packaging/fdNMF/HelpSource/Classes/FDNMF.schelp @@ -0,0 +1,85 @@ +TITLE:: FDNMF +summary:: Non-Negative Matrix Factorisation on Spectral Frames +categories:: Libraries>FluidDecomposition +related:: Overviews/FluCoMa + +DESCRIPTION:: +This Class performs Non-Negative Matrix Factorisation (NMF for short) on buffers on the non-real-time thread. It is a good way to get different components out of a buffered signal. It is part of the Fluid Decomposition Toolkit of the FluCoMa project. footnote:: +This was made possible thanks to the FluCoMa project (http://www.flucoma.org/) funded by the European Research Council (https://erc.europa.eu/) under the European Union’s Horizon 2020 research and innovation programme (grant agreement No 725899).:: + + The algo will take a buffer in, and will divide it in a number of ranks. It can provide back either or all of the following: LIST:: + ## a spectral contour of each rank in the form of a magnitude spectrogramme (called a dictionary in NMF lingo); + ## an amplitude envoloppe of each rank in the form of gains for each consecutive frames of the unterlying FFT (called an activation in NMF lingo) + ## a reconstruction of each rank in audio domain. :: + + The whole process can be related to a vocoder, where each filter is instead a spectrograme of magnitudes (no phase information). More information for musicianly uses of NMF are availabe on this website, and in the LINK::Overviews/FluCoMa:: overview file. + +CLASSMETHODS:: + +METHOD:: nmf +(describe method here) + +ARGUMENT:: server +(describe argument here) + +ARGUMENT:: srcBuf +(describe argument here) + +ARGUMENT:: startAt +(describe argument here) + +ARGUMENT:: nFrames +(describe argument here) + +ARGUMENT:: startChan +(describe argument here) + +ARGUMENT:: nChans +(describe argument here) + +ARGUMENT:: dstBuf +(describe argument here) + +ARGUMENT:: dictBuf +(describe argument here) + +ARGUMENT:: dictFlag +(describe argument here) + +ARGUMENT:: actBuf +(describe argument here) + +ARGUMENT:: actFlag +(describe argument here) + +ARGUMENT:: rank +(describe argument here) + +ARGUMENT:: iterations +(describe argument here) + +ARGUMENT:: sortFlag +(describe argument here) + +ARGUMENT:: windowSize +(describe argument here) + +ARGUMENT:: hopSize +(describe argument here) + +ARGUMENT:: fftSize +(describe argument here) + +returns:: (describe returnvalue here) + + +INSTANCEMETHODS:: + + +EXAMPLES:: + +code:: + b = Buffer.read(s,"../../AudioFiles/01-mix.wav".resolveRelative); +thisProcess.nowExecutingPath + b.play +:: \ No newline at end of file diff --git a/release-packaging/fdNMF/classes/fdfNMF.sc b/release-packaging/fdNMF/classes/fdfNMF.sc index 6f8c650..0509938 100644 --- a/release-packaging/fdNMF/classes/fdfNMF.sc +++ b/release-packaging/fdNMF/classes/fdfNMF.sc @@ -1,25 +1,5 @@ -// adds an instance method to the Buffer class FDNMF { - /*fdNMF { arg dstBuf, dictBuf, actBuf, rank = 1, iterations = 100, fftSize = 2048, windowSize = 2048, hopSize = 512, action; - var resp; - - if(bufnum.isNil) { Error("Cannot call % on a % that has been freed".format(thisMethod.name, this.class.name)).throw }; - -/* // responder idea stolen from getToFloatArray - resp = OSCFunc({ arg msg; - if(msg[1]== '/b_gen' && msg[2]== bufnum, { - resp.clear; - action.value(bufnum); - }); - }, '/done', server.addr);*/ - - // server.listSendMsg([\b_gen, bufnum, "BufNMF", if(dstBuf.isNil, -1, {dstBuf.bufnum}), if(dictBuf.isNil, -1, {dictBuf.bufnum}), if(actBuf.isNil, -1, {actBuf.bufnum}), rank, iterations, fftSize, windowSize, hopSize]) - server.sendMsg(\cmd, \BufNMF, bufnum, if(dstBuf.isNil, -1, {dstBuf.bufnum}), if(dictBuf.isNil, -1, {dictBuf.bufnum}), if(actBuf.isNil, -1, {actBuf.bufnum}), rank, iterations, fftSize, windowSize, hopSize); - - }*/ - - - *nmf { arg server, srcBuf, startAt = 0, nFrames = -1,startChan = 0,nChans = -1, dstBuf, dictBuf, dictFlag = 0, actBuf, actFlag = 0, rank = 1, iterations = 100, windowSize = 2048, hopSize = 512, fftSize = 2048, action; + *nmf { arg server, srcBuf, startAt = 0, nFrames = -1,startChan = 0,nChans = -1, dstBuf, dictBuf, dictFlag = 0, actBuf, actFlag = 0, rank = 1, iterations = 100, sortFlag = 0, windowSize = 2048, hopSize = 512, fftSize = -1 ; var resp; server = server ? Server.default; @@ -29,15 +9,11 @@ FDNMF { dstBuf.bufnum.postln; server.sendMsg(\cmd, \BufNMF, - if(srcBuf.isNil, -1, {srcBuf.bufnum}), - startAt, nFrames, startChan, nChans, - if(dstBuf.isNil, -1, {dstBuf.bufnum}), - if(dictBuf.isNil, -1, {dictBuf.bufnum}), - dictFlag, - if(actBuf.isNil, -1, {actBuf.bufnum}), - actFlag, - rank, iterations, windowSize, hopSize,fftSize); + srcBuf.bufnum, startAt, nFrames, startChan, nChans, + if(dstBuf.isNil, -1, {dstBuf.bufnum}), + if(dictBuf.isNil, -1, {dictBuf.bufnum}), + dictFlag, + if(actBuf.isNil, -1, {actBuf.bufnum}), + actFlag, rank, iterations, windowSize, hopSize,fftSize); } - - }