Created
May 20, 2019 19:21
-
-
Save stephanschulz/3e155617dee97d42b7f9979562780c35 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include "ofMain.h" | |
| #include "ofApp.h" | |
| //======================================================================== | |
| int main( ){ | |
| ofSetupOpenGL(1024,768,OF_WINDOW); // <-------- setup the GL context | |
| // this kicks off the running of my app | |
| // can be OF_WINDOW or OF_FULLSCREEN | |
| // pass in width and height too: | |
| ofRunApp(new ofApp()); | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include "ofApp.h" | |
| //#define USE_LOAD_DIALOG // comment this line if you dont want to use the system load dialog | |
| //-------------------------------------------------------------- | |
| void ofApp::setup(){ | |
| ofSetLogLevel(OF_LOG_VERBOSE); | |
| ofxSoundUtils::printInputSoundDevices(); | |
| ofxSoundUtils::printOutputSoundDevices(); | |
| #ifdef USE_LOAD_DIALOG | |
| // this will open a dialog to select a folder in which you should have audio files. | |
| // Each audio file will be connected to a new input of your matrix mixer. | |
| // by default the file dialog should open in the soundplayer example's folder that has some audio files so you can simply pres open if you want to try those | |
| ofFileDialogResult r = ofSystemLoadDialog("Select folder with audio files(wav, aiff, mp3)", true, "../../../../../examples/sound/soundPlayerExample/bin/data/sounds"); | |
| if(r.bSuccess){ | |
| loadPath = r.getPath(); | |
| #else | |
| // change this path if you want to use another one and not use the system load dialog | |
| // loadPath = ofToDataPath("../../../../../examples/sound/soundPlayerExample/bin/data/sounds"); | |
| // loadPath = "/Users/roy/openFrameworks/examples/sound/soundPlayerExample/bin/data/sounds"; | |
| loadPath = ofToDataPath("/Users/stephanschulz/Desktop/recordings_all/recordings_wav"); | |
| #endif | |
| loadFolder(loadPath); | |
| #ifdef USE_LOAD_DIALOG | |
| } | |
| #endif | |
| //Here we also connect the audio input to the mixer | |
| // | |
| input.connectTo(mixer); | |
| auto inDevices = ofxSoundUtils::getInputSoundDevices(); | |
| auto outDevices = ofxSoundUtils::getOutputSoundDevices(); | |
| // IMPORTANT!!! | |
| // The following two lines of code is where you set which audio interface to use. | |
| // the index is the number printed in the console inside [ ] before the interface name | |
| // You can use a different input and output device. | |
| inDeviceIndex = 0; | |
| outDeviceIndex = 0; | |
| // Setup the sound stream. | |
| ofSoundStreamSettings settings; | |
| settings.bufferSize = 256; | |
| settings.numBuffers = 1; | |
| settings.numInputChannels = inDevices[inDeviceIndex].inputChannels; | |
| settings.numOutputChannels = outDevices[outDeviceIndex].outputChannels; | |
| if(players.size()){ | |
| // we setup the samplerate of the sound stream according to the one of the first player | |
| if(players[0]) | |
| ofLog()<<"players[0]->getSoundFile().getSampleRate() "<<players[0]->getSoundFile().getSampleRate(); | |
| settings.sampleRate = players[0]->getSoundFile().getSampleRate(); | |
| }else{ | |
| ofLogWarning("ofApp::setup", "could not set sample rate for soundstream") ; | |
| } | |
| settings.setInDevice(inDevices[inDeviceIndex]); | |
| settings.setOutDevice(outDevices[outDeviceIndex]); | |
| stream.setup(settings); | |
| input.setInputStream(stream); | |
| mixer.setOutputStream(stream); | |
| mixer.setOutputVolumeForAllChannels(1); | |
| // mixerRenderer.setObject(&mixer); | |
| mixerRenderer.obj = &mixer; | |
| mixerRenderer.enableSliders(); | |
| mixerSettingsXmlPath = "mixerSettings.xml"; | |
| //Create objects signal chain. | |
| //Currently you need to connect the recorder to the output, because of the pull-through audio architecture being used. Eventually this need would become unnecesary. | |
| /* | |
| if you do the following, you'll record the delayed and filtered signal. | |
| input.connectTo(delay).connectTo(locutfilter).connectTo(recorder).connectTo(output); | |
| But if you have the following you'll be recording the raw input, which is then delayed and filtered | |
| input.connectTo(recorder).connectTo(delay).connectTo(locutfilter).connectTo(output); | |
| */ | |
| input.connectTo(recorder).connectTo(mixer); //.connectTo(output); | |
| shuffleIndex = 0; | |
| } | |
| //-------------------------------------------------------------- | |
| void ofApp::loadFolder(const string& path){ | |
| ofFile f(path); | |
| if(f.isDirectory()){ | |
| ofDirectory dir(path); | |
| dir.allowExt("wav"); | |
| dir.allowExt("aiff"); | |
| dir.allowExt("mp3"); | |
| dir.listDir(); | |
| auto startIndex = players.size(); | |
| players.resize( startIndex + dir.size()); | |
| for (int i = 0; i < dir.size(); i++) { | |
| players[startIndex + i] = make_shared<ofxSoundPlayerObject>(); | |
| if(players[startIndex + i]->load(dir.getPath(i))){ | |
| players[startIndex + i]->connectTo(mixer); | |
| players[startIndex + i]->play(); | |
| players[startIndex + i]->setLoop(true); | |
| } | |
| } | |
| } | |
| } | |
| //-------------------------------------------------------------- | |
| void ofApp::update(){ | |
| // ofLog()<<"mixer.getNumInputChannels() "<<mixer.getNumInputChannels(); | |
| if(mixer.getNumOutputChannels() > 0){ | |
| int chan = int(ofGetElapsedTimef() / 1) % mixer.getNumInputChannels(); | |
| float x = ofMap(ofGetMouseX(), 0, ofGetWidth(), 0, 1, true); | |
| // float y = ofMap(ofGetMouseY(), 0, ofGetHeight(), 0, 1, true); | |
| float y = 1 - fmod(ofGetElapsedTimef(),1); | |
| //the following sets the volume for the second connection (sound player) for its first input channel and its second output channels based on the mouse x position | |
| // mixer.setVolumeForConnectionChannel(x, 1, 0, 0); | |
| // the following sets the volume of the matrix channels. In this case it would be the channel number 7 for which you can find out to which sound player it belongs by calling | |
| //mixer.getConnectionIndexAtInputChannel(7); | |
| mixer.setVolumeForChannel(y, chan, 1); | |
| } | |
| if(bNewRecording == true && ofGetElapsedTimef() - stopRecTimer > 3){ | |
| bNewRecording = false; | |
| ofLog()<<"load new file "<<recFileName; | |
| shuffleIndex++; | |
| shuffleIndex %= players.size(); | |
| ofLog()<<"shuffleIndex "<<shuffleIndex; | |
| players[shuffleIndex]->load(recFileName); | |
| // players[shuffleIndex]->connectTo(mixer); | |
| players[shuffleIndex]->play(); | |
| players[shuffleIndex]->setLoop(true); | |
| } | |
| } | |
| //-------------------------------------------------------------- | |
| void ofApp::exit(){ | |
| stream.stop(); | |
| stream.close(); | |
| } | |
| //-------------------------------------------------------------- | |
| void ofApp::draw(){ | |
| if(ofGetElapsedTimef() > 2){ | |
| mixerRenderer.draw(600,700); | |
| } | |
| // mixerRenderer. | |
| stringstream ss; | |
| ss << "Press l key to load mixer settings." << endl; | |
| ss << "Press s key to save mixer settings." << endl; | |
| ss << "Press e key to toggle slider's mouse interaction." << endl; | |
| ss << "Press n key to toggle non-slider mode."; | |
| #ifdef OFX_SOUND_ENABLE_MULTITHREADING | |
| ss << endl << "Press the space bar to load more audio file players"; | |
| #endif | |
| ofBitmapFont bf; | |
| stringstream ss2; | |
| ss2 << "Sliders enabled: " << (mixerRenderer.isSlidersEnabled()?"YES":"NO") << endl; | |
| ss2 << "Non Slider Mode: " << (mixerRenderer.isNonSliderMode()?"YES":"NO") << endl; | |
| auto r2 = bf.getBoundingBox(ss2.str(), 0, 0); | |
| r2.x = ofGetWidth() - 20 - r2.width; | |
| ofDrawBitmapStringHighlight(ss2.str(), r2.x, 20); | |
| auto r = bf.getBoundingBox(ss.str(), 0, 0); | |
| r.x = r2.x - 20 - r.width; | |
| ofDrawBitmapStringHighlight(ss.str(), r.x, 20); | |
| } | |
| //-------------------------------------------------------------- | |
| void ofApp::keyPressed(int key){ | |
| } | |
| //-------------------------------------------------------------- | |
| void ofApp::keyReleased(int key){ | |
| if(key == 's'){ | |
| mixer.save(mixerSettingsXmlPath); | |
| }else if(key == 'l'){ | |
| mixer.load(mixerSettingsXmlPath); | |
| }else if(key == 'e'){ | |
| mixerRenderer.toggleSliders(); | |
| }else if(key == 'n'){ | |
| mixerRenderer.setNonSliderMode(!mixerRenderer.isNonSliderMode()); | |
| } | |
| // else if(key == ' '){ | |
| //// loadFolder(loadPath); | |
| // } | |
| if(key == ' '){ | |
| if(recorder.isRecording()){ | |
| recorder.stopRecording(); | |
| ofLog()<<"recorder.stopRecording();"; | |
| stopRecTimer = ofGetElapsedTimef(); | |
| bNewRecording = true; | |
| }else{ | |
| recFileName = ofToDataPath(ofGetTimestampString()+".wav",true); | |
| recorder.startRecording(recFileName); | |
| ofLog()<<"startRecording "<<recFileName; | |
| } | |
| } | |
| } | |
| //-------------------------------------------------------------- | |
| void ofApp::mouseMoved(int x, int y ){ | |
| } | |
| //-------------------------------------------------------------- | |
| void ofApp::mouseDragged(int x, int y, int button){ | |
| } | |
| //-------------------------------------------------------------- | |
| void ofApp::mousePressed(int x, int y, int button){ | |
| } | |
| //-------------------------------------------------------------- | |
| void ofApp::mouseReleased(int x, int y, int button){ | |
| } | |
| //-------------------------------------------------------------- | |
| void ofApp::mouseEntered(int x, int y){ | |
| } | |
| //-------------------------------------------------------------- | |
| void ofApp::mouseExited(int x, int y){ | |
| } | |
| //-------------------------------------------------------------- | |
| void ofApp::windowResized(int w, int h){ | |
| } | |
| //-------------------------------------------------------------- | |
| void ofApp::gotMessage(ofMessage msg){ | |
| } | |
| //-------------------------------------------------------------- | |
| void ofApp::dragEvent(ofDragInfo dragInfo){ | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #pragma once | |
| #include "ofMain.h" | |
| #include "ofxSoundObjects.h" | |
| #include "ofxSoundObjectMatrixMixerRenderer.h" | |
| #include "ofxSoundRecorderObject.h" | |
| class ofApp : public ofBaseApp{ | |
| public: | |
| void setup(); | |
| void update(); | |
| void draw(); | |
| void exit(); | |
| void keyPressed(int key); | |
| void keyReleased(int key); | |
| void mouseMoved(int x, int y ); | |
| void mouseDragged(int x, int y, int button); | |
| void mousePressed(int x, int y, int button); | |
| void mouseReleased(int x, int y, int button); | |
| void mouseEntered(int x, int y); | |
| void mouseExited(int x, int y); | |
| void windowResized(int w, int h); | |
| void dragEvent(ofDragInfo dragInfo); | |
| void gotMessage(ofMessage msg); | |
| ofSoundStream stream; | |
| ofxSoundMatrixMixer mixer; | |
| ofxSoundMatrixMixerRenderer mixerRenderer; | |
| ofxSoundInput input; | |
| vector<shared_ptr<ofxSoundPlayerObject>> players; | |
| size_t inDeviceIndex, outDeviceIndex; | |
| string mixerSettingsXmlPath; | |
| bool bSettingsLoaded = false; | |
| string loadPath; | |
| void loadFolder(const string& path); | |
| //recorder | |
| ofxSoundRecorderObject recorder; | |
| int shuffleIndex; | |
| string recFileName; | |
| bool bNewRecording; | |
| float stopRecTimer; | |
| }; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment