* ignore more varieties of build folder
* deal with some warnings
* FluidWaveform 'lineWidth' argument now also affects feature lines
* add back the nmf-jit-classifier example
* novelty interface change in example
* resizable and layoutable guis (#83)
* resizable and layoutable guis
* FluidWaveform: rename 'win' to 'parent'
* FluidWaveform/FluidPlotter: update help
* FluidWaveform/Plotter: make views before forking
This way views are immediately available upon creation,
for example to be added to layouts.
Views are still correctly updated with data from within the fork,
whenever they are ready.
* Thanks @elgiano! + a few small edits
Co-authored-by: Ted Moore <ted@tedmooremusic.com>
* slicers: add enums for algorithms (#86)
* typo
* FluidBufNMF class: add resynthMode argument
* add PCA whitening parameter (#65)
* add PCA whitening parameter
* FluidPCA: Ensure whiten parameter is sent to kr query UGen
Co-authored-by: Gerard <gerard@bumblebee.lan>
Co-authored-by: weefuzzy <gungwho@gmail.com>
* Enhance/optional message args (#77)
* optional args: sc wrapper updates
* optional args: KDTree try out
* Enhance/choices param (#78)
* NRTWrapper: Add choices param (long <-> bitset)
* Update `FluidBufStats` with `select` control
* BufStats class: Fix bitfield for `select` and warn on duplicate items
* Update SpectralShape classes for new param
* `PCA.sc`: add batch `inverseTranform` method
* Wrapper: integer sign warnings
* Enhance/max params (#93)
* CMake: Centralise C++ version and set to 17
* Wrapper: handle new LongRuntimeMax param type
* POC for new LongRuntimeMax param with MFCC numCoeffs
* Wrapper: Make MSVC happy about constexpr lambda capture
* All scalers: replace 'invert' parameter with `inverseTransform` messages
* Wrapper: Work around 32 char limit for plugin commands
If too long, remove vowels.
Sorry.
Better ideas welcome
* fix#96
* typo
* Update SC classes for new style `max<X>` parameters
* SpectralShape SC class: maxFFT
* RealTime wrapper: play it safer with output channel count
This really relies on the SC class being correct, but then everything
ultimately does...
* RT FFT Object SC Classes: Provide maxFFTSize default
* BufSTFT SC class: Add maxFFT (now needed due to core type change)
* Add select param to Loudness and Pitch SC clases (#101)
* Wrapper: workaround scsynth 32 char cmd length limit with extra dispatch layer
also avoids need for formerly truncated plugin names in some cases
* removed invert from scalers class definitions (#102)
* Enhance/generate stubs (#104)
* CMake: generate .cpp stubs
* Remove old cpp stubs
* Ensure correct MSVC runtime by default
* CMake: invoke docs properly
* CMake: Tidy up
* CMake: Tidy up
* CMake: typo
* CI: Update nightly
* CI: remove lingering references to docs job
* CMake: belatedly add branch selection for flucoma deps upon which CI relies
* CMake: Actually commit important code for best collaborative results
* CMake: This file is now redundant, in fact
* cmake: missing slash in install
* bufnmf: added the maxFFTsize parameter in the server call
* FluidStats: Change where output Array reshape happens to keep SynthDescLib happy
* FluidBufNNDSVD: maxfftsize now needed in server call, or booooom
fixes#161
* BufNMFCross: Needs MaxFFTSize
* BufNNDSVD: Ensure activations buffer is queried at finish
* FluidBufToKr ensure that numFrames is an int (not a float)
* Added *(Buf)Feature objects to guide (and deleted old guide)
NNDSVD --> NMFSeed in Guide
fixed bad links in Guide
* change interface and file name (#113)
* hidden --> hiddenLayers in class definition (#114)
* reordered some max<X> arguments
* change interp to interpolation in nmfmorph class (#115)
* Feature/skmeans (#66)
* add PCA whitening parameter
* add FluidSKMeans
* SKMeans correction
* added RT query
* <fit>transform<point> -> <fit>encode<point>
* added to overview
Co-authored-by: Gerard <gerard@bumblebee.lan>
Co-authored-by: tremblap <info@pierrealexandretremblay.com>
* [CI] Update Release Workflow (#118)
* cleanup nightly.yaml
* use new release style
* refactor release
* remove workflow dispatch variables
body:"This is a nightly build of the FluCoMa SuperCollider package. As such, be warned there may be bugs or other unexpected behaviour. The build hash is ${{ github.sha }}"
// how it works: a circular buffer is recording and attacks trigger the process
// if in learning mode, it does a one component nmf which makes an approximation of the base. 3 of those will be copied in 3 different positions of our final 3-component base
// in in guessing mode, it does a thres component nmf from the trained bases and yields the 3 activation peaks, on which it thresholds resynth
//how to use:
// 1. start the server
// 2. select between parenthesis below and execute. You should get a window with 3 pads (bd sn hh) and various menus
// 3. train the 3 classes:
// 3.1 select the learn option
// 3.2 select which class you want to train
// 3.3 play the sound you want to associate with that class a few times (the left audio channel is the source)
// 3.4 click the transfer button
// 3.5 repeat (3.2-3.4) for the other 2 classes.
// 3.x you can observe the 3 bases here:
~classify_bases.plot(numChannels:3)
// 4. classify
// 4.1 select the classify option
// 4.2 press a pad and look at the activation
// 4.3 tweak the thresholds and enjoy the resynthesis. (the right audio channel is the detected class where classA is a bd sound)
// 4.x you can observe the 3 activations here:
~activations.plot(numChannels:3)
/// code to execute first
(
var circle_buf = Buffer.alloc(s,s.sampleRate * 2); // b
var input_bus = Bus.audio(s,1); // g
var classifying = 0; // c
var cur_training_class = 0; // d
var train_base = Buffer.alloc(s, 65); // e
var activation_vals = [0.0,0.0,0.0]; // j
var thresholds = [0.5,0.5,0.5]; // k
var activations_disps;
var analysis_synth;
var osc_func;
var update_rout;
~classify_bases = Buffer.alloc(s, 65, 3); // f
~activations = Buffer.new(s);
// the circular buffer with triggered actions sending the location of the head at the attack
// we are retrieving and comparing against the 2nd activation, because FFT processes are zero-padded on each sides, therefore the complete 128 samples are in the middle of the analysis.
~activations.getn(3,3,{|x|
activation_vals = x;
if (activation_vals[0] >= thresholds[0], {Synth(\fluidbd,[\out,1])});
if (activation_vals[1] >= thresholds[1], {Synth(\fluidsn,[\out,1])});
if (activation_vals[2] >= thresholds[2], {Synth(\fluidhh,[\out,1])});
A parent view to embed the FluidPlotter in. If no parent is passed, FluidPlotter will create a window for itself at the given bounds.
A parent view to embed the FluidPlotter in. If no parent is passed, FluidPlotter will create a window for itself at the given bounds. To create a view without STRONG::parent:: and STRONG::bounds:: (e.g. for GUIs with link::Guides/GUI-Layout-Management::), see the STRONG::standalone:: argument below.
ARGUMENT:: bounds
Where to show the FluidPlotter, either within the parent or on the screen (if no parent is passed).
@ -37,6 +37,9 @@ Minimum of the Y range to display. Default is 0.
ARGUMENT:: ymax
Maximum of the Y range to display. Default is 1.
ARGUMENT:: standalone
If strong::false::, creates a link::Classes/View:: without parent or bounds, so that it can be used as part of a larger GUI, e.g. with link::Guides/GUI-Layout-Management::.
returns::
An instance of FluidPlotter
@ -308,6 +311,36 @@ w = Window("test",Rect(50,50,800,600)).front;
},xmin:20,xmax:20000,ymin:-130,ymax:0);
)
// two FluidPlotter side by side with standalone=false
(
Window.closeAll;
// make two different data dictionaries
d = 2.collect { Dictionary.newFrom([
"cols",2,
"data",Dictionary.newFrom(Array.fill(200,{
arg i;
var return;
if((i%2) == 0,{
return = "example-%".format((i/2).asInteger);
},{
return = [exprand(20,20000),rrand(-130,0)];
});
return;
}))
])};
w = Window("test",Rect(50,50,1200,600)).front;
// make two plotters, one for each data dictionary
A link::Classes/Buffer:: containing features to plot over the waveform. If this link::Classes/Buffer:: is multiple channels, it will plot each channel as a separate feature.
ARGUMENT:: parent
A link::Classes/Window:: to place this FluidWaveform in. If STRONG::nil::, FluidWaveform will make its own window using the STRONG::bounds:: argument.
A link::Classes/Window:: to place this FluidWaveform in. If STRONG::nil::, FluidWaveform will make its own window using the STRONG::bounds:: argument. To create a view without parent and bounds (e.g. for GUIs with link::Guides/GUI-Layout-Management::), see the STRONG::standalone:: argument below.
ARGUMENT:: bounds
A link::Classes/Rect:: of where to place the FluidWaveform. If parent is STRONG::nil::, these bounds will be used to create a new link::Classes/Window::. If parent is not STRONG::nil::, these bounds will be used to place this FluidWaveform in the parent.
@ -57,6 +57,9 @@ Boolean. All the features in STRONG::featureBuf:: need to be normalized for plot
ARGUMENT:: imageColorScaling
An integer indicating how to scale the values in strong::imageBuffer:: before applying the strong::imageColorScheme::. 0 indicates linear scaling, 1 indicates logarithmic scaling. The default is 1. These integers can also be accessed via FluidWaveform.lin and FluidWaveform.log.
ARGUMENT:: standalone
If strong::false::, creates a link::Classes/View:: without parent or bounds, so that it can be used as part of a larger GUI, e.g. with link::Guides/GUI-Layout-Management::.
returns:: A new instance of FluidWaveform.
METHOD:: lin
@ -109,6 +112,9 @@ See this argument in the class method 'new' above.
ARGUMENT:: normalizeFeaturesIndependently
See this argument in the class method 'new' above.
ARGUMENT:: lineWidth
See this argument in the class method 'new' above.
METHOD:: addImageLayer
Add a grapic layer that shows an image derived from a buffer.
@ -127,11 +133,14 @@ See this argument in the class method 'new' above.
METHOD:: front
Similar to link::Classes/Window::'s strong::front:: method. Shows the FluidWaveform. This must be called after layers have been added in order to see the layers.
METHOD:: refresh
Similar to link::Classes/Window::'s strong::refresh:: method. Redraws all FluidWaveform layers. Has to be called after link::Classes/FluidWaveform#-addLayer:: in order to see the new layer.
METHOD:: close
Close the FluidWaveform window. If parent is not STRONG::nil::, this method will close the parent window.
METHOD:: win
METHOD:: parent
returns:: The FluidWaveform window. If parent is not STRONG::nil::, this method will return the parent window.
~fw.addFeaturesLayer(~pitch_analysis,[Color.cyan,Color.yellow]).front; // <<<----- notice the `.front` here to update display after adding this layer
~fw.addFeaturesLayer(~pitch_analysis,[Color.cyan,Color.yellow]).refresh; // <<<----- notice the `.refresh` here to update display after adding this layer
SUMMARY:: An overview of the FluCoMa toolbox for signal decomposition
CATEGORIES:: Libraries>FluidCorpusManipulation
The Fluid Decomposition toolbox provides an open-ended, loosely coupled set of objects to break up and analyse sound in terms of slices (segments in time), layers (superpositions in time and frequency) and objects (configurable or discoverable patterns in sound). Almost all objects have audio-rate and buffer-based versions.
This toolbox was made possible thanks to the FluCoMa project ( LINK::http://www.flucoma.org/:: ) funded by the European Research Council ( LINK::https://erc.europa.eu/:: ) under the European Union’s Horizon 2020 research and innovation programme (grant agreement No 725899).
FluidBufHPSS.process(s,b.bufnum, 44100, 44100, 0, 0, c.bufnum, d.bufnum, e.bufnum, 51, 31, 2); // need to change these for something sensible
s.sync;
(Main.elapsedTime - t).postln;
}.play
);
// owen's sexy example (The world's most expensive stereoizer)
(
{
var hpss = FluidHPSS.ar(PlayBuf.ar(1,b.bufnum,loop:1),modeFlag:2,hta1:SinOsc.kr(1.5,mul:20,add:20),hta2:SinOsc.kr(3,mul:25,add:25), pta1:SinOsc.kr(1.6,0,mul:30,add:30),pta2:SinOsc.kr(1.7,0,mul:17,add:24));