Skip to content

Instantly share code, notes, and snippets.

@antimodular
Created May 13, 2019 20:27
Show Gist options
  • Save antimodular/8e9291dfd5e995d120380150a0fc474f to your computer and use it in GitHub Desktop.
Save antimodular/8e9291dfd5e995d120380150a0fc474f to your computer and use it in GitHub Desktop.
#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());
}
#pragma once
#include "ofMain.h"
#include "ofxAudioUnit.h"
#include "ofxAudioUnitUtils.h"
#include "MatrixMixerVolumes.h"
#include "ofxSimpleGuiToo.h"
#define USE_ARTNET
#ifdef USE_ARTNET
#include "ofxArtnet.h"
#else
#include "ofxDmx.h"
#endif
#ifdef __OBJC__
#import <AVFoundation/AVFoundation.h>
class ofApp;
@interface RecordDelegate : NSObject<AVAudioRecorderDelegate>
{
ofApp * _app;
}
@property (nonatomic, assign) ofApp * app;
@end
#else
typedef void AVCaptureAudioFileOutput;
typedef void RecordDelegate;
typedef void AVAudioRecorder;
#endif
//#define USE_LOOP //use loop only durng performance
//#define PERFORMANCE_MODE
#define maxOutputDevices 1
#define NUMBER_OF_MICS 1
#define NUMBER_OF_OUT_CHANNELS 23 // 17 in rio with 16 speakers + one for intercom
//---------30 battens
#define NUMBER_OF_DMX_CHANNELS 768 //= 24 battens //960 = 30 battens // =??? NUMBER_OF_FILE_PLAYERS * NUMBER_OF_LEDS_PER_FILE
#ifdef PERFORMANCE_MODE
//192x5, 160x6, 120x8, 96x10, 80x12, 64x15, 60x16, 48x20, 30x32, 12x80
//#define NUMBER_OF_LEDS_PER_FILE 16 //5 //
//#define NUMBER_OF_FILE_PLAYERS 60 //192 // = 960/?
//#define NUMBER_OF_INPUT_BUSSES 61 //193 //
//#define NUMBER_OF_IN_CHANNELS 122 //386 //
#define NUMBER_OF_LEDS_PER_FILE 34 //60// NUMBER_OF_DMX_CHANNELS / NUMBER_OF_FILE_PLAYERS = NUMBER_OF_LEDS_PER_FILE; i.e. how many audio files do in to one speaker
#define NUMBER_OF_FILE_PLAYERS 22 //16 //192 // = 960/?
#define NUMBER_OF_INPUT_BUSSES 23 //17 //193 //
//#define NUMBER_OF_IN_CHANNELS 46 //34 //386 //
#else
#define NUMBER_OF_LEDS_PER_FILE 1
#define NUMBER_OF_FILE_PLAYERS 768 //961 //78
#define NUMBER_OF_INPUT_BUSSES 769 //962 //79 //
//#define NUMBER_OF_IN_CHANNELS 1538 //1924 // (78+1) x 2
#endif
class ofApp : public ofBaseApp{
public:
void setup();
void exit();
void update();
void draw();
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 windowResized(int w, int h);
void dragEvent(ofDragInfo dragInfo);
void gotMessage(ofMessage msg);
void startRecording(string filePath);
void stopRecording();
void finishedRecording(string filePath);
void deleteRecFile(string t_fileName);
void censorRecFile(string t_fileName);
string addCuratedFile();
void goBackOneStep();
void updateDMX_usb();
void updateDMX_artNet();
void allDmxOff();
void drawDMX(ofPoint windowPos, float windowWidth, float windowHeight);
void drawInputBuss(ofPoint windowPos, float windowWidth, float windowHeight);
void drawMatrixMixer(ofPoint windowPos, float windowWidth, float windowHeight);
void drawOutput(ofPoint windowPos, float windowWidth, float windowHeight);
void saveLevel(string _fileName, float _level);
float loadLevel(string _fileName);
void updateAllMatrixMixerLevels();
void clearAllCossPoints();
void setNormalCrossPointDistribution(float _level);
void setMasterVolume(float _level);
void setAllOutputLevels(float _level);
void setInputRangeToOutputChannel(int _startInputBuss, int _stopInputBuss, int _outputChannel);
void setCrossPoint(int _inputBuss, int _outputChannel, float _level);
void setAllCrossPoints(float _level);
void setAllDmxCrossPointsForPerformance();
bool bMouseIsPressed, bMouseIsReleased;
bool bMouseDoublePressed;
int state;
bool bStopViaKeyRelease;
//---gui
string version;
bool bShowGui;
bool bDebug;
bool bExit;
bool bShowInputBussWindow;
bool bShowMatrixWindow;
bool bShowOutputChannelWindow;
bool bShowMicWindow;
bool bShowDMX;
bool bInverseDmx;
ofTrueTypeFont franklinBook8;
ofTrueTypeFont franklinBook14;
ofTrueTypeFont franklinBook30;
bool muteAllOutputs, old_muteAllOutputs;
bool initDone;
int initStage;
//------led button
bool bLedButtonPressed,bLedButtonReleased;
int ledButtonBrightness;
//--------mic
bool bFoundMic;
int micDeviceID;
ofxAudioUnitTap micTap;
ofxAudioUnitInput micInput;
AVAudioRecorder * recorder;
RecordDelegate * recordDelegate;
string newFileName;
float micLevel;
bool bMakeMicActive, old_bMakeMicActive;
float intercomOutputLevel;
//------recording
bool bStartRecording,bStopRecording,bCheckRecFile;
bool bRecFileSaved;
bool bIsRecording; //current state of recording process
float recDuration, recStartTime;
string recFileName;
float minRecDuration;
int maxRecDuration;
int trimLastRecLength;
int trimEndCycles;
int recWaitTime;
float recWaitTimer;
//-----sounds
ofDirectory dir;
int dirSize;
int availableDeviceCount;
vector <int> availableDeviceIDs;
vector <string> avalaibleDeviceNames;
int numOfOutputDevices;
// int tracksPerOutputDevice;
// int numOfOutputChannels;
int deviceID_list[maxOutputDevices];
int firstSoundIndex;
string localRecordingsFolder;
//ofxAudioUnitFilePlayer source1, source2, source3;
ofxAudioUnitFilePlayer filePlayers[NUMBER_OF_FILE_PLAYERS];
unsigned long startPlayheadTime[NUMBER_OF_FILE_PLAYERS];
ofxAudioUnitTap taps[NUMBER_OF_INPUT_BUSSES];
string fileNames[NUMBER_OF_FILE_PLAYERS];
//ofxAudioUnitMixer mixer;
int numOfInputTaps;
ofxAudioUnitMatrixMixer mMixer; //(3,24);
bool bUpdateMixerLevels;
ofxAudioUnitOutput output[maxOutputDevices];
// int outputDeviceAmount;
float inputTapLevels[NUMBER_OF_INPUT_BUSSES];
float masterVolume,old_masterVolume;
float masterOutputLevel, old_masterOutputLevel;
float masterCrossLevel, old_masterCrossLevel;
Float32 levels[NUMBER_OF_INPUT_BUSSES*2 + 1][NUMBER_OF_OUT_CHANNELS + 1];
int dmx_to_in_Index[NUMBER_OF_DMX_CHANNELS]; //NUMBER_OF_FILE_PLAYERS];
bool mouseInsideInputBussWindow;
bool mouseInsideMatrixWindow;
bool mouseInsideOutputWindow;
//-------dmx
//
#ifdef USE_ARTNET
ofxArtnet artnetDMX;
string artnetIPs[2];
#else
ofxDmx dmx[2];
#endif
unsigned char values[512];
unsigned char dmx_values[2][512];
// int soundDmxChannels;
int allDmxChannels; //since we have a dmx light inside the push button
int dmx_channelAmount[2];
int dmx_universe;
bool bAllOFF,bAllON;
int dimStates[NUMBER_OF_FILE_PLAYERS];
bool bRouteVolumeToDMX;
float brightnessMultiplier;
// float minLevelThreshold;
float levelCurve;
int minBrightness,maxBrightness;
bool bChase, old_bChase;
unsigned long chaseTimer;
int chaseSpeed;
int caseCnt;
int dmxChannelNum, old_dmxChannelNum;
int dmxSilderValue, old_dmxSilderValue;
bool bBuildUp;
//-----
int populationStage;
bool bPopulate;
float populateTimer;
int populationCounter;
int populationSteps;
float populationTiming[NUMBER_OF_OUT_CHANNELS];
int populationTimingCutOff;
float popStepsPerTime;
bool bCensorRecording;
bool bAllOutZero, old_bAllOutZero;
float popTime;
int temp_mappedY;
int temp_mappedX;
float maxInputLevel[NUMBER_OF_INPUT_BUSSES];
float rollingInputMax;
int popLowLight;
ofxAudioUnit delays[NUMBER_OF_INPUT_BUSSES];
// ofxAudioUnitTap delay_taps[NUMBER_OF_INPUT_BUSSES];
int dryAndWet,cutoff,feedback;
float delayTime;
int old_dryAndWet,old_cutoff,old_feedback;
float old_delayTime;
float manualPeakRMS;
float measuredPeakRMS;
// UInt32 fileLength[NUMBER_OF_FILE_PLAYERS];
int fileLength[NUMBER_OF_FILE_PLAYERS];
float playTimer[NUMBER_OF_FILE_PLAYERS];
float playDuration[NUMBER_OF_FILE_PLAYERS];
float minClipLength;
float minClipWithPause, maxClipWithPause;
float filesPerOutput;
float oldestFileLevel_accum;
int oldestFileLevel_cnt;
unsigned long lastTap;
bool bTest;
};
#include "ofApp.h"
//https://gist.github.com/admsyn/00ef95aa58a2202ff87d
//enttec opendmx ethernet setup
//download NMU config app here: http://www.enttec.com/?main_menu=Products&pn=79001
//connect enttecs to ethernet switch and computer to same switch
//give computer manual IP 192.168.0.101
//maybe you need to turn off airport
//open NMU ->select the just entered IP ->discovery devices
//their ip address were by default 10.7.124.27 and 10.7.105.37
//don't change them
//changes
/*
switch order of mic.start and mic.tap
censor keypressed to keyrekeased
click on output channel and hear + see only that channel
click on input channel and hear + see only that channel
start with populationSteps = 0;
*/
//int mic_waveWindowWidth = 256;
//int mic_waveWindowHeight = 256;
//ofPoint mic_windowPos = ofPoint(10,file_windowPos.y+file_waveWindowHeight+5);
//--------------------------------------------------------------
void ofApp::setup()
{
version = "v16";
// ofSetVerticalSync(true);
ofSetBackgroundColor(0);
ofTrueTypeFont::setGlobalDpi(72);
franklinBook8.loadFont("frabk.ttf", 8);
franklinBook8.setLineHeight(10);
franklinBook8.setLetterSpacing(1.037);
franklinBook14.loadFont("frabk.ttf", 14);
franklinBook14.setLineHeight(18.0f);
franklinBook14.setLetterSpacing(1.037);
franklinBook30.loadFont("frabk.ttf", 30, true, true);
franklinBook30.setLineHeight(34.0f);
franklinBook30.setLetterSpacing(1.035);
#ifdef PERFORMANCE_MODE
gui.addTitle("voice array "+version+" performance", 20);
#else
gui.addTitle("voice array "+version, 20);
#endif
gui.addButton("quit", bExit);
gui.addToggle("bDebug", bDebug);
gui.addToggle("show gui", bShowGui);
gui.addToggle("show input", bShowInputBussWindow);
gui.addToggle("show matrix", bShowMatrixWindow);
gui.addToggle("show output", bShowOutputChannelWindow);
gui.addToggle("show dmx", bShowDMX);
gui.addButton("censor", bCensorRecording);
gui.addTitle();
gui.addSlider("master volume", masterVolume, 0, 1);
gui.addSlider("masterOutputLevel", masterOutputLevel, 0, 1);
gui.addSlider("masterCrossLevel", masterCrossLevel, 0, 1);
gui.addToggle("mute all", muteAllOutputs);
gui.addToggle("all out 0", bAllOutZero);
gui.addTitle("mic");
// gui.addButton("start rec", bStartRecording);
// gui.addButton("stop rec", bStopRecording);
gui.addToggle("is recording", bIsRecording);
gui.addSlider("min recLength", minRecDuration, 0, 60);
gui.addSlider("max recLength", maxRecDuration, 0, 60*3);
gui.addSlider("trim end cycles", trimLastRecLength, 0, 10000);
gui.addSlider("recWaitTime", recWaitTime, 0, 5);
gui.addToggle("mic on", bMakeMicActive);
gui.addSlider("manualPeakRMS", manualPeakRMS, 0, 1);
gui.addSlider("measPeakRMS", measuredPeakRMS, 0, 5);
gui.addToggle("stopViaKeyRelease",bStopViaKeyRelease);
gui.addSlider("intercom out level", intercomOutputLevel, 0, 1);
gui.addTitle("dmx");
gui.addButton("all off", bAllOFF);
gui.addButton("all on", bAllON);
gui.addSlider("dmx universe", dmx_universe, 0, 1);
gui.addSlider("dmxChannelNum", dmxChannelNum, 0, NUMBER_OF_DMX_CHANNELS); //960);
gui.addSlider("dmxSilderValue", dmxSilderValue, 0, 255);
gui.addToggle("chase", bChase);
gui.addSlider("chaseSpeed", chaseSpeed, 0, 500);
gui.addToggle("bRouteVolumeToDMX", bRouteVolumeToDMX);
// gui.addSlider("min thresh", minLevelThreshold, 0, 0.5);
gui.addSlider("level curve", levelCurve, 1, 2);
gui.addSlider("push brightness", brightnessMultiplier, 0, 5); //50);
gui.addSlider("min brightness", minBrightness, 0, 255);
gui.addSlider("max brightness", maxBrightness, 0, 255);
gui.addToggle("inverseDmx",bInverseDmx);
// gui.addToggle("bBuildUp", bBuildUp);
gui.addTitle("population");
gui.addSlider("pop time", popTime, 0, 1);
gui.addSlider("first x pause", populationTimingCutOff,0,5);
gui.addSlider("1st pause", populationTiming[0],0,10);
gui.addSlider("2nd pause", populationTiming[1],0,10);
gui.addSlider("3rd pause", populationTiming[2],0,10);
gui.addSlider("4th pause", populationTiming[3],0,10);
gui.addSlider("5th pause", populationTiming[4],0,10);
gui.addSlider("low light", popLowLight, 0, 255);
gui.addSlider("popStepsPerTime", popStepsPerTime, 0, 100);
gui.addTitle("loop settings");
gui.addSlider("minClipLength", minClipLength, 0, 10);
gui.addSlider("minClipWithPause", minClipWithPause, 0, 10);
gui.addSlider("maxClipWithPause", maxClipWithPause, 0, 10);
gui.loadFromXML();
//gui.setAutoSave(false);
//gui.setDefaultKeys(true);
gui.show(); //hide();
//ofHideCursor();
// gui.bShowHeader = true; //false;
bShowGui = false;
bDebug = false; //true; //
old_masterVolume = -1;
old_masterOutputLevel = -1;
old_masterCrossLevel = masterCrossLevel; //-1;
muteAllOutputs = false;
old_muteAllOutputs = muteAllOutputs;
bMakeMicActive = false;
old_bMakeMicActive = bMakeMicActive;
bCensorRecording = false;
bAllOutZero = false;
old_bAllOutZero = false;
popStepsPerTime = 1;
//int NUMBER_OF_FILE_PLAYERS = 90;
bIsRecording = false;
//check which input and output devices
bFoundMic = false;
micDeviceID = 0;
output[0].listOutputDevices();
// ofLog()<<"outputDeviceAmount "<<outputDeviceAmount;
availableDeviceCount = 0;
numOfOutputDevices = 0;
string tempOutputName = "";
for(int i=0; i<output[0].outputDeviceAmount; i++){
int temp_id = output[0].deviceIDArray[i];
string temp_name = output[0].deviceNameArray[i];
if(temp_id >0){
availableDeviceCount++;
availableDeviceIDs.push_back(temp_id);
avalaibleDeviceNames.push_back(temp_name);
if(temp_name == "Aggregate Device"){ //"PCI-424"){ // || temp_name == "M-Audio Fast Track"){
deviceID_list[numOfOutputDevices] = temp_id;
tempOutputName = temp_name;
numOfOutputDevices++;
// cout<<"found the Aggregate Device "<<endl;
}
/*
if(temp_name == "MOTU UltraLite mk3 Hybrid"){ //"Fast Track"){ //"Blue Snowflake"){ // || temp_name == "Built-in Microphone" || temp_name == "Built-in Input"){
micDeviceID = temp_id;
bFoundMic = true;
cout<<"found mic "<<endl;
}
*/
cout<<i<<" deviceIDArray "<<temp_id<<endl;
}
}
cout<<"found "<<numOfOutputDevices<<" Aggregate Device for output"<<endl;
// micInput.configureInputDevice(micDeviceID);
// tracksPerOutputDevice = NUMBER_OF_FILE_PLAYERS; //is different when using multiple devices
// numOfInputTaps = NUMBER_OF_OUT_CHANNELS + NUMBER_OF_MICS;
// numOfOutputChannels = numOfOutputDevices*tracksPerOutputDevice;
//output.listOutputDevices();
// output.setDevice(34, channelInputMap);
output[0].setDevice(tempOutputName); //"Focusrite RedNet PCIe Card"); // <- should set the device before the stream format
AudioStreamBasicDescription ASBD = {
.mSampleRate = 44100,
.mFormatID = kAudioFormatLinearPCM,
.mFormatFlags = kAudioFormatFlagsAudioUnitCanonical,
.mChannelsPerFrame = NUMBER_OF_OUT_CHANNELS, // <- change this to 24 in your case
.mFramesPerPacket = 1,
.mBitsPerChannel = sizeof(AudioUnitSampleType) * 8,
.mBytesPerPacket = sizeof(AudioUnitSampleType),
.mBytesPerFrame = sizeof(AudioUnitSampleType)
};
OFXAU_PRINT(AudioUnitSetProperty(output[0],
kAudioUnitProperty_StreamFormat,
kAudioUnitScope_Input,
0,
&ASBD,
sizeof(ASBD)),
"setting output unit's input ASBD");
// setting mixer to have 960 input busses, 1 output bus and use the
// 24 channel stream format on its output bus
mMixer.setChannelLayout(NUMBER_OF_INPUT_BUSSES, 1, NULL, &ASBD);
string userName = getenv("USER");
localRecordingsFolder = "/Users/"+userName+"/Desktop/recordings_sound/";
/*
#ifdef PERFORMANCE_MODE
cout<<"rename old sounds folder"<<endl;
//dir.removeDirectory("sounds",true);
ofDirectory tempDir("sounds");
tempDir.renameTo("sounds_"+ofGetTimestampString(),true,true);
cout<<"create new sounds folder that is now empty"<<endl;
tempDir.createDirectory("sounds");
#endif
*/
cout<<"------------- load files -------------"<<endl;
dir.listDir(localRecordingsFolder); //"sounds/");
//load files and connect to tap and mixer
//if not enough files exist only load whats there
//tap 0 is the mic, so the files start connecting with 1, so are the mixer input bus connections
//that's why you will see temp_cnt+1
int temp_cnt = 0;
dirSize = dir.size();
if(dirSize < NUMBER_OF_FILE_PLAYERS) cout<<"ERROR not enough files in sound folder"<<endl;
int ii = 0;
while(temp_cnt < NUMBER_OF_FILE_PLAYERS && temp_cnt < dirSize){
fileNames[temp_cnt] = dir.getName(dirSize - 1 - ii);
int ty = (dirSize - 1 - ii);
bool b_fileLoaded = filePlayers[temp_cnt].setFile(localRecordingsFolder+fileNames[temp_cnt]);
// cout<<endl;
cout<<temp_cnt<<" "<<ty<<"/"<<dir.size()<<" fileNames[temp_cnt] "<<fileNames[temp_cnt]<<endl;
// bool b_fileLoaded = filePlayers[temp_cnt].setFile(ofToDataPath("sounds/")+fileNames[0]);
// bool b_fileLoaded = filePlayers[temp_cnt].setFile(ofToDataPath("sounds/test.m4a"));
if(b_fileLoaded == false){
cout<<"load error "<<temp_cnt<<" , "<<ii<<" , "<<(dirSize - 1 - ii)<<" , "<<dir.getName(dirSize - 1 - ii)<<endl;
}else{
//cout<<temp_cnt<<" "<<ii<<" file path "<<ofFilePath::getAbsolutePath("sounds/"+fileNames[temp_cnt])<<endl;
temp_cnt++;
cout<<" ";
}
ii++;
}
cout<<"add files to fileplayer array"<<endl;
for(int i =0; i<NUMBER_OF_FILE_PLAYERS; i++){
fileLength[i] = -1;
}
for(int i =0; i<temp_cnt; i++){
//filePlayers[i].prime();
}
for(int i =0; i<temp_cnt; i++){
// int temp_cnt2 = tempNum[i];
UInt32 framesToPlay = filePlayers[i].getLength();
framesToPlay = framesToPlay - trimLastRecLength;// replace with however many frame you want to trim
fileLength[i] = framesToPlay; //filePlayers[temp_cnt].getLength();
// cout<<i<<" fileLength[i] "<<fileLength[i]<<endl;
playTimer[i] = ofGetElapsedTimef();
// playDuration[temp_cnt] = fileLength[temp_cnt]/44100.0; //ofRandom(minClipWithPause,maxClipWithPause);
playDuration[i] = ofRandom(minClipWithPause,maxClipWithPause);
filePlayers[i].setLength(framesToPlay);
// taps[temp_cnt+1].setBufferLength(256);
filePlayers[i].connectTo(taps[i+1]);
if(filePlayers[i].getLength() > 0){
//filePlayers[i].loop();//play(); //
#ifdef USE_LOOP
filePlayers[i].loop();
filePlayers[i].loop();
filePlayers[i].loop();
#else
filePlayers[i].play();
#endif
}
// filePlayers[i].loop(); //loop();
taps[i+1].connectTo(mMixer, i+1); // connect file player x to mixer input bus y
}
cout<<"files loaded and connected = "<<temp_cnt<<endl;
cout<<"---- set mic and recrodings ----"<<endl;
recordDelegate = [[RecordDelegate alloc] init];
recordDelegate.app = this;
micInput.connectTo(taps[0]);
micInput.start();
taps[0].connectTo(mMixer,0);
mMixer.connectTo(output[0]);
output[0].start();
cout<<"------- set matrix mixer levels -------"<<endl;
firstSoundIndex = NUMBER_OF_INPUT_BUSSES -1 ;// NUMBER_OF_FILE_PLAYERS - 1;
clearAllCossPoints();
// setting the global output volume to 1
setMasterVolume(masterVolume);
//set the input volume of each file player, each player has two channels because they are stereo by default
//and each mic
for(int i = 0; i< NUMBER_OF_INPUT_BUSSES; i++){
//load level from text file
int in_left = i*2;
int in_right = i*2+1;
if(i == 0){
levels[in_left][NUMBER_OF_OUT_CHANNELS] = 1;
levels[in_right][NUMBER_OF_OUT_CHANNELS] = 1;
maxInputLevel[0] = 1;
}else{
string temp_name = fileNames[i-1];
//cout<<"temp_name.substr(0,4) "<<temp_name.substr(0,4)<<endl;
float temp_level;
if(temp_name.substr(0,4) == "2013" ) temp_level = 1;
else temp_level = loadLevel(fileNames[i-1]);
levels[in_left][NUMBER_OF_OUT_CHANNELS] = temp_level; //0.2;
levels[in_right][NUMBER_OF_OUT_CHANNELS] = temp_level; //0.2;
maxInputLevel[i] = temp_level;
}
}
for(int i=0; i<NUMBER_OF_FILE_PLAYERS; i++){
for(int c=0; c<NUMBER_OF_LEDS_PER_FILE; c++){
int _idx = i*NUMBER_OF_LEDS_PER_FILE + c;
// cout<<i<<" "<<NUMBER_OF_LEDS_PER_FILE<<", c "<<c<<"_idx "<<_idx<<endl;
dmx_to_in_Index[_idx] = i+1; //+1 because input 0 is mic and does not have a dmx
// cout<<"_idx "<<_idx<<", dmx_to_in_Index[_idx] "<<dmx_to_in_Index[_idx]<<endl;
}
}
cout<<"done loading input levels"<<endl;
// set the volume of output channel i
setAllOutputLevels(masterOutputLevel);
//set level of cross points
//start with 1, since 0 is for mic
filesPerOutput = NUMBER_OF_FILE_PLAYERS / float(NUMBER_OF_OUT_CHANNELS-1);
cout<<"amount of file per out channel "<<filesPerOutput<<endl;
#ifdef PERFORMANCE_MODE
setAllCrossPoints(masterCrossLevel);
#else
setNormalCrossPointDistribution(masterCrossLevel);
#endif
//set mic cross point levels
setCrossPoint(0, 0, 0.0013);
//set input 1 to output 0; i.e. intercom speaker
// setCrossPoint(1, 0, intercomOutputLevel);
OFXAU_PRINT(AudioUnitSetProperty(mMixer,
kAudioUnitProperty_MatrixLevels,
kAudioUnitScope_Global,
0,
levels,
sizeof(levels)),
"setting matrix volume levels");
cout<<"-------- write matrix mixer array to text file ---------"<<endl;
FILE * debugFile = fopen(ofToDataPath("MatrixMixerVolumes.txt").c_str(),"w"); //fopen("/Users/Adam/Desktop/MatrixMixerVolumes.txt", "w");
PrintMatrixMixerVolumes(debugFile, mMixer);
fclose(debugFile);
mouseInsideInputBussWindow = false;
mouseInsideMatrixWindow = false;
mouseInsideOutputWindow = false;
mMixer.enableOutputMetering();
//----dmx
bChase = false;
old_bChase = !bChase;
old_dmxChannelNum = dmxChannelNum;
old_dmxSilderValue = dmxSilderValue;
// soundDmxChannels = NUMBER_OF_FILE_PLAYERS+NUMBER_OF_MICS;
allDmxChannels = NUMBER_OF_FILE_PLAYERS*NUMBER_OF_LEDS_PER_FILE; //soundDmxChannels + 1; //1 for the dmx controlled led button
cout<<"allDmxChannels = "<<allDmxChannels<<endl;
caseCnt = 1;
//channelsAmount = 512;
//dmx.connect("tty.usbserial-EN092209",channelsAmount); // use the name //ENR2NQEU
dmx_channelAmount[1] = 448; //allDmxChannels / 2 ;//filesPerOutput*(NUMBER_OF_OUT_CHANNELS-1)/2; // NUMBER_OF_FILE_PLAYERS / 2;
dmx_channelAmount[0] = 320; //allDmxChannels - dmx_channelAmount[0];
cout<<"dmx has 2 universes with a = "<<dmx_channelAmount[0]<<", and b = "<<dmx_channelAmount[1]<<" channels "<<endl;
#ifdef USE_ARTNET
ofLog()<<"make sure the firewall is deactivated at this point";
//interface IPs
artnetIPs[1] = "10.7.124.27"; //"192.168.0.160";
artnetIPs[0] = "10.7.105.37"; //"192.168.0.161";
//this computer's IP
artnetDMX.setup("192.168.0.101");
#else
//EN092197
// dmx[0].connect("tty.usbserial-EN092197",dmx_channelAmount[0]); // use the number
// dmx[1].connect("tty.usbserial-ENR2OJHK",dmx_channelAmount[1]);
// dmx[0].connect(0,dmx_channelAmount[0]); // use the number
// dmx[1].connect(2,dmx_channelAmount[1]);
#endif
//------led button
state = 0;
/*
ledButtonBrightness = 255;
out 0 = 0;
all others = 1
*/
ledButtonBrightness = 255;
bLedButtonPressed = false;
bLedButtonReleased = false;
bMouseIsPressed = false;;
bMouseIsReleased = false;
bMouseDoublePressed = false;
ofSleepMillis(2000);
initDone = false;
ofLog()<<"setup done";
ofSetFullscreen(true);
}
void ofApp::exit(){
for(int i = 0; i < numOfOutputDevices; i++){
output[i].stop();
}
micInput.stop();
dir.close();
allDmxOff();
cout<<"-------- write matrix mixer array to text file ---------"<<endl;
FILE * debugFile = fopen(ofToDataPath("MatrixMixerVolumes.txt").c_str(),"w"); //fopen("/Users/Adam/Desktop/MatrixMixerVolumes.txt", "w");
PrintMatrixMixerVolumes(debugFile, mMixer);
fclose(debugFile);
std::exit(1);
}
//--------------------------------------------------------------
void ofApp::update(){
if(bTest == false){
for(int i=0; i<NUMBER_OF_FILE_PLAYERS; i++){
startPlayheadTime[i] = filePlayers[i].getPlayheadPos();
// ofLog()<<"test "<<i<<" play getPlayheadPos "<<filePlayers[i].getPlayheadPos()<<" , "<<filePlayers[i].getCurrentTimestamp().mSampleTime<<" , "<<fileLength[i]<<" , "<<filePlayers[i].getStartTimestamp();
}
}
if(initDone == false){
initDone = true;
allDmxOff();
}
if(bExit == true) exit();
if(muteAllOutputs != old_muteAllOutputs){
old_muteAllOutputs = muteAllOutputs;
AudioUnitSetParameter(mMixer, kMatrixMixerParam_Enable, kAudioUnitScope_Output, 0, !muteAllOutputs, 0);
}
if(masterVolume != old_masterVolume){
old_masterVolume = masterVolume;
setMasterVolume(masterVolume);
}
if(masterOutputLevel != old_masterOutputLevel){
old_masterOutputLevel = masterOutputLevel;
setAllOutputLevels(masterOutputLevel);
}
if(masterCrossLevel != old_masterCrossLevel){
old_masterCrossLevel = masterCrossLevel;
#ifdef PERFORMANCE_MODE
setAllCrossPoints(masterCrossLevel);
#else
setNormalCrossPointDistribution(masterCrossLevel);
#endif
}
//send all inputs out channel 0, for monitoring purposes.
if(bAllOutZero != old_bAllOutZero){
old_bAllOutZero = bAllOutZero;
//start at 0 because we have seperate gui controll for mic
setInputRangeToOutputChannel(1,NUMBER_OF_INPUT_BUSSES,0);
}
if(bUpdateMixerLevels == true){
bUpdateMixerLevels = false;
updateAllMatrixMixerLevels();
}
//---get each taps level, which will be send to dmx
for(int i = 0; i < NUMBER_OF_INPUT_BUSSES; i++){
int temp_num = i;
if(temp_num == 0 ){
//take mic's left and right channel and get a mix of them
inputTapLevels[temp_num] = (taps[temp_num].getLeftChannelRMS()+taps[temp_num].getRightChannelRMS())/2.0;
}
else{
//just get level from left side of stereo file
// inputTapLevels[temp_num] = taps[temp_num].getLeftChannelRMS();
inputTapLevels[temp_num] = (taps[temp_num].getLeftChannelRMS()+taps[temp_num].getRightChannelRMS()) / 2.0; //ofMap(taps[temp_num].getLeftChannelRMS(),0,0.,0,1);
// cout<<"temp_num "<<inputTapLevels[temp_num]<<endl;
// if(inputTapLevels[temp_num] <= 0){
// cout<<"temp_num "<<temp_num<<" "<<inputTapLevels[temp_num]<<endl;
// filePlayers[temp_num].loop();
// }
inputTapLevels[temp_num] = ofMap(inputTapLevels[temp_num],0,manualPeakRMS,0,1,true);
}
temp_num++;
temp_num = temp_num % NUMBER_OF_INPUT_BUSSES;
}
//---check LED button
if(bIsRecording == true && recDuration >= maxRecDuration){
bLedButtonPressed = false;
cout<<"Stop recording because recDuration > "<<maxRecDuration<< endl;
}
#ifdef PERFORMANCE_MODE
//in performance mode we do not have to wait for the population to be done
//we do not check recWaitTime
if(bLedButtonPressed == true){
if(bIsRecording == false){
//intercom button was pressed
//button has been pressed long enough; try to avoid quick clicking
//start recording process
//recWaitTimer = ofGetElapsedTimef();
bStartRecording = true;
ledButtonBrightness = 30;
rollingInputMax = 0;
state = 1;
//clear all cross points
clearAllCossPoints();
//set cross points for out channel 0 to input buss 0 to 0
//i.e. prevent that mic plays through intercom speaker
setCrossPoint(0,0,0.00123);
setCrossPoint(1,0,0.00021); // <#int _outputChannel#>, <#float _level#>)
//ofSleepMillis(100);
//set dmx to get levels from mic; i.e input tap 0 = mic input level mix left+right
// the 0 refers to pos 0 in array that holds the the rms levels which we got in update loop
// out_to_in_Index[0] = 0;
// out_to_in_Index[1] = 0;
for(int i=0; i<allDmxChannels; i++){
dmx_to_in_Index[i] = 0;
}
}else{
//button is pressed
if(recDuration > minRecDuration){
//indicate that we just past the minimum required recording time
ledButtonBrightness = 150;
}
//this is on-going during recording process
//measure input's max levels
if(inputTapLevels[0] > rollingInputMax) rollingInputMax = inputTapLevels[0];
if(rollingInputMax > measuredPeakRMS) measuredPeakRMS = rollingInputMax;
}
}else{
//intercom button not pressed
if(bIsRecording == true){
//we were recording
//button just got released
//stop recording process
bStopRecording = true;
ledButtonBrightness = 0;
}
}
#else
//non-performance
if(bLedButtonPressed == true && bPopulate == false){
if(bIsRecording == false && ofGetElapsedTimef()-recWaitTimer > recWaitTime){
//intercom button was pressed
//button has been pressed long enough; try to avoid quick clicking
//start recording process
//recWaitTimer = ofGetElapsedTimef();
bStartRecording = true;
ledButtonBrightness = 30;
rollingInputMax = 0;
state = 1;
//clear all cross points
clearAllCossPoints();
//set cross points for out channel 0 to input buss 0 to 0
//i.e. prevent that mic plays through intercom speaker
setCrossPoint(0,0,0.00123);
//set dmx to get levels from mic; i.e input tap 0 = mic input level mix left+right
// the 0 refers to pos 0 in array that holds the the rms levels which we got in update loop
// out_to_in_Index[0] = 0;
// out_to_in_Index[1] = 0;
for(int i=0; i<allDmxChannels; i++){
dmx_to_in_Index[i] = 0;
}
}else{
//button is pressed
if(recDuration > minRecDuration){
//indicate that we just past the minimum required recording time
ledButtonBrightness = 150;
}
//this is on-going during recording process
//measure input's max levels
if(inputTapLevels[0] > rollingInputMax) rollingInputMax = inputTapLevels[0];
if(rollingInputMax > measuredPeakRMS) measuredPeakRMS = rollingInputMax;
}
}else{
//intercom button not pressed
if(bIsRecording == true){
//we were recording
//button just got released
//stop recording process
bStopRecording = true;
ledButtonBrightness = 0;
}
}
#endif
// ledButtonBrightness ++;
// ledButtonBrightness %= 255;
if(bStartRecording == true ){
bStartRecording = false;
bIsRecording = true;
bRecFileSaved = false;
cout<<"Start recording\n";
recFileName=ofToString(ofGetTimestampString())+".m4a";
cout <<localRecordingsFolder<<recFileName<<"----\n";
startRecording(localRecordingsFolder+recFileName);
recStartTime = ofGetElapsedTimef();
}
if(bStopRecording == true && bIsRecording == true){
bStopRecording = false;
bCheckRecFile = true;
cout<<"Stop recording\n";
stopRecording();
}
if(bCheckRecFile == true && bRecFileSaved == true){
bCheckRecFile = false;
bIsRecording = false;
bRecFileSaved = false;
//at this point new rec file was saved
//we are ready for populating process
cout<<"recDuration "<<recDuration<<endl;
clearAllCossPoints();
//if recording was too short
if(recDuration < minRecDuration){
deleteRecFile(recFileName);
cout<<"delete file"<<recFileName<<" because duration "<<recDuration<<" < "<<minRecDuration;
ledButtonBrightness = 255;
#ifdef PERFORMANCE_MODE
setAllCrossPoints(masterCrossLevel);
#else
setNormalCrossPointDistribution(masterCrossLevel);
#endif
}else{
//if recording was long enough
if(bCensorRecording == true){
bCensorRecording = false;
censorRecFile(recFileName);
addCuratedFile();
cout<<"file "<<recFileName<<" got censored during recording"<<endl;
}
//the new recording will replace the oldest file in the array
//and connect it to it's tab, which at start is the last tap/buss
//play most recent sound file through intercom speaker; i.e. out channel 0
// cout<<"setCrossPoint(firstSoundIndex, 0, 0.907) "<<firstSoundIndex<<endl;
// setCrossPoint(firstSoundIndex, 0, 0.907);
// levels[firstSoundIndex*2][0] = 0.907; //left file player channel
// levels[firstSoundIndex*2+1][0] = 0.907;
/*
if(firstSoundIndex != 0){
levels[firstSoundIndex*2][0] = 0.907; //left file player channel
levels[firstSoundIndex*2+1][0] = 0.907;
}else{
//this is only for the first time, after start up
//for somereason i get feedback otherwise
levels[NUMBER_OF_FILE_PLAYERS*2][0] = 0.907; //left file player channel
levels[NUMBER_OF_FILE_PLAYERS*2+1][0] = 0.907;
}
*/
// levels[0][0] = 0; //set mic to not output to output channel 0
// levels[1][0] = 0;
int newFileIndex = firstSoundIndex -1;
cout<<"firstSoundIndex "<<firstSoundIndex<<endl;
cout<<"load the latest recorded file from disk in to fileNames[] "<<newFileIndex<<endl;
dir.listDir(localRecordingsFolder);
dirSize = dir.size();
fileNames[newFileIndex] = dir.getName(dirSize - 1);
//use max measured level during recording to set new input level for this file
//linear level correction
//float temp_new_level = (1 - rollingInputMax);
//exponential level correction
cout<<"----------rollingInputMax "<<rollingInputMax;
// rollingInputMax = ofClamp(rollingInputMax, 0, 1);
float temp_new_level = pow(1-rollingInputMax,2);
temp_new_level = ofMap(temp_new_level, 0, pow(1,2.0), 0, 1);
cout<<"rollingInputMax "<<rollingInputMax<<" "<<temp_new_level; //<<endl;
temp_new_level = ofClamp(temp_new_level, 0.05, 1);
cout<<" cl "<<temp_new_level<<endl;
saveLevel(fileNames[newFileIndex],temp_new_level);
bool b_fileLoaded = filePlayers[newFileIndex].setFile(localRecordingsFolder+fileNames[newFileIndex]);
cout<<" b_fileLoaded "<<b_fileLoaded<<endl;
cout<<"recFileName "<<recFileName<<endl;
cout<<"newFileIndex "<<newFileIndex<<" , "<<fileNames[newFileIndex]<<endl;
UInt32 framesToPlay = filePlayers[newFileIndex].getLength();
fileLength[newFileIndex] = framesToPlay;
playTimer[newFileIndex] = ofGetElapsedTimef();
playDuration[newFileIndex] = ofRandom(minClipWithPause,maxClipWithPause);
cout<<"file frame length "<<framesToPlay<<endl;
cout<<"playDuration "<< playDuration[newFileIndex]<<endl;
framesToPlay = framesToPlay - trimLastRecLength;// replace with however many frame you want to trim
//???
// cout<<"framesToPlay 1 "<<framesToPlay<<endl;
// framesToPlay = framesToPlay/44100;
// cout<<"framesToPlay 2 "<<framesToPlay<<endl;
// framesToPlay = framesToPlay * 44100;
// cout<<"framesToPlay 3 "<<framesToPlay<<endl;
filePlayers[newFileIndex].setLength(framesToPlay);
// filePlayers[firstSoundIndex].connectTo(taps[firstSoundIndex+1]);//+1 because tap 0 and input buss 0 is used by mic
filePlayers[newFileIndex].connectTo(taps[firstSoundIndex]);
taps[firstSoundIndex].connectTo(mMixer, firstSoundIndex);
//filePlayers[firstSoundIndex].stop();
// filePlayers[newFileIndex].prime();
#ifdef USE_LOOP
filePlayers[newFileIndex].loop();
#else
filePlayers[newFileIndex].play();
#endif
populateTimer = 0; //ofGetElapsedTimef()+populationTiming[0];
bPopulate = true;
populationStage = 1;
popStepsPerTime = 1;
populationCounter = firstSoundIndex;
cout<<"------------------------populationCounter starts with "<<populationCounter<<endl;
populationSteps = 0;
float temp_level = loadLevel(fileNames[newFileIndex]);
/*
int in_left = (firstSoundIndex+1)*2;
int in_right = (firstSoundIndex+1)*2+1;
levels[in_left][NUMBER_OF_OUT_CHANNELS] = temp_level; //0.2;
levels[in_right][NUMBER_OF_OUT_CHANNELS] = temp_level;
*/
maxInputLevel[firstSoundIndex] = temp_level;
cout<<" also load and set input level "<<temp_level<<endl;
int temp_lastSoundIndex = firstSoundIndex;
firstSoundIndex--;
if(firstSoundIndex < 1) firstSoundIndex = NUMBER_OF_FILE_PLAYERS; //NUMBER_OF_INPUT_BUSSES-1; // NUMBER_OF_FILE_PLAYERS-1;
cout<<"------new firstSoundIndex changed from "<<temp_lastSoundIndex<<" to "<<firstSoundIndex<<endl;
}
bUpdateMixerLevels = true;
//cout<<endl;
// cout<<"reset out_to_in_Index "<<endl;
}
//if person is done recording and censoring is applied
if(bIsRecording == false){
if(bCensorRecording == true){
bCensorRecording = false;
censorRecFile(recFileName);
addCuratedFile();
cout<<"file "<<recFileName<<" got censored after recording"<<endl;
dir.listDir(localRecordingsFolder);
dirSize = dir.size();
fileNames[firstSoundIndex] = dir.getName(dirSize - 1);
bool b_fileLoaded = filePlayers[firstSoundIndex].setFile(localRecordingsFolder+fileNames[firstSoundIndex]);
UInt32 framesToPlay = filePlayers[firstSoundIndex].getLength();
fileLength[firstSoundIndex] = framesToPlay;
playTimer[firstSoundIndex] = ofGetElapsedTimef();
playDuration[firstSoundIndex] = ofRandom(minClipWithPause,maxClipWithPause);
cout<<"playDuration "<< playDuration[firstSoundIndex]<<endl;
// cout<<"file frame length "<<framesToPlay<<endl;
framesToPlay = framesToPlay - trimLastRecLength;// replace with however many frame you want to trim
filePlayers[firstSoundIndex].setLength(framesToPlay);
//filePlayers[firstSoundIndex].connectTo(taps[firstSoundIndex+1]);//+1 because tap 0 and input buss 0 is used by mic
filePlayers[firstSoundIndex].connectTo(taps[firstSoundIndex+1]);
taps[firstSoundIndex+1].connectTo(mMixer, firstSoundIndex+1);
//filePlayers[firstSoundIndex].loop(); //play(); //
#ifdef USE_LOOP
filePlayers[firstSoundIndex].loop();
#else
filePlayers[firstSoundIndex].play();
#endif
//also load and set input level
int in_left = (firstSoundIndex+1)*2;
int in_right = (firstSoundIndex+1)*2+1;
float temp_level = loadLevel(fileNames[firstSoundIndex]);
levels[in_left][NUMBER_OF_OUT_CHANNELS] = temp_level; //0.2;
levels[in_right][NUMBER_OF_OUT_CHANNELS] = temp_level; //0.2;
maxInputLevel[firstSoundIndex+1] = temp_level;
}
}
if(bPopulate == true){
//set cross points
//one step shifted
float temp_nextTime;
//we populate the empty voice array with one sound track after the other
if(populationStage == 1){
if(populationSteps > populationTimingCutOff){
//use formular or linear timing
// temp_nextTime = 0.1;
temp_nextTime = popTime / populationSteps;
// cout<<"temp_nextTime "<<temp_nextTime<<endl;
//temp_nextTime = pow(popTime,populationSteps-populationTimingCutOff);
// temp_nextTime = pow(populationTiming[populationSteps],populationSteps-populationTimingCutOff);
// cout<<populationSteps<<" "temp_nextTime<<endl;
}else{
temp_nextTime = populationTiming[populationSteps];
popStepsPerTime = 1;
}
if(ofGetElapsedTimef() - populateTimer > temp_nextTime){
populateTimer = ofGetElapsedTimef();
//at some point the delay between each population steps is smaller then the fps
//that's when we start turning more then one dmx light on, at a time
if(temp_nextTime < 0.02) popStepsPerTime = popStepsPerTime + 0.01;
for(int s=0;s<(int)popStepsPerTime;s++){
//i = 0 is mic input
// cout<<"populationCounter "<<populationCounter<<endl;
// cout<<"populationSteps "<<populationSteps<<endl;
int in_left = populationCounter*2; //left side of stereo input bus
int in_right = populationCounter*2+1;
//step by step build up
int out_channel = populationCounter; //mixer output channel
out_channel = out_channel + (NUMBER_OF_FILE_PLAYERS - firstSoundIndex);
out_channel = out_channel % NUMBER_OF_FILE_PLAYERS;
out_channel = out_channel/filesPerOutput;
out_channel = out_channel + 1; //+1 because out 0 is for mic
out_channel = ofClamp(out_channel, 1, NUMBER_OF_OUT_CHANNELS-1);
//here we determine where the currently populated sound tracks plays out off
#ifdef PERFORMANCE_MODE
for(int c=1; c < NUMBER_OF_OUT_CHANNELS;c++){
setCrossPoint(populationCounter, c, masterCrossLevel);
}
// setAllCrossPoints(masterCrossLevel);
#else
setCrossPoint(populationCounter, out_channel, masterCrossLevel);
#endif
for(int c=0; c<NUMBER_OF_LEDS_PER_FILE; c++){
int _idx = populationSteps*NUMBER_OF_LEDS_PER_FILE + c;
dmx_to_in_Index[_idx] = populationCounter;
}
populationCounter++;
if(populationCounter >= NUMBER_OF_INPUT_BUSSES){
populationCounter = 1;
}
populationSteps++;
}
//make newest file player louder during population
//should find better place to do this since it only needs to be set once
#ifndef PERFORMANCE_MODE
//play through speaker one
setCrossPoint(firstSoundIndex+1, 1, 0.988);
//plat through intercom speaker
setCrossPoint(firstSoundIndex+1, 0, intercomOutputLevel);
#endif
// bUpdateMixerLevels = true;
}
#ifdef PERFORMANCE_MODE
//for perfomance mode, we switch right back to normal play
if(populationSteps >=NUMBER_OF_FILE_PLAYERS || fileLength[populationSteps] <= 0){
populationStage = 2;
cout<<populationSteps<<" fileLength[populationSteps] "<<fileLength[populationSteps]<<endl;
// setAllCrossPoints(masterCrossLevel);
}
#else
//for normal non-performance voice array
if(populationSteps >=NUMBER_OF_FILE_PLAYERS || fileLength[populationSteps] <= 0){ // NUMBER_OF_INPUT_BUSSES-1){
//populating is done
//now play last file through all speakers
// cout<<populationSteps<<" fileLength[populationSteps] "<<fileLength[populationSteps]<<endl;
cout<<"pop=1 populationSteps == NUMBER_OF_INPUT_BUSSES "<<endl;
populationStage = 2;
ledButtonBrightness = 255;
clearAllCossPoints();
//allDmxOff(); //without forcing dmx = zero there would be
//set all cross points of last file to play through all outputs
//for(int i = 0; i<NUMBER_OF_INPUT_BUSSES; i++){
for(int i = 0; i<NUMBER_OF_OUT_CHANNELS; i++){
setCrossPoint(firstSoundIndex, i, 0.985);
}
//make this play louder through all speakers
setAllOutputLevels(0.979);
//have all dmx channels react to last file
for(int i=0; i<allDmxChannels; i++){
dmx_to_in_Index[i] = firstSoundIndex;
}
cout<<"firstSoundIndex "<<firstSoundIndex-1<<endl;
cout<<"oldest file name = "<<fileNames[firstSoundIndex-1]<<endl;
oldestFileLevel_accum = 0;
oldestFileLevel_cnt = 0;
// ofSleepMillis(200);
// filePlayers[firstSoundIndex-1].loop(); //play();
#ifdef USE_LOOP
// filePlayers[firstSoundIndex-1].stop();
//filePlayers[firstSoundIndex-1].loop();
filePlayers[firstSoundIndex-1].play(1);
#else
filePlayers[firstSoundIndex-1].stop();
filePlayers[firstSoundIndex-1].play();
filePlayers[firstSoundIndex-1].play();
filePlayers[firstSoundIndex-1].play();
#endif
//ofSleepMillis(100);
// filePlayers[firstSoundIndex-1].play();
cout<<"firstSoundIndex-1 "<<firstSoundIndex-1<<endl;
cout<<"fileLength[firstSoundIndex] "<<fileLength[firstSoundIndex-1]<<endl;
cout<<"filePlayers[firstSoundIndex].getLength() "<<filePlayers[firstSoundIndex-1].getLength()<<endl;
cout<<" pop=1 getPlayheadPos() >="<<filePlayers[firstSoundIndex-1].getPlayheadPos() <<endl;
}
#endif
}//end if populationStage==1
if(populationStage == 2){
#ifdef PERFORMANCE_MODE
clearAllCossPoints();
setAllCrossPoints(masterCrossLevel);
setAllDmxCrossPointsForPerformance();
populationStage = 3;
#else
if(oldestFileLevel_cnt < 60){
oldestFileLevel_accum = oldestFileLevel_accum + inputTapLevels[firstSoundIndex];
// cout<<"oldestFileLevel_accum "<<oldestFileLevel_accum<<endl;
oldestFileLevel_cnt++;
}else{
if(oldestFileLevel_accum == 0){
oldestFileLevel_cnt = 0;
oldestFileLevel_accum = 0;
filePlayers[firstSoundIndex-1].play();
cout<<"-----------should abort--------"<<endl;
}
}
// cout<<"pop=2 "<<endl;
if(filePlayers[firstSoundIndex-1].getPlayheadPos() >= fileLength[firstSoundIndex-1]-2000 || fileLength[firstSoundIndex-1] <= 0){
cout<<"firstSoundIndex-1 "<<firstSoundIndex-1<<endl;
cout<<"pop=2 getPlayheadPos() >= "<<filePlayers[firstSoundIndex-1].getPlayheadPos()<<endl;
cout<<"fileLength[firstSoundIndex] "<<fileLength[firstSoundIndex-1]<<endl;
cout<<"filePlayers[firstSoundIndex].getLength() "<<filePlayers[firstSoundIndex-1].getLength()<<endl;
cout<<"playDuration[firstSoundIndex] "<<playDuration[firstSoundIndex-1]<<endl;
clearAllCossPoints();
setNormalCrossPointDistribution(masterCrossLevel);
//set all output levels back to normal
setAllOutputLevels(masterOutputLevel);
//play or not most recent sound file through intercomspeaker; i.e. out buss 0
int mostRecentIndex = firstSoundIndex + 1;
cout<<"mostRecentIndex f+1 "<<mostRecentIndex<<endl;
if(mostRecentIndex > NUMBER_OF_FILE_PLAYERS) mostRecentIndex = 1;
#ifndef PERFORMANCE_MODE
//make most recent file play louder then rest, on speaker 1
setCrossPoint(mostRecentIndex, 1, 0.999);
setCrossPoint(mostRecentIndex, 0, 0); //intercomOutputLevel);
#endif
//stop playing most recent through intercom speaker
// setCrossPoint(mostRecentIndex, 0, 0);
populationStage = 3;
}
#endif
}//end if(populationStage == 2)
if(populationStage == 3){
populationStage = 0;
bPopulate = false;
}
}
if(bIsRecording == true){
recDuration = ofGetElapsedTimef() - recStartTime;
}
if(old_bMakeMicActive != bMakeMicActive){
old_bMakeMicActive = bMakeMicActive;
if(bMakeMicActive){
setCrossPoint(0, 0, 0.907);
// levels[0*2][0] = 0.907;
// levels[0*2+1][0] = 0.907;
// out_to_in_Index[0] = 0;
}else{
setCrossPoint(0, 0, 0);
// levels[0*2][0] = 0; //0.907;
// levels[0*2+1][0] = 0; //0.907;
// out_to_in_Index[0] = -1;
}
}
//since we are not using a .loop call we need to check when a file reached it's duration wait x seconds
//we don't use loop because we want shorter files to have an added pause at the endand call pay again
#ifndef USE_LOOP
int temp_cnt = 0;
for(int i=0; i<NUMBER_OF_FILE_PLAYERS; i++){
// if(bTest == false){
// ofLog()<<"test "<<i<<" play getPlayheadPos "<<filePlayers[i].getPlayheadPos()<<" , "<<filePlayers[i].getCurrentTimestamp().mSampleTime<<" , "<<fileLength[i]<<" , "<<filePlayers[i].getStartTimestamp();
// }
if(i != firstSoundIndex-1){
if(fileLength[i] < minClipLength*44100){
// temp_cnt++;
if(ofGetElapsedTimef() - playTimer[i] >= playDuration[i]){
//if(i == firstSoundIndex) cout<<firstSoundIndex<<" "<<fileLength[i]<<" "<<filePlayers[i].getLength()<<endl;
playTimer[i] = ofGetElapsedTimef();
if(filePlayers[i].getLength() > 0){
filePlayers[i].play();
// ofLog()<<i<<" play ";
}
//cout<<"re-play "<<i<<endl;
}
}else{
// if(i == firstSoundIndex) cout<<firstSoundIndex<<" firstSoundIndex , getPlayheadPos "<<filePlayers[i].getPlayheadPos()<<endl;
if((filePlayers[i].getPlayheadPos() - startPlayheadTime[i]) >= fileLength[i]){
if(filePlayers[i].getLength() > 0){
ofLog()<<i<<" play getPlayheadPos "<<filePlayers[i].getPlayheadPos()<<" , "<<startPlayheadTime[i]<<" , "<<(filePlayers[i].getCurrentTimestamp().mSampleTime-startPlayheadTime[i])<<" , "<<fileLength[i]<<" , "<<filePlayers[i].getStartTimestamp();
filePlayers[i].play();
}
// if(i == firstSoundIndex )cout<<"+++re-play "<<i<<" "<<ofGetTimestampString()<< endl;
}
}
}
}
bTest = true;
// ofLog()<<"temp_cnt "<<temp_cnt;
#endif
#ifdef USE_ARTNET
// updateDMX_artNet();
#else
updateDMX_usb();
#endif
// micLevel = micTap.getLeftChannelRMS();
// cout<<"vol1 "<<vol1<<endl;
}
//--------------------------------------------------------------
void ofApp::draw(){
ofBackground(0);
ofSetColor(255);
int t_width = ofGetWidth()-130; //1800
int t_height = ofGetHeight() - 60;
if(bShowMatrixWindow) drawMatrixMixer(ofPoint(100, 5), t_width, t_height);
drawInputBuss(ofPoint(50,5), 50, t_height);
if(bShowOutputChannelWindow) drawOutput(ofPoint(100,5+t_height), t_width, 30);
if(bShowDMX) drawDMX(ofPoint(200, ofGetHeight()-20), ofGetWidth()-210, 20);
//----other info
ofSetColor(255);
ofPushMatrix();
ofTranslate(20,20);
//ofTranslate(50,50);
int temp_p = 5;
ofDrawBitmapString("fps "+ofToString(ofGetFrameRate()), 0,temp_p+=15);
// ofDrawBitmapString("numOfOutputDevices "+ofToString(numOfOutputDevices), 0,temp_p+=15);
// ofDrawBitmapString("tracksPerOutputDevice "+ofToString(tracksPerOutputDevice), 0,temp_p+=15);
// for(int i=0; i<availableDeviceCount; i++){
// ofDrawBitmapString(ofToString(availableDeviceIDs[i])+" , "+avalaibleDeviceNames[i], 0,temp_p+=15);
// }
ofDrawBitmapString("firstSoundIndex "+ofToString(firstSoundIndex), 0,temp_p+=15);
// ofDrawBitmapString("micLevel "+ofToString(micLevel), 0,temp_p+=15);
// ofDrawBitmapString("pressSelectedTap "+ofToString(pressSelectedTap), 0,temp_p+=15);
// ofDrawBitmapString("in_to_out_Index[] "+ofToString(in_to_out_Index[pressSelectedTap]), 0,temp_p+=15);
ofPopMatrix();
// gui.draw();
ofSetColor(255); //, <#int g#>, <#int b#>)
#ifdef PERFORMANCE_MODE
ofDrawBitmapString("voice array "+version+" performance", 300,300);
#else
ofDrawBitmapString("voice array "+version, 300,300);
#endif
ofDrawBitmapString("press g to show and hide the interface "+version, 300,600);
ofDrawBitmapString("press command q to exit the software "+version, 300,620);
if(bShowGui){
gui.draw();
}else{
gui.hide();
}
}
void ofApp::drawInputBuss(ofPoint windowPos, float windowWidth, float windowHeight){
//--file waves
ofPushMatrix();
ofTranslate(windowPos);
//frame around window
ofSetColor(255);
ofNoFill();
ofRect(0, 0, windowWidth, windowHeight);
//ofLine(0,waveWindowHeight/2, waveWindowWidth, waveWindowHeight/2);
float temp_trackHeight = windowHeight / int(NUMBER_OF_INPUT_BUSSES);
//check if mouse is inside wave window
//bool mouseInsideWaveWindow = false;
int temp_i2 = 0;
// int temp_mappedY = 0;
int temp_Y,temp_X;
if(mouseY> windowPos.y && mouseY < windowPos.y+windowHeight && mouseX > windowPos.x &&mouseX < windowPos.x+windowWidth){
mouseInsideInputBussWindow = true;
}else{
mouseInsideInputBussWindow = false;
}
//draw blue background where mouse hovers
if(mouseInsideInputBussWindow == true){
ofPushMatrix();
temp_mappedY = ofMap(mouseY,windowPos.y,windowPos.y+windowHeight,0,NUMBER_OF_INPUT_BUSSES);
temp_Y = (int)temp_mappedY * temp_trackHeight;
temp_X = int((mouseX-windowPos.x) / windowWidth)*windowWidth;
temp_i2 = int((mouseY-windowPos.x) / windowWidth);
ofTranslate(temp_X,temp_Y);
ofFill();
ofSetColor(10, 0, 150);
ofRect(0, 0, windowWidth, temp_trackHeight);
ofPopMatrix();
}
//draw all waves and their ID
if(bShowInputBussWindow){
// int temp_num = firstSoundIndex;
//draw level readings from input taps
for(int i = 0; i < NUMBER_OF_INPUT_BUSSES; i++){
int temp_num = i;
ofPushMatrix();
ofTranslate(0,i*temp_trackHeight);
ofFill();
ofSetColor(255,0,0);
if(i == 0 && bIsRecording == true) ofRect(0, 0, windowWidth,temp_trackHeight);
/*
float temp_level; // = levels[i*2+1][NUMBER_OF_OUT_CHANNELS];
if(i == 0) temp_level = (levels[i*2][NUMBER_OF_OUT_CHANNELS] + levels[i*2+1][NUMBER_OF_OUT_CHANNELS]) / 2.0;
else temp_level = levels[i*2][NUMBER_OF_OUT_CHANNELS];
*/
float temp_level = (levels[i*2][NUMBER_OF_OUT_CHANNELS] + levels[i*2+1][NUMBER_OF_OUT_CHANNELS]) / 2.0;
ofSetColor(temp_level*255);
if(i==firstSoundIndex) ofSetColor(temp_level*255,255,0); //color last track differently
ofRect(0, 0, inputTapLevels[temp_num]*windowWidth,temp_trackHeight);
ofNoFill();
//frame around level
ofSetColor(200);
// ofRect(0, 0, inputTapLevels[temp_num]*windowWidth,temp_trackHeight);
//frame around box
ofSetColor(111);
ofNoFill();
// ofRect(0, 0, windowWidth,temp_trackHeight);
//cout<<"output level "<<<<" , "<<mMixer.getOutputLevel(2)<<endl;
// franklinBook8.drawString(ofToString(i), -10, temp_trackHeight/2+1);
//ofDrawBitmapString(ofToString(i), -10, temp_trackHeight/2-6);
if(i==0){
ofDrawBitmapString("mic", windowWidth+10,temp_trackHeight/2-6);
}else{
// ofDrawBitmapString(ofToString(in_to_out_Index[i-1]), windowWidth+10, temp_trackHeight/2-6);
}
ofPopMatrix();
// temp_num++;
// temp_num = temp_num % numOfOutputChannels;
// cout<<"temp_num "<<temp_num<<endl;
// }
}
}
ofPopMatrix();
if(mouseInsideInputBussWindow == true){
//show file name
// ofSetColor(255);
ofSetColor(255, 0, 0);
// int arrayID = temp_i2*NUMBER_OF_INPUT_BUSSES + temp_mappedX;
int arrayID = temp_mappedY;
if(arrayID > 0){
arrayID = arrayID -1; //decrease by one, since mic has index 0
int temp_soundsFileNameID = dirSize - 1 - arrayID;
//info: on top of which sound is mouse
franklinBook30.drawString("in "+ofToString(temp_mappedY), mouseX,mouseY);
franklinBook30.drawString(fileNames[arrayID], mouseX,mouseY+20);
// franklinBook30.drawString(ofToString(arrayID)+ " , "+ ofToString(temp_soundsFileNameID), mouseX,mouseY+40);
//franklinBook14.drawString(ofToString(maxInputLevel[temp_mappedY]), mouseX,mouseY+45);
franklinBook30.drawString(ofToString(levels[temp_mappedY*2][NUMBER_OF_OUT_CHANNELS]), mouseX,mouseY+40);
}else{
//mic info
franklinBook30.drawString("mic", mouseX,mouseY);
franklinBook30.drawString(ofToString(temp_i2)+" , " + ofToString(temp_mappedY), mouseX,mouseY+20);
franklinBook30.drawString(ofToString(arrayID)+ " , "+ ofToString(inputTapLevels[arrayID]), mouseX,mouseY+40);
}
/*
if(bShowWavesWindow == false){
ofPushMatrix();
//int temp_i = temp_soundsFileNameID;
ofTranslate(temp_X,temp_Y); //ofTranslate(temp*waveWindowWidth,temp_trackHeight*j);
ofScale(scaleX,scaleY);
ofSetColor(150);
ofRect(0, 0, inputTapLevels[temp_soundsFileNameID]*waveWindowWidth, 255);
ofSetColor(255, 255, 0);
// waves[temp_soundsFileNameID].draw();
ofPopMatrix();
}
*/
}
if(mouseInsideInputBussWindow == true && gui.isOn() == false){
if(bMouseIsPressed == true){
bMouseIsPressed = false;
//filePlayers[temp_mappedY].play();
//dispatch_async(dispatch_get_main_queue(), ^{filePlayers[temp_fileNum].loop();});
//set the input volumes to zero
for(int i = 0; i< NUMBER_OF_INPUT_BUSSES * 2; i++){
levels[i][NUMBER_OF_OUT_CHANNELS] = 0.0001;
}
cout<<"temp_mappedY "<<temp_mappedY<<endl;
//set selected input volume to 1
levels[temp_mappedY*2][NUMBER_OF_OUT_CHANNELS] = 1;
levels[temp_mappedY*2+1][NUMBER_OF_OUT_CHANNELS] = 1; //0.5;
//set master gain level
//levels[NUMBER_OF_INPUT_BUSSES * 2][NUMBER_OF_OUT_CHANNELS] = 1; //0.5;
bUpdateMixerLevels = true;
}
if(bMouseDoublePressed == true){
bMouseDoublePressed = false;
for(int i = 0; i< NUMBER_OF_INPUT_BUSSES; i++){
int in_left = i*2;
int in_right = i*2+1;
levels[in_left][NUMBER_OF_OUT_CHANNELS] = maxInputLevel[i];
levels[in_right][NUMBER_OF_OUT_CHANNELS] = maxInputLevel[i];
//cout<<maxInputLevel[i]<<endl;
}
//levels[NUMBER_OF_INPUT_BUSSES * 2][NUMBER_OF_OUT_CHANNELS] = masterVolume;
bUpdateMixerLevels = true;
}
}
}
//--------------------------------------------------------------
void ofApp::drawMatrixMixer(ofPoint windowPos, float windowWidth, float windowHeight){
if(mouseY> windowPos.y && mouseY < windowPos.y+windowHeight && mouseX > windowPos.x &&mouseX < windowPos.x+windowWidth){
mouseInsideMatrixWindow = true;
}else{
mouseInsideMatrixWindow = false;
}
ofPushMatrix();
ofTranslate(windowPos);
//frame around wave window
ofSetColor(255);
ofNoFill();
ofRect(0, 0, windowWidth, windowHeight);
float cols = NUMBER_OF_OUT_CHANNELS;
float rows = NUMBER_OF_INPUT_BUSSES;
float col_width = windowWidth / cols;
float row_height = windowHeight / rows;
for(int r = 0; r < rows; r++){
for(int c = 0; c < cols; c++){
// int temp_i = (c*2) * rows + r;
ofFill();
float temp_level = levels[r*2][c];
// cout<<r<<" "<<c<<" "<<levels[r*2+1][c]<<" \t"<<r*2+1<<" , "<<c<<endl;
ofSetColor(temp_level*255);
ofRect(c*col_width, r*row_height, col_width, row_height);
ofNoFill();
ofSetColor(111);
//frame around each cross point
//ofRect(c*col_width, r*row_height, col_width, row_height);
}
}
ofPopMatrix();
}
//--------------------------------------------------------------
void ofApp::drawOutput(ofPoint windowPos, float windowWidth, float windowHeight){
ofPushMatrix();
ofTranslate(windowPos);
//frame around window
ofSetColor(255);
ofNoFill();
ofRect(0, 0, windowWidth, windowHeight);
// int temp_mappedX = 0;
int temp_Y,temp_X;
float temp_trackWidth = windowWidth / int(NUMBER_OF_OUT_CHANNELS);
if(mouseY> windowPos.y && mouseY < windowPos.y+windowHeight && mouseX > windowPos.x &&mouseX < windowPos.x+windowWidth){
mouseInsideOutputWindow = true;
}else{
mouseInsideOutputWindow = false;
}
//draw blue background where mouse hovers
if(mouseInsideOutputWindow == true){
ofPushMatrix();
temp_mappedX = ofMap(mouseX,windowPos.x,windowPos.x+windowWidth,0,NUMBER_OF_OUT_CHANNELS);
temp_X = (int)temp_mappedX * temp_trackWidth;
temp_Y = int((mouseY-windowPos.y) / windowHeight)*windowHeight;
ofTranslate(temp_X,temp_Y);
ofSetColor(10, 0, 200);
ofFill();
ofRect(0, 0, temp_trackWidth, windowHeight);
ofPopMatrix();
}
//draw the output level for each output
for(int i = 0; i < NUMBER_OF_OUT_CHANNELS; i++){
int temp_num = i;
ofPushMatrix();
ofTranslate(i*temp_trackWidth,0);
ofFill();
float temp_level = levels[NUMBER_OF_INPUT_BUSSES * 2][i];
ofSetColor(temp_level*255);
float newLevel = pow(10., 0.05*mMixer.getOutputLevel(temp_num));
newLevel = sqrt(newLevel);
// float val = ofMap(mMixer.getOutputLevel(temp_num),-70,-20,0,windowHeight,true);
float val = windowHeight*newLevel; //ofMap(newLevel,0.02,0.6,0,windowHeight,true);
ofRect(0, 0,temp_trackWidth,val);
ofSetColor(111);
ofNoFill();
ofRect(0, 0,temp_trackWidth,windowHeight);
ofSetColor(255, 255, 0);
// ofNoFill();
// float val = ofMap(mMixer.getOutputLevel(temp_num),-120,0,0,windowHeight,true);
// ofRect(temp_trackWidth, windowHeight, temp_trackWidth, val);
// if(i ==0){
// //cout<<mMixer.getOutputLevel(temp_num)<<endl;
// }
ofSetColor(255);
franklinBook8.drawString(ofToString(i),8, windowHeight-8);
ofPopMatrix();
// temp_num++;
// temp_num = temp_num % numOfOutputChannels;
// cout<<"temp_num "<<temp_num<<endl;
// }
}
ofPopMatrix();
if(mouseInsideOutputWindow == true && gui.isOn() == false){
if(bMouseIsPressed == true){
bMouseIsPressed = false;
if(bDebug)cout<<"mouseInsideOutputWindow + bMouseIsPressed "<<endl;
//filePlayers[temp_mappedX].loop();
//dispatch_async(dispatch_get_main_queue(), ^{filePlayers[temp_fileNum].loop();});
// set the volume of output channels to zero
for(int i = 0; i< NUMBER_OF_OUT_CHANNELS; i++){
levels[NUMBER_OF_INPUT_BUSSES * 2][i] = 0.0001; //0;
}
//set selected output volume to 1
levels[NUMBER_OF_INPUT_BUSSES * 2][temp_mappedX] = 1;
//set master gain level
// levels[NUMBER_OF_INPUT_BUSSES * 2][NUMBER_OF_OUT_CHANNELS] = 0.5;
bUpdateMixerLevels = true;
}
if(bMouseDoublePressed == true){
bMouseDoublePressed = false;
for(int i = 0; i< NUMBER_OF_OUT_CHANNELS; i++){
levels[NUMBER_OF_INPUT_BUSSES * 2][i] = masterOutputLevel;
}
levels[NUMBER_OF_INPUT_BUSSES * 2][NUMBER_OF_OUT_CHANNELS] = masterVolume;
bUpdateMixerLevels = true;
}
}
}
void ofApp::updateDMX_artNet(){
// if(bDebug)cout<<"updateDMX_artNet"<<endl;
if(bAllOFF){
for(int _id=0; _id<2;_id++){
for(int n=0; n<dmx_channelAmount[_id]; n++){
dmx_values[_id][n] = 0;
}
}
bAllOFF = false;
}
if(bAllON){
for(int _id=0; _id<2;_id++){
for(int n=0; n<dmx_channelAmount[_id]; n++){
dmx_values[_id][n] = dmxSilderValue;
}
}
bAllON = false;
}
if(bChase != old_bChase){
old_bChase = bChase;
caseCnt = dmxChannelNum;
}
if(bChase){
if(ofGetElapsedTimeMillis() - chaseTimer > chaseSpeed){
chaseTimer = ofGetElapsedTimeMillis();
int chase_id = 0;
int temp_dmxChannelNum = caseCnt;
if(bInverseDmx) temp_dmxChannelNum = (allDmxChannels-1) - caseCnt;
if(temp_dmxChannelNum >= dmx_channelAmount[0]) chase_id = 1;
int channelOffset = 0;
if(chase_id > 0) channelOffset = dmx_channelAmount[chase_id-1];
for(int n=0; n<dmx_channelAmount[chase_id]; n++){
dmx_values[chase_id][n] = 0;
}
dmx_values[chase_id][temp_dmxChannelNum-channelOffset] = 126;
caseCnt++;
if(caseCnt >= NUMBER_OF_FILE_PLAYERS){
caseCnt = 0;
}
}
}
if(dmxChannelNum != old_dmxChannelNum || dmxSilderValue != old_dmxSilderValue){
old_dmxChannelNum = dmxChannelNum;
old_dmxSilderValue = dmxSilderValue;
int _id = 0;
int temp_dmxChannelNum = dmxChannelNum;
if(bInverseDmx) temp_dmxChannelNum = (allDmxChannels-1) - dmxChannelNum;
// cout<<"temp_dmxChannelNum "<<temp_dmxChannelNum<<" "<<dmxSilderValue<<endl;
//all off
for(int _id=0; _id<2;_id++){
for(int n=0; n<dmx_channelAmount[_id]; n++){
dmx_values[_id][n] = 0;
}
}
if(temp_dmxChannelNum >= dmx_channelAmount[0]){
_id = 1;
temp_dmxChannelNum = temp_dmxChannelNum - dmx_channelAmount[0];
}
dmx_values[_id][temp_dmxChannelNum] = dmxSilderValue;
}
for(int _id=0; _id<2;_id++){
int channelOffset = 0;
if(_id > 0) channelOffset = dmx_channelAmount[_id-1];
if(bRouteVolumeToDMX){
// dmx[0].setLevel(1,ledButtonBrightness);
if(mouseInsideOutputWindow && ofGetMousePressed()){
//when mouse click is in one of the output level fields
for(int n=0; n<dmx_channelAmount[_id]; n++){
dmx_values[_id][n] = 0;
}
int ii = temp_mappedX;
ii = filesPerOutput * (ii-1);
if(ii >= channelOffset && ii < channelOffset+dmx_channelAmount[_id]){
int temp_start = ii;
int temp_stop = temp_start + filesPerOutput;
// cout<<"_id "<<_id<<" X "<<temp_mappedX<<" start "<<temp_start<<" stop "<<temp_stop<<" per "<<filesPerOutput<<endl;
for(int i=temp_start; i<temp_stop;i++){
int temp_v = 0;
if(dmx_to_in_Index[i] != -1){
temp_v = inputTapLevels[dmx_to_in_Index[i]] * 255 * brightnessMultiplier;
}
temp_v = ofClamp(temp_v, 0, 255);
dmx_values[_id][i-channelOffset] = temp_v;
}
}
}else if(mouseInsideInputBussWindow && ofGetMousePressed()){
//play + light up file+led that is clipped on
for(int n=0; n<dmx_channelAmount[_id]; n++){
dmx_values[_id][n] = 0;
}
int ii = temp_mappedY - firstSoundIndex;
if(ii <= 0) ii = NUMBER_OF_FILE_PLAYERS + ii;
//cout<<"ii "<<ii<<endl;
if(ii >= channelOffset && ii < channelOffset+dmx_channelAmount[_id]){
int temp_v = 0;
//out_to_in_Index[i] == -1 means output has not been set
if(dmx_to_in_Index[ii] != -1){
temp_v = inputTapLevels[dmx_to_in_Index[ii-1]] * 255 * brightnessMultiplier;
}
temp_v = ofClamp(temp_v, 0, 255);
//0 is mic input which does not have dmx channel
dmx_values[_id][ii-channelOffset] = temp_v;
}
}else{
if(bDebug){
cout<<_id<<"============================="<<endl;
cout<<"channelOffset "<<channelOffset<<" dmx_channelAmount[_id] "<<dmx_channelAmount[_id]<<" , "<<channelOffset+dmx_channelAmount[_id]<<endl;
}
for(int ii=channelOffset; ii<channelOffset+dmx_channelAmount[_id];ii++){
int temp_dmxChannelNum = ii;
int temp_v = 0;
if(bDebug) cout<<"temp_dmxChannelNum-> "<<temp_dmxChannelNum<<endl;
if(bInverseDmx == false){
if(dmx_to_in_Index[temp_dmxChannelNum] != -1){
temp_v = inputTapLevels[dmx_to_in_Index[temp_dmxChannelNum]] * 255 * brightnessMultiplier;
// cout<<temp_dmxChannelNum<<" , "<<dmx_to_in_Index[temp_dmxChannelNum]<<" , temp_v "<<temp_v<<endl;
}else{
temp_v = popLowLight;
}
}else{
//inversed dmx channel order
if(temp_dmxChannelNum != allDmxChannels){ //-1
if(bDebug){
cout<<"------------------ "<<endl;
cout<<"_id "<<_id<<endl;
cout<<"ii "<<ii<<endl;
cout<<"temp_dmxChannelNum "<<temp_dmxChannelNum<<endl;
cout<<"(allDmxChannels)-(temp_dmxChannelNum+1) "<<allDmxChannels<<" - "<<(temp_dmxChannelNum+1)<<" = "<<(allDmxChannels)-(temp_dmxChannelNum+1)<<endl;
cout<<"dmx_to_in_Index[(allDmxChannels)-(temp_dmxChannelNum+1)] "<<dmx_to_in_Index[(allDmxChannels)-(temp_dmxChannelNum+1)]<<endl;
}
if(dmx_to_in_Index[(allDmxChannels)-(temp_dmxChannelNum+1)] != -1){
float temp_level = inputTapLevels[dmx_to_in_Index[(allDmxChannels)-(temp_dmxChannelNum+1)]];
if(_id == 0 && ii == 0){
//this is some strange work around because i can't figure out right now hwo to get the first or last dmx channel to get the right level info. :(
temp_level = inputTapLevels[dmx_to_in_Index[(allDmxChannels)-(temp_dmxChannelNum+3)]];
}
// if(temp_dmxChannelNum > 1)
//makes louder sounds have less visual effect; i.e. darker
//except for last and 2nd last audio file / last dmx channel
temp_level = pow(temp_level, levelCurve);
//make everything a bit brighter
temp_v = temp_level * 255 * brightnessMultiplier;
// if(temp_dmxChannelNum == 0) temp_level = 0;
}else{
temp_v = popLowLight;
}
}
}
//dmx_to_in_Index[i] == -1 means output has not been set
//limit the min and max brightness
temp_v = ofMap(temp_v,0, 255 * brightnessMultiplier, minBrightness, maxBrightness,true);
#ifdef PERFORMANCE_MODE
dmx_values[_id][temp_dmxChannelNum-channelOffset+1] = temp_v;
#else
dmx_values[_id][temp_dmxChannelNum-channelOffset] = temp_v;
#endif
}
// if(ledButtonBrightness > 150) dmx[0].setLevel(1,255);
}
if(bDebug ) cout<<endl;
}//end if(bRouteVolumeToDMX)
}//for(int _id=0; _id<2;_id++){
// if(bDebug)cout<<"artnetDMX.sendDmx"<<endl;
for(int _id=0; _id<2;_id++){
// if(bDebug){
// cout<<_id<<endl;//"artnetIPs[_id] "<<artnetIPs[_id]<<endl;
// // cout<<"dmx_values[_id] "<< (int)dmx_values[_id]<<endl;
// cout<<"dmx_channelAmount[_id] "<<dmx_channelAmount[_id]<<endl;
// }
artnetDMX.sendDmx(artnetIPs[_id], dmx_values[_id], dmx_channelAmount[_id]);
}
}
//-------------------------------------------------------------
void ofApp::allDmxOff(){
for(int _id=0; _id<2;_id++){
unsigned char temp_values[512];
for(int a=0; a<512; a++){
temp_values[a] = 0;
}
artnetDMX.sendDmx(artnetIPs[_id], temp_values, 512);
}
}
//--------------------------------------------------------------
void ofApp::drawDMX(ofPoint windowPos, float windowWidth, float windowHeight){
float temp_trackWidth = windowWidth / allDmxChannels;
//re-adjust window pos and width, since we want channel 1 to be more to the left
//channel 1 is the led button
windowWidth = windowWidth + temp_trackWidth;
temp_trackWidth = windowWidth / allDmxChannels;
windowPos.x = windowPos.x-temp_trackWidth;
ofPushMatrix();
ofTranslate(windowPos.x,windowPos.y);
bool temp_showChannelsNums = false;
int temp_mouseID = -1;
if(mouseX > windowPos.x && mouseX<windowPos.x+windowWidth && mouseY > windowPos.y && mouseY < windowPos.y+windowHeight){
temp_showChannelsNums = true;
temp_mouseID = ofMap(mouseX, windowPos.x, windowPos.x+windowWidth, 0, allDmxChannels);
}
//display dmx values
// float temp_w2 = windowWidth/allDmxChannels * 1.0;
ofFill();
for(int i=0; i<allDmxChannels; i++){
if(i <dmx_channelAmount[0]){
ofSetColor(dmx_values[0][i]);
// if(i == 10)cout<<"c "<<temp_i<<endl;
}else{
ofSetColor(dmx_values[1][i-dmx_channelAmount[0]]);
}
ofRect(i*temp_trackWidth,0,temp_trackWidth,windowHeight);
if(temp_showChannelsNums == true && temp_mouseID == i){
ofSetColor(255);
if(i==NUMBER_OF_FILE_PLAYERS-1){
franklinBook14.drawString(ofToString(i+1)+", not seen", i*temp_trackWidth+temp_trackWidth/3, -1);
}else{
franklinBook14.drawString(ofToString(i+1), i*temp_trackWidth+temp_trackWidth/3, -1);
}
}
}
/*
if(bPopulating == true){
ofEnableAlphaBlending();
ofSetColor(255,150);
ofFill();
int temp_w3 = ofMap(populationCounter, 0, allNum, 0, temp_w);
//cout<<"temp_w3 "<<temp_w3<<" , "<<temp_h<<endl;
ofRect(0,0,temp_w3, temp_h);
ofDisableAlphaBlending();
}
*/
ofNoFill();
ofSetColor(255);
ofRect(0,0, windowWidth, windowHeight);
ofFill();
franklinBook14.drawString("dmx", -franklinBook14.stringWidth("dmx")-3, windowHeight*0.75);
ofPopMatrix();
}
//--------------------------------------------------------------
void ofApp::keyPressed(int key){
if(key == 'r'){
bStartRecording = true;
}
if(key == 's'){
bStopRecording = true;
}
if(key == 'f') ofToggleFullscreen();
if(key == ' '){
bLedButtonPressed = true;
#ifdef PERFORMANCE_MODE
bPopulate = false;
#endif
}
if(key == 'q') std::exit(1);
}
//--------------------------------------------------------------
void ofApp::keyReleased(int key){
if(key == 'g'){
bShowGui = !bShowGui;
// cout<<"bShowGui "<<bShowGui<<endl;
gui.toggleDraw();
}
// #ifndef PERFORMANCE_MODE
if(bStopViaKeyRelease){
if(key == ' '){
// bStopRecording = true;
bLedButtonPressed = false;
recWaitTimer = ofGetElapsedTimef();
}
//#endif
}
if(key == '1'){
filePlayers[firstSoundIndex].play();
cout<<"firstSoundIndex "<<firstSoundIndex<<endl;
cout<<"fileLength[firstSoundIndex] "<<fileLength[firstSoundIndex]<<endl;
cout<<"filePlayers[firstSoundIndex].getLength() "<<filePlayers[firstSoundIndex].getLength()<<endl;
cout<<" pop=1 getPlayheadPos() >="<<filePlayers[firstSoundIndex].getPlayheadPos() <<endl;
}
if(key == '2'){
filePlayers[firstSoundIndex-1].play();
cout<<"firstSoundIndex-1 "<<firstSoundIndex-1<<endl;
cout<<"fileLength[firstSoundIndex] "<<fileLength[firstSoundIndex-1]<<endl;
cout<<"filePlayers[firstSoundIndex].getLength() "<<filePlayers[firstSoundIndex-1].getLength()<<endl;
cout<<" pop=1 getPlayheadPos() >="<<filePlayers[firstSoundIndex-1].getPlayheadPos() <<endl;
}
if(key == 'c'){
// addCuratedFile();
}
if(key == 'x'){
#ifdef PERFORMANCE_MODE
goBackOneStep();
#endif
}
// if(key == 'z') bCensorRecording = true;
}
//--------------------------------------------------------------
void ofApp::mouseMoved(int x, int y ){
// if(y> file_windowPos.y && y < file_windowPos.y+file_waveWindowHeight && x > file_windowPos.x && x < file_windowPos.x+file_waveWindowWidth){
// mouseInsideWaveWindow = true;
// }else{
// mouseInsideWaveWindow = false;
// }
}
//--------------------------------------------------------------
void ofApp::mouseDragged(int x, int y, int button){}
//--------------------------------------------------------------
void ofApp::mousePressed(int x, int y, int button){
// if(gui.isOn() == false) bMouseIsPressed = true;
}
//--------------------------------------------------------------
void ofApp::mouseReleased(int x, int y, int button){
if(gui.isOn() == false){
bMouseIsPressed = !bMouseIsPressed;
unsigned long curTap = ofGetElapsedTimeMillis();
if(lastTap != 0 && curTap - lastTap < 250){
bMouseDoublePressed = true;
}
lastTap = curTap;
}
// if(gui.isOn() == false) bMouseIsReleased = true;
}
//--------------------------------------------------------------
void ofApp::windowResized(int w, int h){}
//--------------------------------------------------------------
void ofApp::gotMessage(ofMessage msg){}
//--------------------------------------------------------------
void ofApp::dragEvent(ofDragInfo dragInfo){}
//--------------------------------------------------------------
void ofApp::startRecording(string filePath) {
// converting file path from C++ string to NSString
NSString * fileString = [NSString stringWithUTF8String:filePath.c_str()];
// declaring settings for recorded file
NSDictionary * fileSettings = @{
AVFormatIDKey : @(kAudioFormatMPEG4AAC),
AVSampleRateKey : @(44100), //32000),
AVNumberOfChannelsKey : @(1) //2 ?????? 2 for stereo 1 for mono
};
if(recorder)
{
[recorder release];
}
NSError * err;
recorder = [[AVAudioRecorder alloc] initWithURL:[NSURL fileURLWithPath:fileString]
settings:fileSettings
error:&err];
if(err){
NSLog(@"Error when setting up recorder : %@", err);
} else {
[recorder setDelegate:recordDelegate];
[recorder record];
}
}
//--------------------------------------------------------------
void ofApp::stopRecording() {
[recorder stop];
}
//--------------------------------------------------------------
void ofApp::finishedRecording(string fileName) {
cout << "Recorded to " << fileName << endl;
bRecFileSaved = true;
}
//--------------------------------------------------------------
void ofApp::deleteRecFile(string t_fileName){
//http://www.openframeworks.cc/documentation/utils/ofFile.html
if(t_fileName != ""){
ofFile file;
file.removeFile(localRecordingsFolder+t_fileName);
file.close();
}
}
//--------------------------------------------------------------
void ofApp::censorRecFile(string t_fileName){
//http://www.openframeworks.cc/documentation/utils/ofFile.html
if(t_fileName != ""){
ofFile file;
cout<<"copy censored file "<<t_fileName<<" and remove it "<<endl;
file.copyFromTo(localRecordingsFolder+t_fileName, "other/"+t_fileName);
file.removeFile(localRecordingsFolder+t_fileName);
file.close();
}
}
//--------------------------------------------------------------
string ofApp::addCuratedFile(){
ofDirectory curatedDir;
curatedDir.listDir("curated/");
int curatedDir_size = curatedDir.size();
int randomPick = (int)ofRandom(curatedDir_size-1);
string curatedFileName = curatedDir.getName(randomPick);
string _newFileName = ofGetTimestampString()+"_";
ofFile file;
file.copyFromTo("curated/"+curatedFileName, localRecordingsFolder,true);
cout<<"pick random curated file # "<<randomPick<<" of "<<curatedDir_size<<" -> name = "<<curatedFileName<<endl;
string newFileName = _newFileName+".m4a";
cout<<"now match/name file -> "<<newFileName<<endl;
ofFile newFile(localRecordingsFolder+curatedFileName);
newFile.renameTo(localRecordingsFolder+newFileName);
file.close();
newFile.close();
float temp_level = loadLevel(curatedFileName);
saveLevel(_newFileName,temp_level);
return curatedFileName;
}
void ofApp::goBackOneStep(){
cout<<"goBackOneStep()"<<endl;
if(firstSoundIndex < NUMBER_OF_FILE_PLAYERS){
// int _idx = firstSoundIndex +1;
// cout<<"_idx "<<_idx<<endl;
cout<<firstSoundIndex<<" fileNames[firstSoundIndex] "<<fileNames[firstSoundIndex]<<endl;
//
// cout<<firstSoundIndex+1<<" fileNames[firstSoundIndex+1] "<<fileNames[firstSoundIndex+1]<<endl;
deleteRecFile(fileNames[firstSoundIndex]);
// cout<<"delete file"<<recFileName<<" because duration "<<recDuration<<" < "<<minRecDuration;
filePlayers[firstSoundIndex].setFile(ofFilePath::getAbsolutePath("empty.m4a"));
filePlayers[firstSoundIndex].stop();
fileLength[firstSoundIndex] = -1;
playDuration[firstSoundIndex] = 0;
firstSoundIndex = firstSoundIndex + 1;
if(firstSoundIndex > NUMBER_OF_FILE_PLAYERS) firstSoundIndex = 1;
//
// clearAllCossPoints();
// setNormalCrossPointDistribution(masterCrossLevel);
setAllDmxCrossPointsForPerformance();
}else{
cout<<"goBackOneStep could not be performaed because firstSoundIndex = "<<firstSoundIndex<<endl;
}
}
//--------------------------------------------------------------
void ofApp::saveLevel(string _fileName, float _level){
ofStringReplace(_fileName, ".m4a", "");
//_fileName = ofSplitString(_fileName, ".m4a")
cout<<"try to save level for "<<_fileName<<endl;
ofstream textFile;
textFile.open(ofToDataPath("levels/"+_fileName+".txt").c_str()); //ios::in);
//this also creates a text file if non exits
string outString;
outString = ofToString(_level);
textFile.write(outString.c_str(), outString.size());
textFile.close();
}
float ofApp::loadLevel(string _fileName){
float _level = -1;
ofStringReplace(_fileName, ".m4a", "");
// ifstream textFile;
//int lineCount = 0;
// textFile.open(ofToDataPath("levels/"+_fileName+".txt").c_str()); //ios::in);
ofBuffer buffer = ofBufferFromFile(ofToDataPath("levels/"+_fileName+".txt").c_str());
if(buffer.size()){
for (ofBuffer::Line it = buffer.getLines().begin(), end = buffer.getLines().end(); it != end; ++it) {
string line = *it;
if(line.empty() == false || line.length() <= 0) {
cout<<"no content in level text file "<<_fileName<<endl;
_level = 0.5;
}else{
_level = ofToFloat(line);
break; //only need first line
}
}
}else{
// cout<<"no text file named "<<_fileName<<" to load from"<<endl;
_level = 0.2;
}
// cout<<"_level "<<_level<<endl;
return _level;
}
void ofApp::clearAllCossPoints(){
for(int i = 0; i< NUMBER_OF_INPUT_BUSSES; i++){
for(int j=0; j<NUMBER_OF_OUT_CHANNELS; j++){
int in_left = i*2; //left side of stereo input bus
int in_right = i*2+1;
int out_channel = j; //i-1; //mixer output channel
levels[in_left][out_channel] = 0; //left file player channel
levels[in_right][out_channel] = 0; //right file player channel
}
}
for(int i = 0; i< allDmxChannels; i++){
dmx_to_in_Index[i] = -1;
}
bUpdateMixerLevels = true;
}
void ofApp::setNormalCrossPointDistribution(float _level){
//this sets the staggered order of the matrix mixer input to output matrix
//and which input is routed to which dmx channel
int inBuss = firstSoundIndex;
//cout<<"firstSoundIndex "<<firstSoundIndex<<endl;
// int temp_steps = 0;
int inBuss_cnt = 1;
cout<<"firstSoundIndex "<<firstSoundIndex<<endl;
while(inBuss_cnt < NUMBER_OF_INPUT_BUSSES){
int in_left = inBuss*2; //left side of stereo input bus
int in_right =inBuss*2+1;
int out_channel = inBuss; //-1; //mixer output channel
out_channel = out_channel + (NUMBER_OF_FILE_PLAYERS - firstSoundIndex);
out_channel = out_channel % NUMBER_OF_FILE_PLAYERS;
// tt = out_channel;
//int out_channel = inBuss -1;
out_channel = out_channel/filesPerOutput;
out_channel = out_channel + 1; //+1 because out 0 is for mic
out_channel = ofClamp(out_channel, 1, NUMBER_OF_OUT_CHANNELS-1);
//set cross point level
setCrossPoint(inBuss,out_channel,_level);
// cout<<"inBuss "<<inBuss<<" out "<<out_channel<<" firstSoundIndex "<<firstSoundIndex<<endl;
if(inBuss == firstSoundIndex){ //firstSoundIndex+1){
// cout<<"inBuss == firstSoundIndex+1"<<endl;
setCrossPoint(inBuss,out_channel,0.012);
}
int bb = inBuss+1;
// if(bb < 1) bb = NUMBER_OF_FILE_PLAYERS;
if(bb > NUMBER_OF_FILE_PLAYERS) bb = 1;
for(int c=0; c<NUMBER_OF_LEDS_PER_FILE; c++){
int _idx = (inBuss_cnt-1)*NUMBER_OF_LEDS_PER_FILE + c;
dmx_to_in_Index[_idx] = bb; //input Buss 0 = mic which does not have a dmx channel
}
// cout<<inBuss_cnt-1<<" dmx_to_in_Index "<< dmx_to_in_Index[inBuss_cnt-1]<<" "<<inBuss<<endl;
inBuss++;
if(inBuss >= NUMBER_OF_INPUT_BUSSES){
inBuss = 1;
}
inBuss_cnt++;
}
cout<<"firstSoundIndex+1 "<<firstSoundIndex+1<<endl;
//play most current file louder then rest, through output
int temp_index = firstSoundIndex+1;
if(temp_index >= NUMBER_OF_INPUT_BUSSES) temp_index = 1;
setCrossPoint(temp_index,1,1);
// setCrossPoint(temp_index, 0, intercomOutputLevel);
for(int i=0; i<NUMBER_OF_FILE_PLAYERS;i++){
if(dmx_to_in_Index[i] < 0 || dmx_to_in_Index[i] > NUMBER_OF_FILE_PLAYERS){
cout<<"+++++++++++++++++++++++ ";
cout<<i<<" dmx_to_in_Index[i]"<<dmx_to_in_Index[i]<<endl;
dmx_to_in_Index[i] = i;
}
}
bUpdateMixerLevels = true;
}
void ofApp::setMasterVolume(float _level){
levels[NUMBER_OF_INPUT_BUSSES * 2][NUMBER_OF_OUT_CHANNELS] = _level;
bUpdateMixerLevels = true;
}
void ofApp::setAllOutputLevels(float _level){
for(int i = 0; i< NUMBER_OF_OUT_CHANNELS; i++){
levels[NUMBER_OF_INPUT_BUSSES * 2][i] = _level; //0.8+ofMap(i, 0, NUMBER_OF_OUT_CHANNELS, 0, 0.1);
}
bUpdateMixerLevels = true;
}
void ofApp::setInputRangeToOutputChannel(int _startInputBuss, int _stopInputBuss, int _outputChannel){
for(int i = _startInputBuss; i < _stopInputBuss; i++){
int in_left = i*2; //left side of stereo input bus
int in_right = i*2+1;
levels[in_left][_outputChannel] = bAllOutZero; //mic left
levels[in_right][_outputChannel] = bAllOutZero;//mic right
}
bUpdateMixerLevels = true;
}
void ofApp::setCrossPoint(int _inputBuss, int _outputChannel, float _level){
int in_left_channel = _inputBuss*2;
int in_right_channel = _inputBuss*2+1;
levels[in_left_channel][_outputChannel] = _level;
levels[in_right_channel][_outputChannel] = _level;
bUpdateMixerLevels = true;
}
void ofApp::setAllCrossPoints(float _level){
for(int i = 1; i< NUMBER_OF_INPUT_BUSSES; i++){
for(int j=1; j<NUMBER_OF_OUT_CHANNELS; j++){
int in_left = i*2; //left side of stereo input bus
int in_right = i*2+1;
int out_channel = j; //i-1; //mixer output channel
levels[in_left][out_channel] = _level; //left file player channel
levels[in_right][out_channel] = _level; //right file player channel
}
}
bUpdateMixerLevels = true;
}
void ofApp::setAllDmxCrossPointsForPerformance(){
//this sets which inputs are routed to which dmx channels
//but does not touch the matrix mixer
int inBuss = firstSoundIndex;
int inBuss_cnt = 1;
cout<<"firstSoundIndex "<<firstSoundIndex<<endl;
while(inBuss_cnt < NUMBER_OF_INPUT_BUSSES){
// int in_left = inBuss*2; //left side of stereo input bus
// int in_right =inBuss*2+1;
//
// int out_channel = inBuss; //-1; //mixer output channel
// out_channel = out_channel + (NUMBER_OF_FILE_PLAYERS - firstSoundIndex);
//
// out_channel = out_channel % NUMBER_OF_FILE_PLAYERS;
// // tt = out_channel;
// //int out_channel = inBuss -1;
// out_channel = out_channel/filesPerOutput;
// out_channel = out_channel + 1; //+1 because out 0 is for mic
// out_channel = ofClamp(out_channel, 1, NUMBER_OF_OUT_CHANNELS-1);
int bb = inBuss+1;
// if(bb < 1) bb = NUMBER_OF_FILE_PLAYERS;
if(bb > NUMBER_OF_FILE_PLAYERS) bb = 1;
for(int c=0; c<NUMBER_OF_LEDS_PER_FILE; c++){
int _idx = (inBuss_cnt-1)*NUMBER_OF_LEDS_PER_FILE + c;
dmx_to_in_Index[_idx] = bb; //input Buss 0 = mic which does not have a dmx channel
}
// cout<<inBuss_cnt-1<<" dmx_to_in_Index "<< dmx_to_in_Index[inBuss_cnt-1]<<" "<<inBuss<<endl;
inBuss++;
if(inBuss >= NUMBER_OF_INPUT_BUSSES){
inBuss = 1;
}
inBuss_cnt++;
}
for(int i=0; i<NUMBER_OF_FILE_PLAYERS;i++){
if(dmx_to_in_Index[i] < 0 || dmx_to_in_Index[i] > NUMBER_OF_FILE_PLAYERS){
cout<<"+++++++++++++++++++++++ ";
cout<<i<<" dmx_to_in_Index[i]"<<dmx_to_in_Index[i]<<endl;
dmx_to_in_Index[i] = i;
}
}
// cout<<"+++++++++++++++++++++++ ";
// for(int i=0; i<NUMBER_OF_FILE_PLAYERS;i++){
//
// cout<<i<<" dmx_to_in_Index[i]"<<dmx_to_in_Index[i]<<endl;
//
// }
}
void ofApp::updateAllMatrixMixerLevels(){
OFXAU_PRINT(AudioUnitSetProperty(mMixer,
kAudioUnitProperty_MatrixLevels,
kAudioUnitScope_Global,
0,
levels,
sizeof(levels)),
"setting matrix volume levels");
if(bDebug){
cout<<"-------- write matrix mixer array to text file ---------"<<endl;
FILE * debugFile = fopen(ofToDataPath("MatrixMixerVolumes.txt").c_str(),"w"); //fopen("/Users/Adam/Desktop/MatrixMixerVolumes.txt", "w");
PrintMatrixMixerVolumes(debugFile, mMixer);
fclose(debugFile);
}
}
@implementation RecordDelegate
@synthesize app = _app;
- (void)audioRecorderDidFinishRecording:(AVAudioRecorder *)recorder successfully:(BOOL)flag
{
// notifying the oF app that the audio file is ready
_app->finishedRecording([[[recorder url] path] UTF8String]);
}
@end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment