Merge branch 'master' of https://github.com/worklist/hifi into pointy

This commit is contained in:
Andrzej Kapolka 2013-08-02 18:00:42 -07:00
commit 5f40923db2
8 changed files with 130 additions and 11 deletions

View file

@ -1877,7 +1877,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);
(_noise = optionsMenu->addAction("Noise", this, SLOT(setNoise(bool)), Qt::Key_N))->setCheckable(true);
(_gyroLook = optionsMenu->addAction("Smooth Gyro Look"))->setCheckable(true);
@ -1897,6 +1897,10 @@ void Application::initMenu() {
optionsMenu->addAction("Cycle Webcam Send Mode", _webcam.getGrabber(), SLOT(cycleVideoSendMode()));
optionsMenu->addAction("Go Home", this, SLOT(goHome()), Qt::CTRL | Qt::Key_G);
QMenu* audioMenu = menuBar->addMenu("Audio");
(_echoAudioMode = audioMenu->addAction("Echo Audio"))->setCheckable(true);
_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);
_renderVoxels->setChecked(true);
@ -2066,6 +2070,22 @@ void Application::setListenModeSingleSource() {
}
}
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");
}
}
void Application::updateFrustumRenderModeAction() {
switch (_frustumDrawingMode) {

View file

@ -177,6 +177,7 @@ private slots:
void setListenModeNormal();
void setListenModePoint();
void setListenModeSingleSource();
void toggleMixedSong();
void renderCoverageMap();
@ -288,6 +289,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* _noise;
QAction* _occlusionCulling;

View file

@ -8,13 +8,11 @@
#ifndef _WIN32
#include <cstring>
#include <fstream>
#include <iostream>
#include <pthread.h>
#include <sys/stat.h>
#include <AngleUtil.h>
#include <NodeList.h>
#include <NodeTypes.h>
@ -155,8 +153,38 @@ 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));
// 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
memcpy(currentPacketPtr, inputLeft, BUFFER_LENGTH_BYTES_PER_CHANNEL);
nodeList->getNodeSocket()->send((sockaddr*) &audioSocket,
dataPacket,
BUFFER_LENGTH_BYTES_PER_CHANNEL + leadingBytes);
@ -385,7 +413,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 +486,25 @@ 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::stopMixingSongWithMicrophone() {
qDebug("Stop mixing called!");
_songFileBytes = 0;
}
void Audio::addReceivedAudioToBuffer(unsigned char* receivedData, int receivedBytes) {
const int NUM_INITIAL_PACKETS_DISCARD = 3;
const int STANDARD_DEVIATION_SAMPLE_COUNT = 500;

View file

@ -9,8 +9,13 @@
#ifndef __interface__Audio__
#define __interface__Audio__
#include <fstream>
#include <vector>
#include <QObject>
#include <portaudio.h>
#include <AudioRingBuffer.h>
#include <StdDev.h>
@ -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,6 +53,7 @@ public:
void startCollisionSound(float magnitude, float frequency, float noise, float duration);
float getCollisionSoundMagnitude() { return _collisionSoundMagnitude; };
int getSongFileBytes() { return _songFileBytes; }
void ping();
@ -60,8 +67,13 @@ public:
void addListenSource(int sourceID);
void removeListenSource(int sourceID);
void clearListenSources();
void importSongToMixWithMicrophone(const char* filename);
public slots:
void stopMixingSongWithMicrophone();
private:
private:
PaStream* _stream;
AudioRingBuffer _ringBuffer;
Oscilloscope* _scope;
@ -96,6 +108,8 @@ private:
float _collisionSoundDuration;
int _proceduralEffectSample;
float _heartbeatMagnitude;
std::ifstream* _songFileStream;
int _songFileBytes;
AudioRingBuffer::ListenMode _listenMode;
float _listenRadius;

View file

@ -44,12 +44,28 @@ JurisdictionMap::JurisdictionMap(const char* filename) : _rootOctalCode(NULL) {
readFromFile(filename);
}
JurisdictionMap::JurisdictionMap(unsigned char* rootOctalCode, const std::vector<unsigned char*>& 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<unsigned char*>& endNodes) {
clear(); // clean up our own memory
_rootOctalCode = rootOctalCode;

View file

@ -23,6 +23,7 @@ public:
JurisdictionMap();
JurisdictionMap(const char* filename);
JurisdictionMap(unsigned char* rootOctalCode, const std::vector<unsigned char*>& endNodes);
JurisdictionMap(const char* rootHextString, const char* endNodesHextString);
~JurisdictionMap();
Area isMyJurisdiction(unsigned char* nodeOctalCode, int childIndex) const;

View file

@ -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 octcode]
Tells the server to honor jurisdiction from the specified root node and below
--jurisdictionEndNodes [<octcode>(<,octcode>...)]
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

View file

@ -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);