diff --git a/src/WavFileWriterBeta.h b/src/WavFileWriterBeta.h index a6b6d3f61001906c4684a89cbed963a7bd285b16..d48f43db45937a6f810f2b6e77dcb3f10635d7be 100644 --- a/src/WavFileWriterBeta.h +++ b/src/WavFileWriterBeta.h @@ -19,7 +19,7 @@ class WavFileWriterBeta { std::string filename; - /// open file for a fixed-length number of samples + /// open file for a fixed-length number of samples WavFileWriterBeta(std::string filename, unsigned short numChannels, unsigned long sampleRate, unsigned short bytesPerSample, diff --git a/src/ofApp.cpp b/src/ofApp.cpp index 82ea11a5446ad57cb60b5a32c3c8defc8b08e511..49a69709005f294376f5659a45a97ddf5f9b0201 100644 --- a/src/ofApp.cpp +++ b/src/ofApp.cpp @@ -36,6 +36,9 @@ void ofApp::setup() { numBuffers = sampleRate * inputSeconds / bufferSize; previousBuffers.setMaxLen(numPreviousBuffers); sampleBuffers.setMaxLen(numBuffers); + ofLogVerbose(PACKAGE) << "Looking " << std::to_string(numPreviousBuffers) << " into the past" + << " and recording a total of " << std::to_string(numBuffers) << " buffers" + << " each with " << std::to_string(bufferSize) << " samples"; // apply settings to soundStream ofSoundStreamSettings settings; @@ -61,15 +64,15 @@ void ofApp::setup() { ofLogWarning(PACKAGE) << "audio input device does not have enough input channels"; inputChannel = 0; } - ofLogNotice(PACKAGE) << "audio input channel: " << inputChannel+1; + ofLogNotice(PACKAGE) << "audio input channel: " << inputChannel; ofLogNotice(PACKAGE) << "audio input samplerate: " << sampleRate; ofLogNotice(PACKAGE) << "audio input buffer size: " << bufferSize; settings.setInDevice(device); settings.setInListener(this); settings.sampleRate = sampleRate; settings.numOutputChannels = 0; - settings.numInputChannels = device.inputChannels; - settings.bufferSize = bufferSize; + settings.numInputChannels = inputChannel + 1; + settings.bufferSize = bufferSize * (inputChannel + 1); if(!soundStream.setup(settings)) { ofLogError(PACKAGE) << "audio input device " << inputDevice << " setup failed"; ofLogError(PACKAGE) << "perhaps try a different device or samplerate?"; @@ -79,6 +82,9 @@ void ofApp::setup() { if(!listening) { soundStream.stop(); } + if(soundStream.getSampleRate() == 44100) { + ofLogWarning(PACKAGE) << "treating sample rate of 44100 as 48000, may or may not affect detection"; + } // display volHistory.assign(400, 0.0); @@ -250,17 +256,13 @@ void ofApp::exit() { //-------------------------------------------------------------- void ofApp::audioIn(ofSoundBuffer & input) { - - // this shouldn't happen... but we don't let it blow up - if(input.getNumFrames() != monoBuffer.size()) { - ofLogWarning(PACKAGE) << "resizing mono input buffer to " << input.getNumFrames(); - monoBuffer.resize(input.getNumFrames()); - } + // beh, ofSoundBuffer::getNumFrames() actually returns the buffer size? + std::size_t numFrames = input.getNumFrames() / input.getNumChannels(); // copy desired channel out of interleaved stream into mono buffer, // assume input stream has enough channels... - for(std::size_t i = 0; i < input.getNumFrames(); i++) { - monoBuffer[i] = input[i + inputChannel]; + for(std::size_t i = 0; i < numFrames; i++) { + monoBuffer[i] = input[(i*input.getNumChannels())+inputChannel]; } // calculate the root mean square which is a rough way to calculate volume @@ -281,8 +283,8 @@ void ofApp::audioIn(ofSoundBuffer & input) { ofLogVerbose(PACKAGE) << "Start recording..."; // copy previous buffers to the recording sampleBuffers = previousBuffers; - sampleBuffers.setMaxLen(numBuffers); // just to make sure (not tested) - recordingCounter = sampleBuffers.size(); + sampleBuffers.setMaxLen(numBuffers); // hacky: last step overwrites maxLen + recordingCounter = sampleBuffers.size(); // we already have the previous buffer // trigger recording in the next function call recording = true; recordingStarted = true; @@ -294,7 +296,7 @@ void ofApp::audioIn(ofSoundBuffer & input) { // if recording: save the incoming buffer to the recording // then trigger the neural network if(recording) { - sampleBuffers.push(input.getBuffer()); + sampleBuffers.push(monoBuffer); recordingCounter++; if(recordingCounter >= numBuffers) { recording = false; diff --git a/src/ofApp.h b/src/ofApp.h index be94d6318c9858a02a4b60e58be42234ca0a80cf..66075f70b9a37123288fbe3122910ed729a878d6 100644 --- a/src/ofApp.h +++ b/src/ofApp.h @@ -67,9 +67,8 @@ class ofApp : public ofBaseApp { // audio ofSoundStream soundStream; - int inputDevice = -1; - int inputChannel = 0; - std::vector monoBuffer; //< mono inputChannel stream buffer + int inputDevice = -1; // -1 means search for default device + int inputChannel = 0; // 0 - chan 1 (left), 1 - chan 2 (right), 2 - chan 3, etc bool listening = true; // neural network input parameters @@ -77,18 +76,17 @@ class ofApp : public ofBaseApp { // we want to keep the buffersize a multiple of the downsampling factor // downsamplingFactor = sampleRate / modelSampleRate // downsampling is required for microphones that do not have 16kHz sampling - std::size_t bufferSize = 1024; + std::size_t bufferSize = 1024; //< in this case, number of sample frames std::size_t sampleRate = 48000; std::size_t downsamplingFactor = 3; - static const std::size_t modelSampleRate; //< sample rate expected by model - - // since volume detection has some latency we keep a history of buffers + // since volume detection has some latency,d we keep a history of buffers AudioBufferFifo previousBuffers; std::size_t numPreviousBuffers = 10; // how many buffers to save before trigger happens // sampleBuffers acts as a buffer for recording (could be fused) AudioBufferFifo sampleBuffers; std::size_t numBuffers; + SimpleAudioBuffer monoBuffer; //< mono inputChannel stream buffer // volume float curVol = 0.0; @@ -104,9 +102,9 @@ class ofApp : public ofBaseApp { AudioClassifier model; cppflow::tensor output; std::size_t inputSeconds = 5; - const std::size_t inputSamplingRate = 16000; // AI was trained on 16kHz std::size_t inputSize; float minConfidence = 0.75; + static const std::size_t modelSampleRate; //< sample rate expected by model // neural network control logic std::size_t recordingCounter = 0;