From dd04440afc4b855e8a24146cd302c5ef1115e894 Mon Sep 17 00:00:00 2001 From: Paul Brossier Date: Tue, 19 Jan 2016 21:11:03 +0100 Subject: [PATCH] src/ofxAubioOnsetClass.*: add basic onset class based on mel bands --- example_aubioDemo/src/ofApp.cpp | 16 +++++++ example_aubioDemo/src/ofApp.h | 2 + src/ofxAubioOnsetClass.cpp | 95 +++++++++++++++++++++++++++++++++++++++++ src/ofxAubioOnsetClass.h | 60 ++++++++++++++++++++++++++ 4 files changed, 173 insertions(+) create mode 100644 src/ofxAubioOnsetClass.cpp create mode 100644 src/ofxAubioOnsetClass.h diff --git a/example_aubioDemo/src/ofApp.cpp b/example_aubioDemo/src/ofApp.cpp index 022ad7a..7d8a9bb 100644 --- a/example_aubioDemo/src/ofApp.cpp +++ b/example_aubioDemo/src/ofApp.cpp @@ -31,6 +31,12 @@ void ofApp::setup(){ // setup mel bands object bands.setup(); + // setup onsetClass object + onsetClass.setup(); + onsetClass.setOnset(onset); + onsetClass.setBands(bands); + ofAddListener(onsetClass.gotOnsetClass, this, &ofApp::onsetClassEvent); + ofSoundStreamSetup(nOutputs, nInputs, this); //ofSoundStreamSetup(nOutputs, nInputs, sampleRate, bufferSize, nBuffers); //ofSoundStreamListDevices(); @@ -73,6 +79,9 @@ void ofApp::audioIn(float * input, int bufferSize, int nChannels){ beat.audioIn(input, bufferSize, nChannels); // compute bands bands.audioIn(input, bufferSize, nChannels); + + // compute onset class + onsetClass.audioIn(); //, onset, bands); } void audioOut(){ @@ -119,6 +128,8 @@ void ofApp::draw(){ bandPlot[i].y = 240 - 100 * bands.energies[i]; } bandPlot.draw(); + + ofRect(250 + 190 + onsetClass.currentClass * 7, 150, 50, 50); } //-------------------------------------------------------------- @@ -177,3 +188,8 @@ void ofApp::beatEvent(float & time) { //ofLog() << "got beat at " << time << " s"; gotBeat = true; } + +//--- +void ofApp::onsetClassEvent(int & t) { + //ofLog() << "got onset class event at " << t << " "; +} diff --git a/example_aubioDemo/src/ofApp.h b/example_aubioDemo/src/ofApp.h index cb68c48..4f3e9a4 100644 --- a/example_aubioDemo/src/ofApp.h +++ b/example_aubioDemo/src/ofApp.h @@ -28,12 +28,14 @@ class ofApp : public ofBaseApp{ void onsetEvent(float & time); void beatEvent(float & time); + void onsetClassEvent(int & t); private: ofxAubioOnset onset; ofxAubioPitch pitch; ofxAubioBeat beat; ofxAubioMelBands bands; + ofxAubioOnsetClass onsetClass; ofxPanel pitchGui; ofxFloatSlider midiPitch; diff --git a/src/ofxAubioOnsetClass.cpp b/src/ofxAubioOnsetClass.cpp new file mode 100644 index 0000000..58785fb --- /dev/null +++ b/src/ofxAubioOnsetClass.cpp @@ -0,0 +1,95 @@ +/* + Copyright (C) 2015 Paul Brossier + + This file is part of ofxAubio. + + ofxAubio is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + aubio is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with aubio. If not, see . + +*/ + +#include "ofxAubioOnsetClass.h" +#include "ofLog.h" + +ofEvent ofxAubioOnsetClass::gotGlobalOnsetClass = ofEvent(); + +ofxAubioOnsetClass::ofxAubioOnsetClass() + : bands(NULL) +{ + lag = 3; +} + +ofxAubioOnsetClass::~ofxAubioOnsetClass() +{ +} + +void ofxAubioOnsetClass::setup() +{ + setup("default", 512, 256, 44100); +} +void ofxAubioOnsetClass::setup(string method, int buf_s, int hop_s, int samplerate) +{ + //setup("default", 512, 256, 44100); +} + +void ofxAubioOnsetClass::setBands(ofxAubioMelBands & _bands) { + bands = &_bands; +} + +void ofxAubioOnsetClass::setOnset(ofxAubioOnset & _onset) { + onset = &_onset; + ofAddListener(onset->gotOnset, this, &ofxAubioOnsetClass::onsetEvent); +} + +void ofxAubioOnsetClass::audioIn() +{ + energies.push_back(bands->energies); + if (energies.size() > lag - 1) { + energies.erase (energies.begin()); + } + // hack to add a counter to delay lag * blockSize frames + if (startSelection > 0) { + startSelection--; + if (startSelection == 1) { + onsetClassify(); + } + } +} + +void ofxAubioOnsetClass::onsetEvent(float & time) +{ + //ofLog() << "ofxAubioOnsetClass got onset at " << time; + // hack to add a counter to delay lag * blockSize frames + int delay = 0; + startSelection = lag + delay; +} + +void ofxAubioOnsetClass::onsetClassify() { + if (energies.size() == lag - 1) { + int max_band = 0; + float max_energy = 0; + for (int i = 0; i < bands->nBands; i ++) { + float band_sum = 0; + for (int j = 0; j < energies.size(); j ++) { + band_sum += energies[j][i]; + } + if (max_energy < band_sum) { + max_energy = band_sum; + max_band = i; + } + } + currentClass = max_band; + ofNotifyEvent(gotOnsetClass, currentClass, this); + ofNotifyEvent(gotGlobalOnsetClass, currentClass); + } +} diff --git a/src/ofxAubioOnsetClass.h b/src/ofxAubioOnsetClass.h new file mode 100644 index 0000000..57c7251 --- /dev/null +++ b/src/ofxAubioOnsetClass.h @@ -0,0 +1,60 @@ +/* + Copyright (C) 2015 Paul Brossier + + This file is part of ofxAubio. + + ofxAubio is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + aubio is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with aubio. If not, see . + +*/ + +#pragma once + +#include +#include +#include "ofEvents.h" +#include "ofxAubioBlock.h" +#include "ofxAubioOnset.h" +#include "ofxAubioMelBands.h" + +class ofxAubioOnsetClass : public ofxAubioBlock { + + public: + + ofxAubioOnsetClass(); + ~ofxAubioOnsetClass(); + + ofEvent gotOnsetClass; + static ofEvent gotGlobalOnsetClass; + + void onsetEvent(float & time); + + ofxAubioOnset *onset; + void setOnset(ofxAubioOnset & onset); + ofxAubioMelBands *bands; + void setBands(ofxAubioMelBands & bands); + + int currentClass; + std::vectorenergies; + + void setup(); + void setup(std::string method, int buf_s, int hop_s, int samplerate); + + void audioIn(); + + void onsetClassify(); + + private: + int lag; + int startSelection; +}; -- 2.11.0