[Release] 1.0.1 (#125)

* 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

* interface changes in 8c

* knearest interface change in 10a

* waveform help nmf interface change

* capitalise beatRemember

* two more changes of interface

* typo

* sign binaries

* add -nightly affix

* sign releases too

* enforce concurrency of jobs

* UMAP kr method should not allow user to pass numDimensions

* slicers: change algo/metric select to symbols (#103)

* slicers: change algo/metric selection to symbols

* slicers: algo/metric accept UGen

* FluidDataSetWr example code (#124)
nix
James Bradbury 4 years ago committed by GitHub
parent 3fd541feaf
commit 322c4454df
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -1,37 +1,48 @@
name: Nightly Releases name: nightly
on: on:
workflow_dispatch: workflow_dispatch:
push: push:
branches: [ dev, ci/** ] branches: [ dev, ci/** ]
concurrency:
group: environment-${{ github.ref }}
cancel-in-progress: true
jobs: jobs:
macbuild: macbuild:
runs-on: macos-11 runs-on: macos-latest
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v3
- uses: flucoma/actions/env@v5 - uses: flucoma/actions/env@main
- uses: flucoma/actions/sc@v5 - uses: flucoma/actions/sc@main
with: with:
branch: origin/dev branch: origin/dev
- name: compress archive - name: sign binaries
run: zip -r FluCoMa-SC-Mac-nightly.zip FluidCorpusManipulation uses: flucoma/actions/distribution@main
working-directory: install
- uses: actions/upload-artifact@v2
with: with:
name: macbuild glob: '-e scx'
path: install/FluCoMa-SC-Mac-nightly.zip package: 'install'
output_type: 'dmg'
output: FluCoMa-SC-Mac-nightly
cert: ${{ secrets.CERT }}
certpwd: ${{ secrets.CERTPWD }}
teamid: ${{ secrets.WWDRTEAMID }}
apppwd: ${{ secrets.APPSTORECONNECTPWD }}
appusr: ${{ secrets.APPSTORECONNECTUSERNAME }}
- uses: actions/upload-artifact@v3
with:
name: macbuild
path: install/FluCoMa-SC-Mac-nightly.dmg
winbuild: winbuild:
runs-on: windows-latest runs-on: windows-latest
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v3
- uses: flucoma/actions/env@v5 - uses: flucoma/actions/env@main
- uses: flucoma/actions/sc@v5 - uses: flucoma/actions/sc@main
with: with:
branch: origin/dev branch: origin/dev
@ -42,25 +53,25 @@ jobs:
run: 7z a FluCoMa-SC-Windows-nightly.zip FluidCorpusManipulation run: 7z a FluCoMa-SC-Windows-nightly.zip FluidCorpusManipulation
working-directory: install working-directory: install
- uses: actions/upload-artifact@v2 - uses: actions/upload-artifact@v3
with: with:
name: winbuild name: winbuild
path: install/FluCoMa-SC-Windows-nightly.zip path: install/FluCoMa-SC-Windows-nightly.zip
linuxbuild: linuxbuild:
runs-on: ubuntu-18.04 runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v3
- uses: flucoma/actions/env@v5 - uses: flucoma/actions/env@main
- uses: flucoma/actions/sc@v5 - uses: flucoma/actions/sc@main
with: with:
branch: origin/dev branch: origin/dev
- name: compress archive - name: compress archive
run: tar -zcvf FluCoMa-SC-Linux-nightly.tar.gz FluidCorpusManipulation run: tar -zcvf FluCoMa-SC-Linux-nightly.tar.gz FluidCorpusManipulation
working-directory: install working-directory: install
- uses: actions/upload-artifact@v2 - uses: actions/upload-artifact@v3
with: with:
name: linuxbuild name: linuxbuild
path: install/FluCoMa-SC-Linux-nightly.tar.gz path: install/FluCoMa-SC-Linux-nightly.tar.gz
@ -94,7 +105,7 @@ jobs:
with: with:
name: FluCoMa SuperCollider Nightly Release name: FluCoMa SuperCollider Nightly Release
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 }}" 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 }}"
files: FluCoMa-SC-* files: FluCoMa*
prerelease: true prerelease: true
tag_name: nightly tag_name: nightly
draft: false draft: false

@ -1,33 +1,42 @@
name: Release name: release
on: on:
workflow_dispatch: workflow_dispatch:
jobs: jobs:
macbuild: macbuild:
runs-on: macos-11 runs-on: macos-latest
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v3
- uses: flucoma/actions/env@v5 - uses: flucoma/actions/env@main
- uses: flucoma/actions/sc@v5 - uses: flucoma/actions/sc@main
with: with:
branch: origin/main branch: origin/main
- name: compress archive - name: sign binaries
run: zip -r FluCoMa-SC-Mac.zip FluidCorpusManipulation uses: flucoma/actions/distribution@main
working-directory: install with:
glob: '-e scx'
package: 'install'
output_type: 'dmg'
output: FluCoMa-SC-Mac
cert: ${{ secrets.CERT }}
certpwd: ${{ secrets.CERTPWD }}
teamid: ${{ secrets.WWDRTEAMID }}
apppwd: ${{ secrets.APPSTORECONNECTPWD }}
appusr: ${{ secrets.APPSTORECONNECTUSERNAME }}
- uses: actions/upload-artifact@v2 - uses: actions/upload-artifact@v3
with: with:
name: macbuild name: macbuild
path: install/FluCoMa-SC-Mac.zip path: install/FluCoMa-SC-Mac.dmg
winbuild: winbuild:
runs-on: windows-latest runs-on: windows-latest
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v3
- uses: flucoma/actions/env@v5 - uses: flucoma/actions/env@main
- uses: flucoma/actions/sc@v5 - uses: flucoma/actions/sc@main
with: with:
branch: origin/main branch: origin/main
@ -38,19 +47,19 @@ jobs:
run: 7z a FluCoMa-SC-Windows.zip FluidCorpusManipulation run: 7z a FluCoMa-SC-Windows.zip FluidCorpusManipulation
working-directory: install working-directory: install
- uses: actions/upload-artifact@v2 - uses: actions/upload-artifact@v3
with: with:
name: winbuild name: winbuild
path: install/FluCoMa-SC-Windows.zip path: install/FluCoMa-SC-Windows.zip
linuxbuild: linuxbuild:
runs-on: ubuntu-18.04 runs-on: ubuntu-latest
outputs: outputs:
version: ${{ steps.get-version.outputs.version }} version: ${{ steps.get-version.outputs.version }}
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v3
- uses: flucoma/actions/env@v5 - uses: flucoma/actions/env@main
- uses: flucoma/actions/sc@v5 - uses: flucoma/actions/sc@main
with: with:
branch: origin/main branch: origin/main
@ -58,7 +67,7 @@ jobs:
run: tar -zcvf FluCoMa-SC-Linux.tar.gz FluidCorpusManipulation run: tar -zcvf FluCoMa-SC-Linux.tar.gz FluidCorpusManipulation
working-directory: install working-directory: install
- uses: actions/upload-artifact@v2 - uses: actions/upload-artifact@v3
with: with:
name: linuxbuild name: linuxbuild
path: install/FluCoMa-SC-Linux.tar.gz path: install/FluCoMa-SC-Linux.tar.gz

@ -6,6 +6,10 @@ FluidBufNoveltyFeature : FluidBufProcessor {
source = source.asUGenInput; source = source.asUGenInput;
features = features.asUGenInput; features = features.asUGenInput;
algorithm = FluidNoveltySlice.prSelectAlgorithm(algorithm) ?? {
("FluidBufNoveltySlice: % is not a recognised algorithm")
.format(algorithm).throw;
};
source.isNil.if {"FluidBufNoveltyFeature: Invalid source buffer".throw}; source.isNil.if {"FluidBufNoveltyFeature: Invalid source buffer".throw};
features.isNil.if {"FluidBufNoveltyFeature: Invalid features buffer".throw}; features.isNil.if {"FluidBufNoveltyFeature: Invalid features buffer".throw};
@ -20,6 +24,11 @@ FluidBufNoveltyFeature : FluidBufProcessor {
source = source.asUGenInput; source = source.asUGenInput;
features = features.asUGenInput; features = features.asUGenInput;
algorithm = FluidNoveltySlice.prSelectAlgorithm(algorithm);
if (algorithm.isNil or: algorithm.isUGen) {
("FluidBufNoveltySlice: % is not a recognised algorithm")
.format(algorithm).throw;
};
source.isNil.if {"FluidBufNoveltyFeature: Invalid source buffer".throw}; source.isNil.if {"FluidBufNoveltyFeature: Invalid source buffer".throw};
features.isNil.if {"FluidBufNoveltyFeature: Invalid features buffer".throw}; features.isNil.if {"FluidBufNoveltyFeature: Invalid features buffer".throw};
@ -40,6 +49,11 @@ FluidBufNoveltyFeature : FluidBufProcessor {
source.isNil.if {"FluidBufNoveltyFeature: Invalid source buffer".throw}; source.isNil.if {"FluidBufNoveltyFeature: Invalid source buffer".throw};
features.isNil.if {"FluidBufNoveltyFeature: Invalid features buffer".throw}; features.isNil.if {"FluidBufNoveltyFeature: Invalid features buffer".throw};
algorithm = FluidNoveltySlice.prSelectAlgorithm(algorithm);
if (algorithm.isNil or: algorithm.isUGen) {
("FluidBufNoveltySlice: % is not a recognised algorithm")
.format(algorithm).throw;
};
^this.new( ^this.new(
server, nil, [features] server, nil, [features]

@ -1,11 +1,15 @@
FluidBufNoveltySlice : FluidBufProcessor { FluidBufNoveltySlice : FluidBufProcessor {
*kr { |source, startFrame = 0, numFrames = -1, startChan = 0, numChans = -1, indices, algorithm = 0, kernelSize = 3, threshold = 0.5, filterSize = 1, minSliceLength = 2, windowSize = 1024, hopSize = -1, fftSize = -1, trig = 1 , blocking = 0| *kr { |source, startFrame = 0, numFrames = -1, startChan = 0, numChans = -1, indices, algorithm = 0, kernelSize = 3, threshold = 0.5, filterSize = 1, minSliceLength = 2, windowSize = 1024, hopSize = -1, fftSize = -1, trig = 1 , blocking = 0|
var maxFFTSize = if (fftSize == -1) {windowSize.nextPowerOfTwo} {fftSize}; var maxFFTSize = if (fftSize == -1) {windowSize.nextPowerOfTwo} {fftSize};
source = source.asUGenInput; source = source.asUGenInput;
indices = indices.asUGenInput; indices = indices.asUGenInput;
algorithm = FluidNoveltySlice.prSelectAlgorithm(algorithm) ?? {
("FluidBufNoveltySlice: % is not a recognised algorithm")
.format(algorithm).throw;
};
source.isNil.if {"FluidBufNoveltySlice: Invalid source buffer".throw}; source.isNil.if {"FluidBufNoveltySlice: Invalid source buffer".throw};
indices.isNil.if {"FluidBufNoveltySlice: Invalid features buffer".throw}; indices.isNil.if {"FluidBufNoveltySlice: Invalid features buffer".throw};
@ -15,15 +19,20 @@ FluidBufNoveltySlice : FluidBufProcessor {
} }
*process { |server, source, startFrame = 0, numFrames = -1, startChan = 0, numChans = -1, indices, algorithm= 0, kernelSize = 3, threshold = 0.5, filterSize = 1, minSliceLength = 2, windowSize = 1024, hopSize = -1, fftSize = -1, freeWhenDone = true, action | *process { |server, source, startFrame = 0, numFrames = -1, startChan = 0, numChans = -1, indices, algorithm= 0, kernelSize = 3, threshold = 0.5, filterSize = 1, minSliceLength = 2, windowSize = 1024, hopSize = -1, fftSize = -1, freeWhenDone = true, action |
var maxFFTSize = if (fftSize == -1) {windowSize.nextPowerOfTwo} {fftSize}; var maxFFTSize = if (fftSize == -1) {windowSize.nextPowerOfTwo} {fftSize};
source = source.asUGenInput; source = source.asUGenInput;
indices = indices.asUGenInput; indices = indices.asUGenInput;
algorithm = FluidNoveltySlice.prSelectAlgorithm(algorithm);
if (algorithm.isNil or: algorithm.isUGen) {
("FluidBufNoveltySlice: % is not a recognised algorithm")
.format(algorithm).throw;
};
source.isNil.if {"FluidBufNoveltySlice: Invalid source buffer".throw}; source.isNil.if {"FluidBufNoveltySlice: Invalid source buffer".throw};
indices.isNil.if {"FluidBufNoveltySlice: Invalid features buffer".throw}; indices.isNil.if {"FluidBufNoveltySlice: Invalid features buffer".throw};
^this.new( ^this.new(
server, nil, [indices] server, nil, [indices]
).processList( ).processList(
@ -32,15 +41,20 @@ FluidBufNoveltySlice : FluidBufProcessor {
} }
*processBlocking { |server, source, startFrame = 0, numFrames = -1, startChan = 0, numChans = -1, indices, algorithm= 0, kernelSize = 3, threshold = 0.5, filterSize = 1, minSliceLength = 2, windowSize = 1024, hopSize = -1, fftSize = -1, freeWhenDone = true, action | *processBlocking { |server, source, startFrame = 0, numFrames = -1, startChan = 0, numChans = -1, indices, algorithm= 0, kernelSize = 3, threshold = 0.5, filterSize = 1, minSliceLength = 2, windowSize = 1024, hopSize = -1, fftSize = -1, freeWhenDone = true, action |
var maxFFTSize = if (fftSize == -1) {windowSize.nextPowerOfTwo} {fftSize}; var maxFFTSize = if (fftSize == -1) {windowSize.nextPowerOfTwo} {fftSize};
source = source.asUGenInput; source = source.asUGenInput;
indices = indices.asUGenInput; indices = indices.asUGenInput;
algorithm = FluidNoveltySlice.prSelectAlgorithm(algorithm);
if (algorithm.isNil or: algorithm.isUGen) {
("FluidBufNoveltySlice: % is not a recognised algorithm")
.format(algorithm).throw;
};
source.isNil.if {"FluidBufNoveltySlice: Invalid source buffer".throw}; source.isNil.if {"FluidBufNoveltySlice: Invalid source buffer".throw};
indices.isNil.if {"FluidBufNoveltySlice: Invalid features buffer".throw}; indices.isNil.if {"FluidBufNoveltySlice: Invalid features buffer".throw};
^this.new( ^this.new(
server, nil, [indices] server, nil, [indices]
).processList( ).processList(

@ -5,6 +5,10 @@ FluidBufOnsetFeature : FluidBufProcessor {
source = source.asUGenInput; source = source.asUGenInput;
features = features.asUGenInput; features = features.asUGenInput;
metric = FluidOnsetSlice.prSelectMetric(metric) ?? {
("FluidBufOnsetSlice: % is not a recognised metric")
.format(metric).throw;
};
source.isNil.if {"FluidBufOnsetFeature: Invalid source buffer".throw}; source.isNil.if {"FluidBufOnsetFeature: Invalid source buffer".throw};
features.isNil.if {"FluidBufOnsetFeature: Invalid features buffer".throw}; features.isNil.if {"FluidBufOnsetFeature: Invalid features buffer".throw};
@ -18,6 +22,11 @@ FluidBufOnsetFeature : FluidBufProcessor {
source = source.asUGenInput; source = source.asUGenInput;
features = features.asUGenInput; features = features.asUGenInput;
metric = FluidOnsetSlice.prSelectMetric(metric);
if (metric.isNil or: metric.isUGen) {
("FluidBufOnsetSlice: % is not a recognised metric")
.format(metric).throw;
};
source.isNil.if {"FluidBufOnsetFeature: Invalid source buffer".throw}; source.isNil.if {"FluidBufOnsetFeature: Invalid source buffer".throw};
features.isNil.if {"FluidBufOnsetFeature: Invalid features buffer".throw}; features.isNil.if {"FluidBufOnsetFeature: Invalid features buffer".throw};
@ -35,6 +44,11 @@ FluidBufOnsetFeature : FluidBufProcessor {
source = source.asUGenInput; source = source.asUGenInput;
features = features.asUGenInput; features = features.asUGenInput;
metric = FluidOnsetSlice.prSelectMetric(metric);
if (metric.isNil or: metric.isUGen) {
("FluidBufOnsetSlice: % is not a recognised metric")
.format(metric).throw;
};
source.isNil.if {"FluidBufOnsetFeature: Invalid source buffer".throw}; source.isNil.if {"FluidBufOnsetFeature: Invalid source buffer".throw};
features.isNil.if {"FluidBufOnsetFeature: Invalid features buffer".throw}; features.isNil.if {"FluidBufOnsetFeature: Invalid features buffer".throw};

@ -1,27 +1,37 @@
FluidBufOnsetSlice : FluidBufProcessor { FluidBufOnsetSlice : FluidBufProcessor {
*kr { |source, startFrame = 0, numFrames = -1, startChan = 0, numChans = -1, indices, metric = 0, threshold = 0.5, minSliceLength = 2, filterSize = 5, frameDelta = 0, windowSize = 1024, hopSize = -1, fftSize = -1, trig = 1, blocking = 0|
*kr { |source, startFrame = 0, numFrames = -1, startChan = 0, numChans = -1, indices, metric = 0, threshold = 0.5, minSliceLength = 2, filterSize = 5, frameDelta = 0, windowSize = 1024, hopSize = -1, fftSize = -1, trig = 1, blocking = 0|
var maxFFTSize = if (fftSize == -1) {windowSize.nextPowerOfTwo} {fftSize}; var maxFFTSize = if (fftSize == -1) {windowSize.nextPowerOfTwo} {fftSize};
source = source.asUGenInput; source = source.asUGenInput;
indices = indices.asUGenInput; indices = indices.asUGenInput;
metric = FluidOnsetSlice.prSelectMetric(metric) ?? {
("FluidBufOnsetSlice: % is not a recognised metric")
.format(metric).throw;
};
source.isNil.if {"FluidBufOnsetSlice: Invalid source buffer".throw}; source.isNil.if {"FluidBufOnsetSlice: Invalid source buffer".throw};
indices.isNil.if {"FluidBufOnsetSlice: Invalid features buffer".throw}; indices.isNil.if {"FluidBufOnsetSlice: Invalid features buffer".throw};
^FluidProxyUgen.kr(\FluidBufOnsetSliceTrigger, -1, source, startFrame, numFrames, startChan, numChans, indices, metric, threshold, minSliceLength, filterSize, frameDelta, windowSize, hopSize, fftSize, maxFFTSize, trig, blocking); ^FluidProxyUgen.kr(\FluidBufOnsetSliceTrigger, -1, source, startFrame, numFrames, startChan, numChans, indices, metric, threshold, minSliceLength, filterSize, frameDelta, windowSize, hopSize, fftSize, maxFFTSize, trig, blocking);
} }
*process { |server, source, startFrame = 0, numFrames = -1, startChan = 0, numChans = -1, indices, metric = 0, threshold = 0.5, minSliceLength = 2, filterSize = 5, frameDelta = 0, windowSize = 1024, hopSize = -1, fftSize = -1, freeWhenDone = true, action| *process { |server, source, startFrame = 0, numFrames = -1, startChan = 0, numChans = -1, indices, metric = 0, threshold = 0.5, minSliceLength = 2, filterSize = 5, frameDelta = 0, windowSize = 1024, hopSize = -1, fftSize = -1, freeWhenDone = true, action|
var maxFFTSize = if (fftSize == -1) {windowSize.nextPowerOfTwo} {fftSize}; var maxFFTSize = if (fftSize == -1) {windowSize.nextPowerOfTwo} {fftSize};
source = source.asUGenInput; source = source.asUGenInput;
indices = indices.asUGenInput; indices = indices.asUGenInput;
metric = FluidOnsetSlice.prSelectMetric(metric);
if (metric.isNil or: metric.isUGen) {
("FluidBufOnsetSlice: % is not a recognised metric")
.format(metric).throw;
};
source.isNil.if {"FluidBufOnsetSlice: Invalid source buffer".throw}; source.isNil.if {"FluidBufOnsetSlice: Invalid source buffer".throw};
indices.isNil.if {"FluidBufOnsetSlice: Invalid features buffer".throw}; indices.isNil.if {"FluidBufOnsetSlice: Invalid features buffer".throw};
^this.new( ^this.new(
server, nil, [indices] server, nil, [indices]
).processList( ).processList(
@ -30,15 +40,20 @@ FluidBufOnsetSlice : FluidBufProcessor {
} }
*processBlocking { |server, source, startFrame = 0, numFrames = -1, startChan = 0, numChans = -1, indices, metric = 0, threshold = 0.5, minSliceLength = 2, filterSize = 5, frameDelta = 0, windowSize = 1024, hopSize = -1, fftSize = -1, freeWhenDone = true, action| *processBlocking { |server, source, startFrame = 0, numFrames = -1, startChan = 0, numChans = -1, indices, metric = 0, threshold = 0.5, minSliceLength = 2, filterSize = 5, frameDelta = 0, windowSize = 1024, hopSize = -1, fftSize = -1, freeWhenDone = true, action|
var maxFFTSize = if (fftSize == -1) {windowSize.nextPowerOfTwo} {fftSize}; var maxFFTSize = if (fftSize == -1) {windowSize.nextPowerOfTwo} {fftSize};
source = source.asUGenInput; source = source.asUGenInput;
indices = indices.asUGenInput; indices = indices.asUGenInput;
metric = FluidOnsetSlice.prSelectMetric(metric);
if (metric.isNil or: metric.isUGen) {
("FluidBufOnsetSlice: % is not a recognised metric")
.format(metric).throw;
};
source.isNil.if {"FluidBufOnsetSlice: Invalid source buffer".throw}; source.isNil.if {"FluidBufOnsetSlice: Invalid source buffer".throw};
indices.isNil.if {"FluidBufOnsetSlice: Invalid features buffer".throw}; indices.isNil.if {"FluidBufOnsetSlice: Invalid features buffer".throw};
^this.new( ^this.new(
server, nil, [indices] server, nil, [indices]
).processList( ).processList(

@ -1,13 +1,19 @@
FluidNoveltyFeature : FluidRTUGen { FluidNoveltyFeature : FluidRTUGen {
*kr { arg in = 0, algorithm = 0, kernelSize = 3, filterSize = 1, windowSize = 1024, hopSize = -1, fftSize = -1, maxFFTSize = -1, maxKernelSize, maxFilterSize; *kr { arg in = 0, algorithm = 0, kernelSize = 3, filterSize = 1, windowSize = 1024, hopSize = -1, fftSize = -1, maxFFTSize = -1, maxKernelSize, maxFilterSize;
maxKernelSize = maxKernelSize ? kernelSize; maxKernelSize = maxKernelSize ? kernelSize;
maxFilterSize = maxFilterSize ? filterSize; maxFilterSize = maxFilterSize ? filterSize;
algorithm = FluidNoveltySlice.prSelectAlgorithm(algorithm) ?? {
("FluidNoveltySlice: % is not a recognised algorithm").format(algorithm);
};
^this.multiNew('control', in.asAudioRateInput(this), algorithm, kernelSize, maxKernelSize, filterSize, maxFilterSize, windowSize, hopSize, fftSize, maxFFTSize) ^this.multiNew('control', in.asAudioRateInput(this), algorithm, kernelSize, maxKernelSize, filterSize, maxFilterSize, windowSize, hopSize, fftSize, maxFFTSize)
} }
checkInputs { checkInputs {
if([\scalar, \control].includes(inputs.at(1).rate).not) {
^(": invalid algorithm");
};
if(inputs.at(9).rate != 'scalar') { if(inputs.at(9).rate != 'scalar') {
^(": maxFFTSize cannot be modulated."); ^(": maxFFTSize cannot be modulated.");
}; };

@ -1,20 +1,35 @@
FluidNoveltySlice : FluidRTUGen { FluidNoveltySlice : FluidRTUGen {
const <spectrum = 0; const <algorithms = #[\spectrum, \mfcc, \chroma, \pitch, \loudness];
const <mfcc = 1;
const <chroma = 2; *prSelectAlgorithm { |sym|
const <pitch = 3; if (sym.isUGen) { ^sym };
const <loudness = 4; if (sym.isNumber) {
if (sym >= 0 && (sym < algorithms.size)) {
^sym
} {
^nil
}
};
^algorithms.indexOf(sym.asSymbol)
}
*ar { arg in = 0, algorithm = 0, kernelSize = 3, threshold = 0.8, filterSize = 1, minSliceLength = 2, windowSize = 1024, hopSize = -1, fftSize = -1, maxFFTSize = -1, maxKernelSize, maxFilterSize; *ar { arg in = 0, algorithm = 0, kernelSize = 3, threshold = 0.8, filterSize = 1, minSliceLength = 2, windowSize = 1024, hopSize = -1, fftSize = -1, maxFFTSize = -1, maxKernelSize, maxFilterSize;
maxKernelSize = maxKernelSize ? kernelSize; maxKernelSize = maxKernelSize ? kernelSize;
maxFilterSize = maxFilterSize ? filterSize; maxFilterSize = maxFilterSize ? filterSize;
algorithm = this.prSelectAlgorithm(algorithm) ?? {
("FluidNoveltySlice: % is not a recognised algorithm").format(algorithm);
};
^this.multiNew('audio', in.asAudioRateInput(this), algorithm, kernelSize, maxKernelSize, threshold, filterSize, maxFilterSize, minSliceLength, windowSize, hopSize, fftSize, maxFFTSize) ^this.multiNew('audio', in.asAudioRateInput(this), algorithm, kernelSize, maxKernelSize, threshold, filterSize, maxFilterSize, minSliceLength, windowSize, hopSize, fftSize, maxFFTSize)
} }
checkInputs { checkInputs {
if([\scalar, \control].includes(inputs.at(1).rate).not) {
^(": invalid algorithm");
};
if(inputs.at(11).rate != 'scalar') { if(inputs.at(11).rate != 'scalar') {
^(": maxFFTSize cannot be modulated."); ^(": maxFFTSize cannot be modulated.");
}; };

@ -1,8 +1,16 @@
FluidOnsetFeature : FluidRTUGen { FluidOnsetFeature : FluidRTUGen {
*kr { arg in = 0, metric = 0, filterSize = 5, frameDelta = 0, windowSize = 1024, hopSize = -1, fftSize = -1, maxFFTSize = -1; *kr { arg in = 0, metric = 0, filterSize = 5, frameDelta = 0, windowSize = 1024, hopSize = -1, fftSize = -1, maxFFTSize = -1;
metric = FluidOnsetSlice.prSelectMetric(metric) ?? {
("% is not a recognised metric").format(metric);
};
^this.multiNew('control', in.asAudioRateInput(this), metric, filterSize, frameDelta, windowSize, hopSize, fftSize, maxFFTSize) ^this.multiNew('control', in.asAudioRateInput(this), metric, filterSize, frameDelta, windowSize, hopSize, fftSize, maxFFTSize)
} }
checkInputs { checkInputs {
if([\scalar, \control].includes(inputs.at(1).rate).not) {
^(": invalid metric");
};
if(inputs.at(7).rate != 'scalar') { if(inputs.at(7).rate != 'scalar') {
^(": maxFFTSize cannot be modulated."); ^(": maxFFTSize cannot be modulated.");
}; };

@ -1,20 +1,42 @@
FluidOnsetSlice : FluidRTUGen { FluidOnsetSlice : FluidRTUGen {
const <power = 0; const <metrics = #[
const <hfc = 1; \power,
const <flux = 2; \hfc,
const <mkl = 3; \flux,
const <is = 4; \mkl,
const <cosine = 5; \is,
const <phase = 6; \cosine,
const <wphase = 7; \phase,
const <complex = 8; \wphase,
const <rcomplex = 9; \complex,
\rcomplex,
];
*prSelectMetric { |sym|
if (sym.isUGen) { ^sym };
if (sym.isNumber) {
if (sym >= 0 && (sym < metrics.size)) {
^sym
} {
^nil
}
};
^metrics.indexOf(sym.asSymbol)
}
*ar { arg in = 0, metric = 0, threshold = 0.5, minSliceLength = 2, filterSize = 5, frameDelta = 0, windowSize = 1024, hopSize = -1, fftSize = -1, maxFFTSize = -1; *ar { arg in = 0, metric = 0, threshold = 0.5, minSliceLength = 2, filterSize = 5, frameDelta = 0, windowSize = 1024, hopSize = -1, fftSize = -1, maxFFTSize = -1;
metric = this.prSelectMetric(metric) ?? {
("% is not a recognised metric").format(metric);
};
^this.multiNew('audio', in.asAudioRateInput(this), metric, threshold, minSliceLength, filterSize, frameDelta, windowSize, hopSize, fftSize, maxFFTSize) ^this.multiNew('audio', in.asAudioRateInput(this), metric, threshold, minSliceLength, filterSize, frameDelta, windowSize, hopSize, fftSize, maxFFTSize)
} }
checkInputs { checkInputs {
if([\scalar, \control].includes(inputs.at(1).rate).not) {
^(": invalid metric");
};
if(inputs.at(9).rate != 'scalar') { if(inputs.at(9).rate != 'scalar') {
^(": maxFFTSize cannot be modulated."); ^(": maxFFTSize cannot be modulated.");
}; };

@ -87,7 +87,7 @@ FluidPlotter : FluidViewer {
if(dict_internal.at(identifier).notNil,{ if(dict_internal.at(identifier).notNil,{
"FluidPlotter::addPoint_ There already exists a point with identifier %. Point not added. Use setPoint_ to overwrite existing points.".format(identifier).warn; "FluidPlotter::addPoint_ There already exists a point with identifier %. Point not added. Use setPoint_ to overwrite existing points.".format(identifier).warn;
},{ },{
this.setPoint_(identifier,x,y,size,color); this.setPoint_(identifier,x,y,color,size);
}); });
} }

@ -63,10 +63,7 @@ FluidUMAP : FluidModelObject {
this.prSendMsg(this.transformPointMsg(sourceBuffer,destBuffer)); this.prSendMsg(this.transformPointMsg(sourceBuffer,destBuffer));
} }
kr{|trig, inputBuffer,outputBuffer,numDimensions| kr{|trig, inputBuffer,outputBuffer|
numDimensions = numDimensions ? this.numDimensions;
this.numDimensions_(numDimensions);
^FluidUMAPQuery.kr(trig, ^FluidUMAPQuery.kr(trig,
this, this,

@ -17,7 +17,7 @@ y = {
) )
// isolate just sines or residual; // isolate just sines or residual;
~song = Buffer.readChannel(s,FluidFilesPath("Tremblay-beatRemember.wav"),channels:[0]); ~song = Buffer.readChannel(s,FluidFilesPath("Tremblay-BeatRemember.wav"),channels:[0]);
( (
y = { y = {
@ -37,7 +37,7 @@ y.set(\mix,0);
y.set(\mix,1); y.set(\mix,1);
// a stereo example // a stereo example
~song = Buffer.read(s,FluidFilesPath("Tremblay-beatRemember.wav")); ~song = Buffer.read(s,FluidFilesPath("Tremblay-BeatRemember.wav"));
( (
y = { y = {
@ -85,7 +85,7 @@ FluidHPSS separates a sound into "harmonic" and "percussive" components. This ca
*/ */
//load a soundfile to play //load a soundfile to play
~buf = Buffer.readChannel(s,FluidFilesPath("Tremblay-beatRemember.wav"),channels:[0]); ~buf = Buffer.readChannel(s,FluidFilesPath("Tremblay-BeatRemember.wav"),channels:[0]);
// run with basic parameters (left is harmonic, right is percussive) // run with basic parameters (left is harmonic, right is percussive)
{FluidHPSS.ar(PlayBuf.ar(1,~buf,loop:1))}.play {FluidHPSS.ar(PlayBuf.ar(1,~buf,loop:1))}.play

@ -59,7 +59,7 @@ Routine{
Routine{ Routine{
var drums = Buffer.read(s,FluidFilesPath("Nicol-LoopE-M.wav")); var drums = Buffer.read(s,FluidFilesPath("Nicol-LoopE-M.wav"));
var voice = Buffer.read(s,FluidFilesPath("Tremblay-AaS-VoiceQC-B2K-M.wav")); var voice = Buffer.read(s,FluidFilesPath("Tremblay-AaS-VoiceQC-B2K-M.wav"));
var song = Buffer.read(s,FluidFilesPath("Tremblay-beatRemember.wav")); var song = Buffer.read(s,FluidFilesPath("Tremblay-BeatRemember.wav"));
s.sync; s.sync;
"drums through the drums bases as filters".postln; "drums through the drums bases as filters".postln;

@ -74,8 +74,6 @@ FluidBufMelBands.process(s,~audio, features: ~melfeatures,action: {\done.postln;
//prepare the normalizers and the neural net for inverse query //prepare the normalizers and the neural net for inverse query
( (
~normalView.invert = 1;
~normalizer.invert = 1;
~mlp.tapIn = 2; ~mlp.tapIn = 2;
~mlp.tapOut = -1; ~mlp.tapOut = -1;
) )
@ -114,9 +112,9 @@ v.mouseMoveAction = {|view, x, y|
~kdtree.kNearest(~queryPoint, action: {|nearest| //retrieve the nearest point ~kdtree.kNearest(~queryPoint, action: {|nearest| //retrieve the nearest point
~norm.getPoint(nearest, ~dpN, action: { //get the normalised 40d ~norm.getPoint(nearest, ~dpN, action: { //get the normalised 40d
~raw.getPoint(nearest, ~datapoint, action: { // get the original 40d ~raw.getPoint(nearest, ~datapoint, action: { // get the original 40d
~normalView.transformPoint(~queryPoint, ~dQueryPoint, action: { //denormalise the 2d coordinate to get the right range of values for the MLP ~normalView.inverseTransformPoint(~queryPoint, ~dQueryPoint, action: { //denormalise the 2d coordinate to get the right range of values for the MLP
~mlp.predictPoint(~dQueryPoint, ~dpMLPn, action: { //predict from the middle (2d) to the normalised output (40d) ~mlp.predictPoint(~dQueryPoint, ~dpMLPn, action: { //predict from the middle (2d) to the normalised output (40d)
~normalizer.transformPoint(~dpMLPn, ~dpMLP, action: { //denormalised the 40d ~normalizer.inverseTransformPoint(~dpMLPn, ~dpMLP, action: { //denormalised the 40d
~datapoint.getn(0,40,{|x|~arrayRawN = x; //retrieve the nearest ~datapoint.getn(0,40,{|x|~arrayRawN = x; //retrieve the nearest
~dpN.getn(0,40,{|x|~arrayRawNn = x; // retrieve the normalised nearest ~dpN.getn(0,40,{|x|~arrayRawNn = x; // retrieve the normalised nearest
~dpMLPn.getn(0,40,{|x|~arrayMLPn = x; //retrieve the predicted normalised 40d ~dpMLPn.getn(0,40,{|x|~arrayMLPn = x; //retrieve the predicted normalised 40d
@ -158,4 +156,4 @@ w.drawFunc = {
}; };
w.refresh; w.refresh;
w.front; w.front;
) )

@ -425,7 +425,7 @@ FluidWaveform(featureBuffer:~bases,bounds:Rect(0,0,1200,300));
// if we play a different source through FluidNMFFilter, it will try to decompose that real-time signal according to the bases // if we play a different source through FluidNMFFilter, it will try to decompose that real-time signal according to the bases
// it is given (in our case the bases from the drum loop) // it is given (in our case the bases from the drum loop)
~song = Buffer.readChannel(s,FluidFilesPath("Tremblay-beatRemember.wav"),channels:[0]); ~song = Buffer.readChannel(s,FluidFilesPath("Tremblay-BeatRemember.wav"),channels:[0]);
( (
{ {

@ -1,7 +1,7 @@
TITLE:: FluidDataSetWr TITLE:: FluidDataSetWr
summary:: Write to FluidDataSet on the server summary:: Write to FluidDataSet on the server
categories:: Libraries>FluidCorpusManipulation categories:: Libraries>FluidCorpusManipulation
related:: Classes/FLuidDataSet related:: Classes/FluidDataSet
DESCRIPTION:: DESCRIPTION::
A UGen that adds data points with associated identifiers to a link::Classes/FluidDataSet:: Internally, this calls code::setPoint::, so IDs that already exist will be overwritten, and new IDs will be added. The actual work is done on the server's command queue, rather than the real-thread. A UGen that adds data points with associated identifiers to a link::Classes/FluidDataSet:: Internally, this calls code::setPoint::, so IDs that already exist will be overwritten, and new IDs will be added. The actual work is done on the server's command queue, rather than the real-thread.
@ -21,10 +21,10 @@ CLASSMETHODS::
private:: *new1 private:: *new1
METHOD:: kr METHOD:: kr
The equivalent of calling link::Classes/FluidDataSet#-addPoint::, but within a link::Classes/Synth:: The equivalent of calling link::Classes/FluidDataSet#-setPoint::, but within a link::Classes/Synth::
ARGUMENT:: dataset ARGUMENT:: dataset
An instance of link::Classes/FluidDataSet:: or an instance's name. An instance of link::Classes/FluidDataSet::
ARGUMENT:: idPrefix ARGUMENT:: idPrefix
A string or symbol with a prefix for generated identifiers. A string or symbol with a prefix for generated identifiers.
@ -67,58 +67,38 @@ s.reboot;
( (
~ds.clear; ~ds.clear;
OSCFunc({ OSCFunc({
"FluidDataSetWr help: all points written".postln; "FluidDataSetWr help: all points written".postln;
~ds.print ~ds.print
},'/datasetwrdone').oneShot; },'/datasetwrdone').oneShot;
{ |n| {
var b = LocalBuf.newFrom([0,1,2,3]); arg n;
var trig = Impulse.kr(ControlRate.ir / 8); var buf = LocalBuf(4);
var idx = Stepper.kr(trig,min:-1, max:n); //we need to start at -1 to catch the first increment var trig = Impulse.kr(ControlRate.ir / 8); // can't go any faster
4.collect{|i| BufWr.kr([(4 * idx) + i],b,i)}; var idx = Stepper.kr(trig,min:-1, max:n); //we need to start at -1 to catch the first increment
FluidDataSetWr.kr(~ds,idNumber:idx,buf:b,trig:trig);
SendReply.kr(idx >= (n-1), '/datasetwrdone'); FluidKrToBuf.kr((idx * 4) + [0,1,2,3],buf);
FreeSelf.kr(idx >= (n-1)); FluidDataSetWr.kr(~ds,"point-",idNumber:idx,buf:buf,trig:trig);
}.play(s,args:[n:100]); SendReply.kr(idx >= (n-1), '/datasetwrdone');
FreeSelf.kr(idx >= (n-1));
}.play(args:[\n,100]);
) )
::
//it printed with the return function strong::incremental buffer writing - sky is the limit::
code::
//Again, but as fast as possible using a feedback of the trigger we are given when the writing is done
(
~ds.clear;
OSCFunc({
"FluidDataSetWr help: all points written".postln;
~ds.print
},'/datasetwrdone').oneShot;
{ |n|
var b = LocalBuf.newFrom([0,1,2,3]);
var trig = LocalIn.kr(1,1);
var idx = Stepper.kr(trig,min:-1, max:n);
var wr = FluidDataSetWr.kr(~ds,idNumber:idx,buf:b,trig:trig);
4.collect{|i| BufWr.kr([(4 * idx) + i],b,i)};
LocalOut.kr(Done.kr(wr));
SendReply.kr(idx >= (n-1), '/datasetwrdone');
FreeSelf.kr(idx >= (n-1));
}.play(s,args:[n:100]);
)
// incremental buffer writing - sky is the limit
~ds.clear
// start the entry maker, trigging twice a second // start the entry maker, trigging twice a second
( (
~ds.clear;
{ {
var buf = LocalBuf.newFrom([0,1,2,3]); var buf = LocalBuf(4);
var noise = 4.collect{WhiteNoise.kr()}; var trig = Impulse.kr(30);
var trig = Impulse.kr(2); var count = PulseCount.kr(trig) - 1;
var count = PulseCount.kr(trig); FluidKrToBuf.kr(WhiteNoise.kr(1.dup(4)),buf);
4.do{|i| FluidDataSetWr.kr(~ds,"point-",idNumber: count, trig: trig, buf:buf);
BufWr.kr(noise[i], buf, DC.kr(i)); }.play;
};
FluidDataSetWr.kr(~ds, idNumber: count, trig: trig, buf:buf);
}.play(s);
) )
//print a few times //print a few times
@ -132,18 +112,24 @@ OSCFunc({
~ds.print; ~ds.print;
~ds.clear ~ds.clear
// circular writing ::
strong::circular writing::
Each time link::Classes/FluidDataSetWr:: is triggered it is like the link::Classes/FluidDataSet#-setPoint:: method so if the identifier does not exist it creates it. If the identifier does it exist then it updates it with the new values.
By looping code::idNumber:: values, we can use a link::Classes/FluidDataSet:: similar to a "circle buffer", always have the most recent code::n:: points in it that we want.
code::
// always have only the most recent 10 points in the buffer
( (
{ {
var buf = LocalBuf.newFrom([0,1,2,3]); var buf = LocalBuf.newFrom([0,1,2,3]);
var noise = 4.collect{WhiteNoise.kr()}; var noise = WhiteNoise.kr(1.dup(4)) + Sweep.kr(1,1);
var trig = Impulse.kr(2); var trig = Impulse.kr(2);
var count = Stepper.kr(trig, min: 0, max: 9, resetval: -1); //0 to 9, starting at -1 to catch the first entry var count = Stepper.kr(trig, min: 0, max: 9, resetval: -1); //0 to 9, starting at -1 to catch the first entry
4.do{|i| FluidKrToBuf.kr(noise,buf);
BufWr.kr(noise[i], buf, DC.kr(i)); FluidDataSetWr.kr(~ds, "point-",idNumber: count, trig: trig, buf:buf);
}; }.play;
FluidDataSetWr.kr(~ds, idNumber: count, trig: trig, buf:buf);
}.play(s);
) )
//print regularly to see a specific identifier being overwritten //print regularly to see a specific identifier being overwritten

@ -293,7 +293,7 @@ s.waitForBoot{
~resynths = {Buffer(s)} ! ~n_components; ~resynths = {Buffer(s)} ! ~n_components;
s.sync; s.sync;
FluidBufNMF.processBlocking(s,~audio,resynth:~resynth,activations:~activations,components:~n_components); FluidBufNMF.processBlocking(s,~audio,resynth:~resynth,resynthMode: 1,activations:~activations,components:~n_components);
~n_components.do{ ~n_components.do{
arg i; arg i;

@ -166,10 +166,10 @@ FluidBufCompose.process(s,~loader.buffer,a,(b-a),numChans: 1, destination: ~targ
~flatbuf[1].getn(0,182,{|x|~curatedWBuf = Buffer.loadCollection(s, x[[0,1,4,6,7,8,11,13].collect{|x|var y=x*13+1;(y..(y+11))}.flat].postln)}) ~flatbuf[1].getn(0,182,{|x|~curatedWBuf = Buffer.loadCollection(s, x[[0,1,4,6,7,8,11,13].collect{|x|var y=x*13+1;(y..(y+11))}.flat].postln)})
//find its nearest neighbours //find its nearest neighbours
~tree.kNearest(~flatbuf[0],{|x| ~friends = x.postln;}) ~tree.kNearest(~flatbuf[0],action:{|x| ~friends = x.postln;})
~treeW.kNearest(~flatbuf[1],{|x| ~friendsW = x.postln;}) ~treeW.kNearest(~flatbuf[1],action:{|x| ~friendsW = x.postln;})
~treeC.kNearest(~curatedBuf,{|x| ~friendsC = x.postln;}) ~treeC.kNearest(~curatedBuf,action:{|x| ~friendsC = x.postln;})
~treeCW.kNearest(~curatedWBuf,{|x| ~friendsCW = x.postln;}) ~treeCW.kNearest(~curatedWBuf,action:{|x| ~friendsCW = x.postln;})
// play them in a row // play them in a row

@ -4,7 +4,7 @@
//slightly oversegment with novelty //slightly oversegment with novelty
//segments should still make sense but might cut a few elements in 2 or 3 //segments should still make sense but might cut a few elements in 2 or 3
~slicer = FluidSliceCorpus({ |src,start,num,dest| FluidBufNoveltySlice.kr(src,start,num,indices:dest, feature: 1, kernelSize: 29, threshold: 0.1, filterSize: 5, hopSize: 128, blocking: 1)}); ~slicer = FluidSliceCorpus({ |src,start,num,dest| FluidBufNoveltySlice.kr(src, start, num, indices:dest, algorithm:1, kernelSize:29, threshold:0.1, filterSize:5, hopSize:128, blocking:1)});
~slicer.play(s, ~loader.buffer,~loader.index); ~slicer.play(s, ~loader.buffer,~loader.index);
//test the segmentation by looping them //test the segmentation by looping them

@ -297,7 +297,7 @@ FluidBufMelBands.process(s, ~inBuf, features: ~inBufMels, action: {
FluidBufFlatten.process(s, ~inBufStats, destination:~inBufFlat, action: { FluidBufFlatten.process(s, ~inBufStats, destination:~inBufFlat, action: {
FluidBufCompose.process(s, ~inBufFlat, numFrames: ~numMelBands, destination: ~inBufComp, action: { FluidBufCompose.process(s, ~inBufFlat, numFrames: ~numMelBands, destination: ~inBufComp, action: {
~standardizer.transformPoint(~inBufComp, ~inBufStand, { ~standardizer.transformPoint(~inBufComp, ~inBufStand, {
~tree.kNearest(~inBufStand,{ |a|a.postln;~nearest = a;}) ~tree.kNearest(~inBufStand,action:{ |a|a.postln;~nearest = a;})
}) })
}) })
}) })

@ -74,8 +74,6 @@ FluidBufMelBands.process(s,~audio, features: ~melfeatures,action: {\done.postln;
//prepare the normalizers and the neural net for inverse query //prepare the normalizers and the neural net for inverse query
( (
~normalView.invert = 1;
~normalizer.invert = 1;
~mlp.tapIn = 2; ~mlp.tapIn = 2;
~mlp.tapOut = -1; ~mlp.tapOut = -1;
) )
@ -114,9 +112,9 @@ v.mouseMoveAction = {|view, x, y|
~kdtree.kNearest(~queryPoint, action: {|nearest| //retrieve the nearest point ~kdtree.kNearest(~queryPoint, action: {|nearest| //retrieve the nearest point
~norm.getPoint(nearest, ~dpN, action: { //get the normalised 40d ~norm.getPoint(nearest, ~dpN, action: { //get the normalised 40d
~raw.getPoint(nearest, ~datapoint, action: { // get the original 40d ~raw.getPoint(nearest, ~datapoint, action: { // get the original 40d
~normalView.transformPoint(~queryPoint, ~dQueryPoint, action: { //denormalise the 2d coordinate to get the right range of values for the MLP ~normalView.inverseTransformPoint(~queryPoint, ~dQueryPoint, action: { //denormalise the 2d coordinate to get the right range of values for the MLP
~mlp.predictPoint(~dQueryPoint, ~dpMLPn, action: { //predict from the middle (2d) to the normalised output (40d) ~mlp.predictPoint(~dQueryPoint, ~dpMLPn, action: { //predict from the middle (2d) to the normalised output (40d)
~normalizer.transformPoint(~dpMLPn, ~dpMLP, action: { //denormalised the 40d ~normalizer.inverseTransformPoint(~dpMLPn, ~dpMLP, action: { //denormalised the 40d
~datapoint.getn(0,40,{|x|~arrayRawN = x; //retrieve the nearest ~datapoint.getn(0,40,{|x|~arrayRawN = x; //retrieve the nearest
~dpN.getn(0,40,{|x|~arrayRawNn = x; // retrieve the normalised nearest ~dpN.getn(0,40,{|x|~arrayRawNn = x; // retrieve the normalised nearest
~dpMLPn.getn(0,40,{|x|~arrayMLPn = x; //retrieve the predicted normalised 40d ~dpMLPn.getn(0,40,{|x|~arrayMLPn = x; //retrieve the predicted normalised 40d

Loading…
Cancel
Save