Created
August 26, 2013 15:32
-
-
Save halfd/6342769 to your computer and use it in GitHub Desktop.
The main file controlling the installation
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
/* | |
Joens exhibition | |
*/ | |
#include "FileWvIn.h" | |
#include "RtAudio.h" | |
#include "RtWvOut.h" | |
#include <iostream> | |
#include <boost/asio/serial_port.hpp> | |
#include <boost/asio.hpp> | |
#include <string> | |
#include <vector> | |
using namespace std; | |
using namespace boost; | |
using namespace stk; | |
const float volume = 0.6; //0.4; | |
const unsigned int threshold = 440; | |
const unsigned int timer_threshold = 2.0; | |
// Tick function for the audio interfaces | |
int tick( void *outputBuffer, void *inputBuffer, unsigned int nBufferFrames, | |
double streamTime, RtAudioStreamStatus status, void *dataPointer ) | |
{ | |
FileWvIn *sine = (FileWvIn *) dataPointer; | |
register StkFloat *samples = (StkFloat *) outputBuffer; | |
for ( unsigned int i = 0; i < nBufferFrames; i++ ) { | |
*samples++ = volume * sine->tick(); | |
} | |
if (sine->isFinished()) { | |
sine->reset(); | |
} | |
return 0; | |
} | |
int tick1( void *outputBuffer, void *inputBuffer, unsigned int nBufferFrames, | |
double streamTime, RtAudioStreamStatus status, void *dataPointer ) | |
{ | |
FileWvIn *sine = (FileWvIn *) dataPointer; | |
register StkFloat *samples = (StkFloat *) outputBuffer; | |
for ( unsigned int i = 0; i < nBufferFrames; i++ ) { | |
*samples++ = volume * sine->tick(); | |
} | |
if (sine->isFinished()) { | |
sine->reset(); | |
} | |
return 0; | |
} | |
int tick2( void *outputBuffer, void *inputBuffer, unsigned int nBufferFrames, | |
double streamTime, RtAudioStreamStatus status, void *dataPointer ) | |
{ | |
FileWvIn *sine = (FileWvIn *) dataPointer; | |
register StkFloat *samples = (StkFloat *) outputBuffer; | |
for ( unsigned int i = 0; i < nBufferFrames; i++ ) { | |
*samples++ = volume * sine->tick(); | |
} | |
if (sine->isFinished()) { | |
sine->reset(); | |
} | |
return 0; | |
} | |
int tick3( void *outputBuffer, void *inputBuffer, unsigned int nBufferFrames, | |
double streamTime, RtAudioStreamStatus status, void *dataPointer ) | |
{ | |
FileWvIn *sine = (FileWvIn *) dataPointer; | |
register StkFloat *samples = (StkFloat *) outputBuffer; | |
for ( unsigned int i = 0; i < nBufferFrames; i++ ) { | |
*samples++ = volume * sine->tick(); | |
} | |
if (sine->isFinished()) { | |
sine->reset(); | |
} | |
return 0; | |
} | |
int tick4( void *outputBuffer, void *inputBuffer, unsigned int nBufferFrames, | |
double streamTime, RtAudioStreamStatus status, void *dataPointer ) | |
{ | |
FileWvIn *sine = (FileWvIn *) dataPointer; | |
register StkFloat *samples = (StkFloat *) outputBuffer; | |
for ( unsigned int i = 0; i < nBufferFrames; i++ ) { | |
*samples++ = volume * sine->tick(); | |
} | |
if (sine->isFinished()) { | |
sine->reset(); | |
} | |
return 0; | |
} | |
// Function that breaks string into tokens according to a delimeter | |
std::vector<std::string> &split(const std::string &s, char delim, std::vector<std::string> &elems) { | |
std::stringstream ss(s); | |
std::string item; | |
while (std::getline(ss, item, delim)) { | |
elems.push_back(item); | |
} | |
return elems; | |
} | |
/*std::vector<std::string> split(const std::string &s, char delim) { | |
std::vector<std::string> elems; | |
split(s, delim, elems); | |
return elems; | |
}*/ | |
// This function splits a string into tokens according to a delimeter | |
// The tokens are converted to unsigned int and returned | |
std::vector<unsigned int> split(const std::string &s, char delim) { | |
std::vector<std::string> elems; | |
split(s, delim, elems); | |
std::vector<unsigned int> numbers; | |
unsigned int num; | |
for (unsigned int i = 0; i < elems.size(); i++) { | |
num = (unsigned int)atoi(elems[i].c_str()); | |
if (num > 600) | |
//num = 600; | |
if (num < 30) | |
num = 30; | |
numbers.push_back( num ); | |
} | |
return numbers; | |
} | |
int main() | |
{ | |
std::cout << "Welcome to Joen's player" << std::endl; | |
// Declare variables | |
asio::io_service io; | |
asio::serial_port port(io); | |
// Address of serial port | |
char port_name[] = "/dev/tty.usbmodem1d1361"; | |
// Open serial port and set options | |
cout << "Opening port " << port_name << "..."; | |
port.open( port_name ); | |
port.set_option( asio::serial_port_base::baud_rate(9600) ); | |
port.set_option( asio::serial_port_base::parity() ); // default none | |
port.set_option( asio::serial_port_base::character_size( 8 ) ); | |
port.set_option( asio::serial_port_base::stop_bits() ); // default one | |
cout << "ok" << std::endl; | |
// Set the global sample rate before creating class instances. | |
Stk::setSampleRate( 44100.0 ); | |
// Load the files | |
FileWvIn input; | |
FileWvIn input2; | |
FileWvIn input3; | |
FileWvIn input4; | |
FileWvIn input5; | |
input.openFile("wave/H√∏jtaler mix 2.aif"); | |
input2.openFile("wave/H√∏jtaler mix 5.aif"); | |
input3.openFile("wave/H√∏jtaler mix 4.aif"); | |
input4.openFile("wave/H√∏jtaler mix 1.aif"); | |
input5.openFile("wave/H√∏jtaler mix 3.aif"); | |
// Initialize audio engine | |
RtAudio rtengine(RtAudio::MACOSX_CORE); | |
RtAudio rtengine2(RtAudio::MACOSX_CORE); | |
RtAudio rtengine3(RtAudio::MACOSX_CORE); | |
RtAudio rtengine4(RtAudio::MACOSX_CORE); | |
RtAudio rtengine5(RtAudio::MACOSX_CORE); | |
// Set parameters for audio streams | |
RtAudio::StreamParameters parameters, parameters2, parameters3; | |
RtAudio::StreamParameters parameters4, parameters5; | |
parameters.deviceId = 2; | |
parameters.nChannels = 1; | |
parameters2.deviceId = 3; | |
parameters2.nChannels = 1; | |
parameters3.deviceId = 4; | |
parameters3.nChannels = 1; | |
parameters4.deviceId = 5; | |
parameters4.nChannels = 1; | |
parameters5.deviceId = 6; | |
parameters5.nChannels = 1; | |
// Start the audio interfaces | |
RtAudioFormat format = ( sizeof(StkFloat) == 8 ) ? RTAUDIO_FLOAT64 : RTAUDIO_FLOAT32; | |
unsigned int bufferFrames = RT_BUFFER_SIZE; | |
try { | |
rtengine.openStream( ¶meters, NULL, format, (unsigned int)Stk::sampleRate(), &bufferFrames, &tick, (void *)&input); | |
rtengine2.openStream( ¶meters2, NULL, format, (unsigned int)Stk::sampleRate(), &bufferFrames, &tick1, (void *)&input2 ); | |
rtengine3.openStream( ¶meters3, NULL, format, (unsigned int)Stk::sampleRate(), &bufferFrames, &tick2, (void *)&input3 ); | |
rtengine4.openStream( ¶meters4, NULL, format, (unsigned int)Stk::sampleRate(), &bufferFrames, &tick3, (void *)&input4 ); | |
rtengine5.openStream( ¶meters5, NULL, format, (unsigned int)Stk::sampleRate(), &bufferFrames, &tick4, (void *)&input5 ); | |
} | |
catch ( RtError &error ) { | |
error.printMessage(); | |
return -2; | |
} | |
// Start reading from serial port | |
// Get 100 first readings, we assume it's junk | |
char c = 0; | |
for (int j = 0; j < 200; j++) { | |
while (c != 10) { | |
asio::read( port, asio::buffer(&c, 1) ); | |
}; | |
} | |
cout << "Entering infinite loop..." << std::endl; | |
stringstream stream; | |
std::vector<unsigned int> values; | |
string s; | |
double timer0, timer1, timer2, timer3, timer4; | |
bool timer0_state, timer1_state, timer2_state, timer3_state, timer4_state; | |
bool should0, should1, should2, should3, should4; | |
unsigned int val0, val1, val2, val3, val4; | |
timer0 = 0; | |
timer1 = 0; | |
timer2 = 0; | |
timer3 = 0; | |
timer4 = 0; | |
// Inside this infinite loop we read one entire line | |
// which means 5 numbers, 5 readings from the sensors | |
while (1) { | |
// Reset | |
c = 0; | |
stream.str(""); | |
// Wait until a line is read from the serial port | |
while (c != 10) { | |
asio::read( port, asio::buffer(&c, 1) ); | |
if (c != 10) { | |
stream << c; | |
} | |
} | |
// Get the line, explode it and get the numeric values | |
s = stream.str(); | |
stream.flush(); | |
values = split(s, '-'); | |
val0 = values[0]; | |
val1 = values[1]; | |
val2 = values[2]; | |
val3 = values[3]; | |
val4 = values[4]; | |
//cout << val0 << "\t" << val1 << "\t" << val2 << "\t" << val3 << "\t" << val4 << endl; | |
//cout << val0 << "\t" << ((val0 <= threshold) ? "under" : "over") << "\t" << ((timer0_state) ? "timer waiting" : "no timer") << "\t" << ((timer0_state) ? (rtengine3.getStreamTime() - timer0) : rtengine3.getStreamTime()) << endl; | |
//cout << ((should0) ? "1" : "0") << "\t" << ((should1) ? "1" : "0") << "\t" << ((should2) ? "1" : "0") << "\t" << ((should3) ? "1" : "0") << "\t" << ((should4) ? "1" : "0") << endl; | |
cout << ((val0 <= threshold) ? "under" : "over") << "\t"; | |
cout << ((val1 <= threshold) ? "under" : "over") << "\t"; | |
cout << ((val2 <= threshold) ? "under" : "over") << "\t"; | |
cout << ((val3 <= threshold) ? "under" : "over") << "\t"; | |
cout << ((val4 <= threshold) ? "under" : "over") << std::endl; | |
cout << timer0 << "\t"; | |
cout << timer1 << "\t"; | |
cout << timer2 << "\t"; | |
cout << timer3 << "\t"; | |
cout << timer4 << std::endl; | |
// Val0 | |
if (val0 <= threshold) { | |
if (!rtengine3.isStreamRunning()) { | |
rtengine3.startStream(); | |
} | |
timer0_state = true; | |
} else { | |
if (timer0_state) { | |
timer0 = rtengine3.getStreamTime(); | |
timer0_state = false; | |
} | |
if (!timer0_state) { | |
if (rtengine3.getStreamTime() - timer0 > timer_threshold) { | |
if (rtengine3.isStreamRunning()) { | |
rtengine3.abortStream(); | |
} | |
} | |
} | |
} | |
// Val1 | |
if (val1 <= threshold) { | |
if (!rtengine4.isStreamRunning()) { | |
rtengine4.startStream(); | |
} | |
timer1_state = true; | |
} else { | |
if (timer1_state) { | |
timer1 = rtengine4.getStreamTime(); | |
timer1_state = false; | |
} | |
if (!timer1_state) { | |
if (rtengine4.getStreamTime() - timer1 > timer_threshold) { | |
if (rtengine4.isStreamRunning()) { | |
rtengine4.abortStream(); | |
} | |
} | |
} | |
} | |
// Val2 | |
if (val2 <= threshold) { | |
if (!rtengine.isStreamRunning()) { | |
rtengine.startStream(); | |
} | |
timer2_state = true; | |
} else { | |
if (timer2_state) { | |
timer2 = rtengine.getStreamTime(); | |
timer2_state = false; | |
} | |
if (!timer2_state) { | |
if (rtengine.getStreamTime() - timer2 > timer_threshold) { | |
if (rtengine.isStreamRunning()) { | |
rtengine.abortStream(); | |
} | |
} | |
} | |
} | |
// Val3 | |
if (val3 <= threshold) { | |
if (!rtengine2.isStreamRunning()) { | |
rtengine2.startStream(); | |
} | |
timer3_state = true; | |
} else { | |
if (timer3_state) { | |
timer3 = rtengine2.getStreamTime(); | |
timer3_state = false; | |
} | |
if (!timer3_state) { | |
if (rtengine2.getStreamTime() - timer3 > timer_threshold) { | |
if (rtengine2.isStreamRunning()) { | |
rtengine2.abortStream(); | |
} | |
} | |
} | |
} | |
// Val4 | |
if (val4 <= threshold) { | |
if (!rtengine5.isStreamRunning()) { | |
rtengine5.startStream(); | |
} | |
timer4_state = true; | |
} else { | |
if (timer4_state) { | |
timer4 = rtengine5.getStreamTime(); | |
timer4_state = false; | |
} | |
if (!timer4_state) { | |
if (rtengine5.getStreamTime() - timer4 > timer_threshold) { | |
if (rtengine5.isStreamRunning()) { | |
rtengine5.abortStream(); | |
} | |
} | |
} | |
} | |
} | |
// Close the serial port | |
port.close(); | |
// Shut down the output stream. | |
try { | |
rtengine.closeStream(); | |
rtengine2.closeStream(); | |
rtengine3.closeStream(); | |
rtengine4.closeStream(); | |
rtengine5.closeStream(); | |
} | |
catch ( RtError &error ) { | |
error.printMessage(); | |
} | |
std::cout << "I'm going to sleep now. Goodbye!" << std::endl; | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment