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
////////////////////////////
// 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})

@ -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
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 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 {
*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)
}
}

@ -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 { 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);
}
}

Loading…
Cancel
Save