From 06e249b872b08ac4034d6c1016505d143e792b62 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Fri, 2 Aug 2013 15:38:43 -0700 Subject: [PATCH 1/7] added command line options for jurisdiction settings --- libraries/voxels/src/JurisdictionMap.cpp | 18 +++++++++++++++++- libraries/voxels/src/JurisdictionMap.h | 1 + 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/libraries/voxels/src/JurisdictionMap.cpp b/libraries/voxels/src/JurisdictionMap.cpp index b67963d8d6..f67bbbabf7 100644 --- a/libraries/voxels/src/JurisdictionMap.cpp +++ b/libraries/voxels/src/JurisdictionMap.cpp @@ -44,12 +44,28 @@ JurisdictionMap::JurisdictionMap(const char* filename) : _rootOctalCode(NULL) { readFromFile(filename); } - JurisdictionMap::JurisdictionMap(unsigned char* rootOctalCode, const std::vector& endNodes) : _rootOctalCode(NULL) { init(rootOctalCode, endNodes); } +JurisdictionMap::JurisdictionMap(const char* rootHexCode, const char* endNodesHexCodes) { + _rootOctalCode = hexStringToOctalCode(QString(rootHexCode)); + + QString endNodesHexStrings(endNodesHexCodes); + QString delimiterPattern(","); + QStringList endNodeList = endNodesHexStrings.split(delimiterPattern); + + for (int i = 0; i < endNodeList.size(); i++) { + QString endNodeHexString = endNodeList.at(i); + + unsigned char* endNodeOctcode = hexStringToOctalCode(endNodeHexString); + //printOctalCode(endNodeOctcode); + _endNodes.push_back(endNodeOctcode); + } +} + + void JurisdictionMap::init(unsigned char* rootOctalCode, const std::vector& endNodes) { clear(); // clean up our own memory _rootOctalCode = rootOctalCode; diff --git a/libraries/voxels/src/JurisdictionMap.h b/libraries/voxels/src/JurisdictionMap.h index a52765549f..6c7cc4f0ca 100644 --- a/libraries/voxels/src/JurisdictionMap.h +++ b/libraries/voxels/src/JurisdictionMap.h @@ -23,6 +23,7 @@ public: JurisdictionMap(); JurisdictionMap(const char* filename); JurisdictionMap(unsigned char* rootOctalCode, const std::vector& endNodes); + JurisdictionMap(const char* rootHextString, const char* endNodesHextString); ~JurisdictionMap(); Area isMyJurisdiction(unsigned char* nodeOctalCode, int childIndex) const; From ba5480e17626a6332fbc8fe58cecc2217fb6af75 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Fri, 2 Aug 2013 15:38:50 -0700 Subject: [PATCH 2/7] added command line options for jurisdiction settings --- voxel-server/src/main.cpp | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/voxel-server/src/main.cpp b/voxel-server/src/main.cpp index 329e8d803c..5d7489135a 100644 --- a/voxel-server/src/main.cpp +++ b/voxel-server/src/main.cpp @@ -456,11 +456,22 @@ int main(int argc, const char * argv[]) { printf("about to readFromFile().... jurisdictionFile=%s\n", jurisdictionFile); jurisdiction = new JurisdictionMap(jurisdictionFile); printf("after readFromFile().... jurisdictionFile=%s\n", jurisdictionFile); + } else { + const char* JURISDICTION_ROOT = "--jurisdictionRoot"; + const char* jurisdictionRoot = getCmdOption(argc, argv, JURISDICTION_ROOT); + if (jurisdictionRoot) { + printf("jurisdictionRoot=%s\n", jurisdictionRoot); + } - // test writing the file... - printf("about to writeToFile().... jurisdictionFile=%s\n", jurisdictionFile); - jurisdiction->writeToFile(jurisdictionFile); - printf("after writeToFile().... jurisdictionFile=%s\n", jurisdictionFile); + const char* JURISDICTION_ENDNODES = "--jurisdictionEndNodes"; + const char* jurisdictionEndNodes = getCmdOption(argc, argv, JURISDICTION_ENDNODES); + if (jurisdictionEndNodes) { + printf("jurisdictionEndNodes=%s\n", jurisdictionEndNodes); + } + + if (jurisdictionRoot || jurisdictionEndNodes) { + jurisdiction = new JurisdictionMap(jurisdictionRoot, jurisdictionEndNodes); + } } NodeList* nodeList = NodeList::createInstance(NODE_TYPE_VOXEL_SERVER, listenPort); From f28f8d71d191ce629ee6440b5487ff28556e8fd8 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Fri, 2 Aug 2013 15:41:49 -0700 Subject: [PATCH 3/7] added command line options for jurisdiction settings --- voxel-server/src/README | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/voxel-server/src/README b/voxel-server/src/README index 81824d96a9..44d6439070 100644 --- a/voxel-server/src/README +++ b/voxel-server/src/README @@ -15,6 +15,12 @@ OPTIONS --local This will run the voxel server in "local domain mode" and will look for a domain-server running on the same IP address as the voxel server + + --jurisdictionRoot [hex string of root octalcode] + Tells the server to honor jurisdiction from the specified root node and below + + --jurisdictionEndNodes [(<,octcode>...)] + Tells the server to honor jurisdiction from the root down to the octcodes included in the comma separted list --jurisdictionFile [filename] Tells the server to load it's jurisdiction from the specified file. When a voxel server is running with a limited From 6b483e4b22eeb316f9a4bf3398acf1c074a8a8c8 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Fri, 2 Aug 2013 15:44:05 -0700 Subject: [PATCH 4/7] added command line options for jurisdiction settings --- voxel-server/src/README | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/voxel-server/src/README b/voxel-server/src/README index 44d6439070..76ed051679 100644 --- a/voxel-server/src/README +++ b/voxel-server/src/README @@ -16,11 +16,11 @@ OPTIONS This will run the voxel server in "local domain mode" and will look for a domain-server running on the same IP address as the voxel server - --jurisdictionRoot [hex string of root octalcode] + --jurisdictionRoot [hex string of root octcode] Tells the server to honor jurisdiction from the specified root node and below --jurisdictionEndNodes [(<,octcode>...)] - Tells the server to honor jurisdiction from the root down to the octcodes included in the comma separted list + Tells the server to honor jurisdiction from the root down to the octcodes included in the comma separated list --jurisdictionFile [filename] Tells the server to load it's jurisdiction from the specified file. When a voxel server is running with a limited From d56b715432b3708b06056e4edf6c168952bef238 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 2 Aug 2013 17:30:49 -0700 Subject: [PATCH 5/7] add menu option to mix RAW audio with microphone audio --- interface/src/Application.cpp | 15 +++++++++++++- interface/src/Application.h | 1 + interface/src/Audio.cpp | 39 ++++++++++++++++++++++++++++++++--- interface/src/Audio.h | 15 +++++++++++--- 4 files changed, 63 insertions(+), 7 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 0f87e2f063..58e6ffebff 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1772,7 +1772,7 @@ void Application::initMenu() { QMenu* optionsMenu = menuBar->addMenu("Options"); (_lookingInMirror = optionsMenu->addAction("Mirror", this, SLOT(setRenderMirrored(bool)), Qt::Key_H))->setCheckable(true); - (_echoAudioMode = optionsMenu->addAction("Echo Audio"))->setCheckable(true); + optionsMenu->addAction("Noise", this, SLOT(setNoise(bool)), Qt::Key_N)->setCheckable(true); (_gyroLook = optionsMenu->addAction("Smooth Gyro Look"))->setCheckable(true); @@ -1791,6 +1791,10 @@ void Application::initMenu() { optionsMenu->addAction("Cycle Webcam Send Mode", _webcam.getGrabber(), SLOT(cycleVideoSendMode())); optionsMenu->addAction("Go Home", this, SLOT(goHome())); + QMenu* audioMenu = menuBar->addMenu("Audio"); + (_echoAudioMode = audioMenu->addAction("Echo Audio"))->setCheckable(true); + audioMenu->addAction("Mix RAW Audio", this, SLOT(importMixSong())); + QMenu* renderMenu = menuBar->addMenu("Render"); (_renderVoxels = renderMenu->addAction("Voxels", this, SLOT(setRenderVoxels(bool)), Qt::SHIFT | Qt::Key_V))->setCheckable(true); _renderVoxels->setChecked(true); @@ -1959,6 +1963,15 @@ void Application::setListenModeSingleSource() { } } +void Application::importMixSong() { + QString filename = QFileDialog::getOpenFileName(_glWidget, + tr("Choose RAW Audio file"), + QStandardPaths::writableLocation(QStandardPaths::DesktopLocation), + tr("RAW Audio file (*.raw)")); + + _audio.importSongToMixWithMicrophone(filename.toLocal8Bit().data()); +} + void Application::updateFrustumRenderModeAction() { switch (_frustumDrawingMode) { diff --git a/interface/src/Application.h b/interface/src/Application.h index 80ebd34250..13dcb73844 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -177,6 +177,7 @@ private slots: void setListenModeNormal(); void setListenModePoint(); void setListenModeSingleSource(); + void importMixSong(); void renderCoverageMap(); diff --git a/interface/src/Audio.cpp b/interface/src/Audio.cpp index a9aa61a34e..c7e7590eab 100644 --- a/interface/src/Audio.cpp +++ b/interface/src/Audio.cpp @@ -8,13 +8,11 @@ #ifndef _WIN32 #include -#include #include #include #include - #include #include #include @@ -155,8 +153,26 @@ inline void Audio::performIO(int16_t* inputLeft, int16_t* outputLeft, int16_t* o memcpy(currentPacketPtr, &headOrientation, sizeof(headOrientation)); currentPacketPtr += sizeof(headOrientation); + // check if we have a song to add to our audio + if (_songFileBytes > 0 && _songFileStream->tellg() <= _songFileBytes) { + // iterate over BUFFER_LENGTH_SAMPLES_PER_CHANNEL from the song file and add that to our audio + for (int i = 0; i < BUFFER_LENGTH_SAMPLES_PER_CHANNEL; i++) { + int16_t songSample = 0; + + _songFileStream->read((char*) &songSample, sizeof(songSample)); + + const float SONG_SAMPLE_ATTENUATION = 0.25; + songSample *= SONG_SAMPLE_ATTENUATION; + + inputLeft[i] = inputLeft[i] + songSample; + outputLeft[i] = outputLeft[i] + songSample; + outputRight[i] = outputLeft[i] + songSample; + } + } + // copy the audio data to the last BUFFER_LENGTH_BYTES bytes of the data packet memcpy(currentPacketPtr, inputLeft, BUFFER_LENGTH_BYTES_PER_CHANNEL); + nodeList->getNodeSocket()->send((sockaddr*) &audioSocket, dataPacket, BUFFER_LENGTH_BYTES_PER_CHANNEL + leadingBytes); @@ -385,7 +401,9 @@ Audio::Audio(Oscilloscope* scope, int16_t initialJitterBufferSamples) : _proceduralEffectSample(0), _heartbeatMagnitude(0.0f), _listenMode(AudioRingBuffer::NORMAL), - _listenRadius(0.0f) + _listenRadius(0.0f), + _songFileStream(NULL), + _songFileBytes(0) { outputPortAudioError(Pa_Initialize()); @@ -456,6 +474,21 @@ Audio::~Audio() { delete[] _echoSamplesLeft; } + +void Audio::importSongToMixWithMicrophone(const char* filename) { + _songFileStream = new std::ifstream(filename); + + long begin = _songFileStream->tellg(); + _songFileStream->seekg(0, std::ios::end); + long end = _songFileStream->tellg(); + + // go back to the beginning + _songFileStream->seekg(0); + + _songFileBytes = end - begin; +} + + void Audio::addReceivedAudioToBuffer(unsigned char* receivedData, int receivedBytes) { const int NUM_INITIAL_PACKETS_DISCARD = 3; const int STANDARD_DEVIATION_SAMPLE_COUNT = 500; diff --git a/interface/src/Audio.h b/interface/src/Audio.h index 2eb4e7ef70..7d7c95c9ee 100644 --- a/interface/src/Audio.h +++ b/interface/src/Audio.h @@ -9,8 +9,13 @@ #ifndef __interface__Audio__ #define __interface__Audio__ +#include #include + +#include + #include + #include #include @@ -23,7 +28,8 @@ static const int PACKET_LENGTH_BYTES_PER_CHANNEL = PACKET_LENGTH_BYTES / 2; static const int PACKET_LENGTH_SAMPLES = PACKET_LENGTH_BYTES / sizeof(int16_t); static const int PACKET_LENGTH_SAMPLES_PER_CHANNEL = PACKET_LENGTH_SAMPLES / 2; -class Audio { +class Audio : public QObject { + Q_OBJECT public: // initializes audio I/O Audio(Oscilloscope* scope, int16_t initialJitterBufferSamples); @@ -47,7 +53,6 @@ public: void startCollisionSound(float magnitude, float frequency, float noise, float duration); float getCollisionSoundMagnitude() { return _collisionSoundMagnitude; }; - void ping(); // Call periodically to eventually perform round trip time analysis, @@ -60,8 +65,10 @@ public: void addListenSource(int sourceID); void removeListenSource(int sourceID); void clearListenSources(); + + void importSongToMixWithMicrophone(const char* filename); -private: +private: PaStream* _stream; AudioRingBuffer _ringBuffer; Oscilloscope* _scope; @@ -96,6 +103,8 @@ private: float _collisionSoundDuration; int _proceduralEffectSample; float _heartbeatMagnitude; + std::ifstream* _songFileStream; + int _songFileBytes; AudioRingBuffer::ListenMode _listenMode; float _listenRadius; From d259180778313fb964aa7ed3c09d48b3a866bdab Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 2 Aug 2013 17:46:23 -0700 Subject: [PATCH 6/7] add option to audio menu to stop the mixed audio --- interface/src/Application.cpp | 23 +++++++++++++++-------- interface/src/Application.h | 3 ++- interface/src/Audio.cpp | 8 ++++++++ interface/src/Audio.h | 5 +++++ 4 files changed, 30 insertions(+), 9 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 58e6ffebff..4baebd050e 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1793,7 +1793,7 @@ void Application::initMenu() { QMenu* audioMenu = menuBar->addMenu("Audio"); (_echoAudioMode = audioMenu->addAction("Echo Audio"))->setCheckable(true); - audioMenu->addAction("Mix RAW Audio", this, SLOT(importMixSong())); + _rawAudioMicrophoneMix = audioMenu->addAction("Mix RAW Song", this, SLOT(toggleMixedSong())); QMenu* renderMenu = menuBar->addMenu("Render"); (_renderVoxels = renderMenu->addAction("Voxels", this, SLOT(setRenderVoxels(bool)), Qt::SHIFT | Qt::Key_V))->setCheckable(true); @@ -1963,13 +1963,20 @@ void Application::setListenModeSingleSource() { } } -void Application::importMixSong() { - QString filename = QFileDialog::getOpenFileName(_glWidget, - tr("Choose RAW Audio file"), - QStandardPaths::writableLocation(QStandardPaths::DesktopLocation), - tr("RAW Audio file (*.raw)")); - - _audio.importSongToMixWithMicrophone(filename.toLocal8Bit().data()); +void Application::toggleMixedSong() { + if (_audio.getSongFileBytes() == 0) { + QString filename = QFileDialog::getOpenFileName(_glWidget, + tr("Choose RAW Audio file"), + QStandardPaths::writableLocation(QStandardPaths::DesktopLocation), + tr("RAW Audio file (*.raw)")); + + QByteArray filenameArray = filename.toLocal8Bit(); + _audio.importSongToMixWithMicrophone(filenameArray.data()); + _rawAudioMicrophoneMix->setText("Stop Mixing Song"); + } else { + _audio.stopMixingSongWithMicrophone(); + _rawAudioMicrophoneMix->setText("Mix RAW Song"); + } } diff --git a/interface/src/Application.h b/interface/src/Application.h index 13dcb73844..c05b62d70c 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -177,7 +177,7 @@ private slots: void setListenModeNormal(); void setListenModePoint(); void setListenModeSingleSource(); - void importMixSong(); + void toggleMixedSong(); void renderCoverageMap(); @@ -287,6 +287,7 @@ private: QAction* _fullScreenMode; // whether we are in full screen mode QAction* _frustumRenderModeAction; QAction* _settingsAutosave; // Whether settings are saved automatically + QAction* _rawAudioMicrophoneMix; // Mixing of a RAW audio file with microphone stream for rave gloves QAction* _renderCoverageMapV2; QAction* _renderCoverageMap; diff --git a/interface/src/Audio.cpp b/interface/src/Audio.cpp index c7e7590eab..9881eb4650 100644 --- a/interface/src/Audio.cpp +++ b/interface/src/Audio.cpp @@ -168,6 +168,10 @@ inline void Audio::performIO(int16_t* inputLeft, int16_t* outputLeft, int16_t* o outputLeft[i] = outputLeft[i] + songSample; outputRight[i] = outputLeft[i] + songSample; } + } else if (_songFileStream) { + _songFileStream->close(); + delete _songFileStream; + _songFileStream = NULL; } // copy the audio data to the last BUFFER_LENGTH_BYTES bytes of the data packet @@ -488,6 +492,10 @@ void Audio::importSongToMixWithMicrophone(const char* filename) { _songFileBytes = end - begin; } +void Audio::stopMixingSongWithMicrophone() { + qDebug("Stop mixing called!"); + _songFileBytes = 0; +} void Audio::addReceivedAudioToBuffer(unsigned char* receivedData, int receivedBytes) { const int NUM_INITIAL_PACKETS_DISCARD = 3; diff --git a/interface/src/Audio.h b/interface/src/Audio.h index 7d7c95c9ee..249453c877 100644 --- a/interface/src/Audio.h +++ b/interface/src/Audio.h @@ -53,6 +53,8 @@ public: void startCollisionSound(float magnitude, float frequency, float noise, float duration); float getCollisionSoundMagnitude() { return _collisionSoundMagnitude; }; + int getSongFileBytes() { return _songFileBytes; } + void ping(); // Call periodically to eventually perform round trip time analysis, @@ -67,6 +69,9 @@ public: void clearListenSources(); void importSongToMixWithMicrophone(const char* filename); + +public slots: + void stopMixingSongWithMicrophone(); private: PaStream* _stream; From 222a46189f53ab10fadb6ec7c83c0f0bedb4a1ce Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 2 Aug 2013 17:50:08 -0700 Subject: [PATCH 7/7] some comments and _songFileBytes reset --- interface/src/Audio.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/interface/src/Audio.cpp b/interface/src/Audio.cpp index 9881eb4650..c1466d5571 100644 --- a/interface/src/Audio.cpp +++ b/interface/src/Audio.cpp @@ -161,17 +161,25 @@ inline void Audio::performIO(int16_t* inputLeft, int16_t* outputLeft, int16_t* o _songFileStream->read((char*) &songSample, sizeof(songSample)); + // attenuate the song samples since they will be loud const float SONG_SAMPLE_ATTENUATION = 0.25; songSample *= SONG_SAMPLE_ATTENUATION; + // add the song sample to the output and input buffersg inputLeft[i] = inputLeft[i] + songSample; outputLeft[i] = outputLeft[i] + songSample; outputRight[i] = outputLeft[i] + songSample; } } else if (_songFileStream) { + // close the stream _songFileStream->close(); + + // delete the _songFileStream delete _songFileStream; _songFileStream = NULL; + + // reset the _songFileBytes back to zero + _songFileBytes = 0; } // copy the audio data to the last BUFFER_LENGTH_BYTES bytes of the data packet