Corrected interface of FDGain and FDNMF, updated test code, and designed helpfile for FDGain (and started on FDNMF's)

nix
Pierre Alexandre Tremblay 7 years ago
parent 26d637ca98
commit a34cbe6afd

@ -1,61 +1,41 @@
s.reboot s.reboot
//////////////////////////// ////////////////////////////
// test for efficiency // test for efficiency
( (
b = Buffer.read(s,"/Users/owen/Desktop/denoise_stn/sources/01-mix.wav", numFrames:88200); b = Buffer.read(s,"/Users/pa/Documents/documents@hudd/research/projects/fluid corpus navigation/research/denoise_stn/sources/01-mix.wav");
// s.sync; c = Buffer.new(s);
~fft_size = 2048; x = Buffer.new(s);
~frame_size = 1024; y = Buffer.new(s);
~fft_size = 1024;
~frame_size = 512;
~hop_size = 256; ~hop_size = 256;
~which_rank = 0; ~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 // without sources
r = Routine{ r = Routine{
t = Main.elapsedTime; 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; s.sync;
u = Main.elapsedTime; (Main.elapsedTime - t).postln;
(u-t).postln;
}.play }.play
); );
c.query
x.query
// with sources // with sources
( (
r = Routine{ r = Routine{
t = Main.elapsedTime; 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; s.sync;
u = Main.elapsedTime; (Main.elapsedTime - t).postln;
(u-t).postln;
}.play }.play
) )
//look at the dictionaries and activations //look at the dictionaries and activations
x.plot; y.plot; c.plot;x.plot; y.plot;
d.plot;
c.plot;
//null test of the sum of sources //null test of the sum of sources
{(PlayBuf.ar(5,c.bufnum,doneAction:2).sum)+(-1*PlayBuf.ar(1,b.bufnum,doneAction:2))}.play {(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 //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 {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 //play noise through both activation and filter
( (
{ {
var chain; 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| 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)]; [0,IFFT(chain)];
}.play }.play
) )
// test with stereo input // test with stereo input
Buffer.freeAll(s) Buffer.freeAll(s)
( (
b = Buffer.read(s,"/Users/pa/Desktop/verystereo.wav"); b = Buffer.read(s,"/Users/pa/Desktop/verystereo.wav");
c = Buffer.new(s);
x = Buffer.new(s);
y = Buffer.new(s);
~fft_size = 1024; ~fft_size = 1024;
~frame_size = 512; ~frame_size = 512;
~hop_size = 256; ~hop_size = 256;
) )
( (
c = Buffer.alloc(s,b.numFrames,10); r = Routine{
x = Buffer.alloc(s,(~fft_size / 2 +1),10); t = Main.elapsedTime;
y = Buffer.alloc(s,(b.numFrames / ~hop_size + 1) ,10); 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)[2].dup}.play
{PlayBuf.ar(10,c.bufnum,doneAction:2)[5].dup}.play
c.getn(0, 10, {|x|x.postln}) c.getn(0, 10, {|x|x.postln})

@ -1,4 +1,46 @@
//Ar modulator class:: FDGain
{FDGain.ar(WhiteNoise.ar,64,SinOsc.ar(2))}.play summary:: Real-Time Gain Changer
//Kr modulator categories:: UGens>Algebraic
{FDGain.ar(WhiteNoise.ar,64,SinOsc.kr(2))}.play 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 Unions 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
::

@ -1,6 +1,6 @@
FDGain : UGen { FDGain : UGen {
*ar { arg in = 0, framesize=64, gain=1.0; *ar { arg in = 0, frameSize=64, gain=1.0;
^this.multiNew('audio', in.asAudioRateInput(this),framesize, gain) ^this.multiNew('audio', in.asAudioRateInput(this),frameSize, gain)
} }
} }

@ -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;
::

@ -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 Unions 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
::

@ -1,25 +1,5 @@
// adds an instance method to the Buffer class
FDNMF { FDNMF {
/*fdNMF { arg dstBuf, dictBuf, actBuf, rank = 1, iterations = 100, fftSize = 2048, windowSize = 2048, hopSize = 512, 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;
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;
var resp; var resp;
server = server ? Server.default; server = server ? Server.default;
@ -29,15 +9,11 @@ FDNMF {
dstBuf.bufnum.postln; dstBuf.bufnum.postln;
server.sendMsg(\cmd, \BufNMF, server.sendMsg(\cmd, \BufNMF,
if(srcBuf.isNil, -1, {srcBuf.bufnum}), srcBuf.bufnum, startAt, nFrames, startChan, nChans,
startAt, nFrames, startChan, nChans, if(dstBuf.isNil, -1, {dstBuf.bufnum}),
if(dstBuf.isNil, -1, {dstBuf.bufnum}), if(dictBuf.isNil, -1, {dictBuf.bufnum}),
if(dictBuf.isNil, -1, {dictBuf.bufnum}), dictFlag,
dictFlag, if(actBuf.isNil, -1, {actBuf.bufnum}),
if(actBuf.isNil, -1, {actBuf.bufnum}), actFlag, rank, iterations, windowSize, hopSize,fftSize);
actFlag,
rank, iterations, windowSize, hopSize,fftSize);
} }
} }

Loading…
Cancel
Save