From 1aff6c23a15a0d4677158b80392ca63c889b4a1f Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 29 Jan 2013 16:27:02 -0800 Subject: [PATCH] split audio tests into multiple classes, expand gitignore --- .gitignore | 14 ++++++ Source/AudioData.cpp | 30 +++++++++++ Source/AudioData.h | 30 +++++++++++ Source/AudioSource.cpp | 31 ++++++++++++ Source/AudioSource.h | 28 +++++++++++ Source/audio.cpp | 78 +++++++++-------------------- Source/audio.h | 24 ++------- interface.xcodeproj/project.pbxproj | 12 +++++ 8 files changed, 171 insertions(+), 76 deletions(-) create mode 100644 Source/AudioData.cpp create mode 100644 Source/AudioData.h create mode 100644 Source/AudioSource.cpp create mode 100644 Source/AudioSource.h diff --git a/.gitignore b/.gitignore index 47042c2291..7b7a50dbf6 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,16 @@ .DS_Store xcuserdata +*.pbxuser +!default.pbxuser +*.mode1v3 +!default.mode1v3 +*.mode2v3 +!default.mode2v3 +*.perspectivev3 +!default.perspectivev3 +xcuserdata +profile +*.moved-aside +DerivedData +.idea/ +*.hmap \ No newline at end of file diff --git a/Source/AudioData.cpp b/Source/AudioData.cpp new file mode 100644 index 0000000000..1b093d3165 --- /dev/null +++ b/Source/AudioData.cpp @@ -0,0 +1,30 @@ +// +// AudioData.cpp +// interface +// +// Created by Stephen Birarda on 1/29/13. +// Copyright (c) 2013 HighFidelity, Inc. All rights reserved. +// + +#include "AudioData.h" + +AudioData::AudioData(int numberOfSources, int bufferLength) { + _numberOfSources = numberOfSources; + + sources = new AudioSource*[numberOfSources]; + + for(int s = 0; s < numberOfSources; s++) { + sources[s] = new AudioSource(); + std::cout << "Created a new audio source!\n"; + } + + samplesToQueue = new int16_t[bufferLength / sizeof(int16_t)]; +} + +AudioData::~AudioData() { + for (int s = 0; s < _numberOfSources; s++) { + delete sources[s]; + } + + delete[] samplesToQueue; +} \ No newline at end of file diff --git a/Source/AudioData.h b/Source/AudioData.h new file mode 100644 index 0000000000..606cda8bfa --- /dev/null +++ b/Source/AudioData.h @@ -0,0 +1,30 @@ +// +// AudioData.h +// interface +// +// Created by Stephen Birarda on 1/29/13. +// Copyright (c) 2013 HighFidelity, Inc. All rights reserved. +// + +#ifndef __interface__AudioData__ +#define __interface__AudioData__ + +#include +#include "AudioSource.h" +#include "head.h" + +class AudioData { + public: + Head *linkedHead; + AudioSource **sources; + + int16_t *samplesToQueue; + + AudioData(int numberOfSources, int bufferLength); + ~AudioData(); + + private: + int _numberOfSources; +}; + +#endif /* defined(__interface__AudioData__) */ diff --git a/Source/AudioSource.cpp b/Source/AudioSource.cpp new file mode 100644 index 0000000000..c8c7d84f71 --- /dev/null +++ b/Source/AudioSource.cpp @@ -0,0 +1,31 @@ +// +// AudioSource.cpp +// interface +// +// Created by Stephen Birarda on 1/29/13. +// Copyright (c) 2013 HighFidelity, Inc. All rights reserved. +// + +#include "AudioSource.h" + +AudioSource::~AudioSource() +{ + delete[] sourceData; +} + + +int AudioSource::loadDataFromFile(const char *filename) { + FILE *soundFile = fopen(filename, "r"); + + // get length of file: + std::fseek(soundFile, 0, SEEK_END); + lengthInSamples = std::ftell(soundFile) / sizeof(int16_t); + std::rewind(soundFile); + + sourceData = new int16_t[lengthInSamples]; + std::fread(sourceData, sizeof(int16_t), lengthInSamples, soundFile); + + std::fclose(soundFile); + + return lengthInSamples; +} \ No newline at end of file diff --git a/Source/AudioSource.h b/Source/AudioSource.h new file mode 100644 index 0000000000..adb68c3df4 --- /dev/null +++ b/Source/AudioSource.h @@ -0,0 +1,28 @@ +// +// AudioSource.h +// interface +// +// Created by Stephen Birarda on 1/29/13. +// Copyright (c) 2013 HighFidelity, Inc. All rights reserved. +// + +#ifndef __interface__AudioSource__ +#define __interface__AudioSource__ + +#include +#include "glm.hpp" + +class AudioSource { + public: + glm::vec3 position; + int16_t *sourceData; + int lengthInSamples; + int samplePointer; + + AudioSource() { samplePointer = 0; sourceData = NULL; } + ~AudioSource(); + + int loadDataFromFile(const char *filename); +}; + +#endif /* defined(__interface__AudioSource__) */ diff --git a/Source/audio.cpp b/Source/audio.cpp index ac61a51726..8cea3d0d77 100644 --- a/Source/audio.cpp +++ b/Source/audio.cpp @@ -10,33 +10,12 @@ #include #include "audio.h" #include "util.h" +#include "AudioSource.h" bool Audio::initialized; PaError Audio::err; PaStream *Audio::stream; -Audio::AudioData *Audio::data; - - -Audio::AudioSource::~AudioSource() -{ - delete[] audioData; -} - -Audio::AudioData::AudioData() { - for(int s = 0; s < NUM_AUDIO_SOURCES; s++) { - sources[s] = AudioSource(); - } - - samplesToQueue = new int16_t[BUFFER_LENGTH_BYTES / sizeof(int16_t)]; -} - -Audio::AudioData::~AudioData() { - for (int s = 0; s < NUM_AUDIO_SOURCES; s++) { - sources[s].AudioSource::~AudioSource(); - } - - delete[] samplesToQueue; -} +AudioData *Audio::data; /** * Audio callback used by portaudio. @@ -65,7 +44,7 @@ int audioCallback (const void *inputBuffer, PaStreamCallbackFlags statusFlags, void *userData) { - Audio::AudioData *data = (Audio::AudioData *) userData; + AudioData *data = (AudioData *) userData; int16_t *outputLeft = ((int16_t **) outputBuffer)[0]; int16_t *outputRight = ((int16_t **) outputBuffer)[1]; @@ -75,19 +54,23 @@ int audioCallback (const void *inputBuffer, for (int s = 0; s < NUM_AUDIO_SOURCES; s++) { + AudioSource *source = data->sources[s]; + glm::vec3 headPos = data->linkedHead->getPos(); - glm::vec3 sourcePos = data->sources[s].position; + glm::vec3 sourcePos = source->position; + + std::cout << "L2: " << source->lengthInSamples << "\n"; - int startPointer = data->sources[s].samplePointer; - int wrapAroundSamples = (BUFFER_LENGTH_BYTES / sizeof(int16_t)) - (data->sources[s].lengthInSamples - data->sources[s].samplePointer); + int startPointer = source->samplePointer; + int wrapAroundSamples = (BUFFER_LENGTH_BYTES / sizeof(int16_t)) - (source->lengthInSamples - source->samplePointer); if (wrapAroundSamples <= 0) { - memcpy(data->samplesToQueue, data->sources[s].audioData + data->sources[s].samplePointer, BUFFER_LENGTH_BYTES); - data->sources[s].samplePointer += (BUFFER_LENGTH_BYTES / sizeof(int16_t)); + memcpy(data->samplesToQueue, source->sourceData + source->samplePointer, BUFFER_LENGTH_BYTES); + source->samplePointer += (BUFFER_LENGTH_BYTES / sizeof(int16_t)); } else { - memcpy(data->samplesToQueue, data->sources[s].audioData + data->sources[s].samplePointer, (data->sources[s].lengthInSamples - data->sources[s].samplePointer) * sizeof(int16_t)); - memcpy(data->samplesToQueue + (data->sources[s].lengthInSamples - data->sources[s].samplePointer), data->sources[s].audioData, wrapAroundSamples * sizeof(int16_t)); - data->sources[s].samplePointer = wrapAroundSamples; + memcpy(data->samplesToQueue, source->sourceData + source->samplePointer, (source->lengthInSamples - source->samplePointer) * sizeof(int16_t)); + memcpy(data->samplesToQueue + (source->lengthInSamples - source->samplePointer), source->sourceData, wrapAroundSamples * sizeof(int16_t)); + source->samplePointer = wrapAroundSamples; } float distance = sqrtf(powf(-headPos[0] - sourcePos[0], 2) + powf(-headPos[2] - sourcePos[2], 2)); @@ -114,10 +97,10 @@ int audioCallback (const void *inputBuffer, int sampleIndex = startPointer - numSamplesDelay + i; if (sampleIndex < 0) { - sampleIndex += data->sources[s].lengthInSamples; + sampleIndex += source->lengthInSamples; } - trailingOutput[i] += data->sources[s].audioData[sampleIndex] * (distanceAmpRatio * phaseAmpRatio / NUM_AUDIO_SOURCES); + trailingOutput[i] += source->sourceData[sampleIndex] * (distanceAmpRatio * phaseAmpRatio / NUM_AUDIO_SOURCES); } } } @@ -140,17 +123,17 @@ bool Audio::init() bool Audio::init(Head* mainHead) { - data = new AudioData(); + data = new AudioData(NUM_AUDIO_SOURCES, BUFFER_LENGTH_BYTES); data->linkedHead = mainHead; err = Pa_Initialize(); if (err != paNoError) goto error; - data->sources[0].position = glm::vec3(6, 0, -1); - readFile("jeska.raw", &data->sources[0]); + data->sources[0]->position = glm::vec3(6, 0, -1); + data->sources[0]->loadDataFromFile("jeska.raw"); - data->sources[1].position = glm::vec3(6, 0, 6); - readFile("grayson.raw", &data->sources[1]); + data->sources[1]->position = glm::vec3(6, 0, 6); + data->sources[1]->loadDataFromFile("grayson.raw"); err = Pa_OpenDefaultStream(&stream, NULL, // input channels @@ -185,7 +168,7 @@ void Audio::sourceSetup() // render gl objects on screen for our sources glPushMatrix(); - glTranslatef(data->sources[s].position[0], data->sources[s].position[1], data->sources[s].position[2]); + glTranslatef(data->sources[s]->position[0], data->sources[s]->position[1], data->sources[s]->position[2]); glColor3f((s == 0 ? 1 : 0), (s == 1 ? 1 : 0), (s == 2 ? 1 : 0)); glutSolidCube(0.5); @@ -194,21 +177,6 @@ void Audio::sourceSetup() } } -void Audio::readFile(const char *filename, struct AudioSource *source) -{ - FILE *soundFile = fopen(filename, "r"); - - // get length of file: - std::fseek(soundFile, 0, SEEK_END); - source->lengthInSamples = std::ftell(soundFile) / sizeof(int16_t); - std::rewind(soundFile); - - source->audioData = new int16_t[source->lengthInSamples]; - std::fread(source->audioData, sizeof(int16_t), source->lengthInSamples, soundFile); - - std::fclose(soundFile); -} - /** * Close the running audio stream, and deinitialize portaudio. * Should be called at the end of program execution. diff --git a/Source/audio.h b/Source/audio.h index 5197668922..ec390cce0a 100644 --- a/Source/audio.h +++ b/Source/audio.h @@ -12,6 +12,7 @@ #include #include "portaudio.h" #include "head.h" +#include "AudioData.h" #define BUFFER_LENGTH_BYTES 1024 #define PHASE_DELAY_AT_90 20 @@ -28,29 +29,10 @@ public: // terminates audio I/O static bool terminate(); -private: - struct AudioSource { - glm::vec3 position; - int16_t *audioData; - int lengthInSamples; - int samplePointer; - - AudioSource() { samplePointer = 0; } - ~AudioSource(); - }; - - static void readFile(const char *filename, struct AudioSource *source); +private: static bool initialized; - static struct AudioData { - Head* linkedHead; - AudioSource sources[NUM_AUDIO_SOURCES]; - - int16_t *samplesToQueue; - - AudioData(); - ~AudioData(); - } *data; + static AudioData *data; // protects constructor so that public init method is used Audio(); diff --git a/interface.xcodeproj/project.pbxproj b/interface.xcodeproj/project.pbxproj index de5f22e24f..e270809ce6 100644 --- a/interface.xcodeproj/project.pbxproj +++ b/interface.xcodeproj/project.pbxproj @@ -25,6 +25,8 @@ 5325C26016AF4DBE0051A40B /* texture.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5325C24B16AF4DBE0051A40B /* texture.cpp */; }; 5325C26116AF4DBE0051A40B /* util.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5325C24D16AF4DBE0051A40B /* util.cpp */; }; 5325C26416AF4E2C0051A40B /* audio.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5325C26216AF4E2C0051A40B /* audio.cpp */; }; + 5328864616B87E040041A07C /* AudioSource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5328864416B87E040041A07C /* AudioSource.cpp */; }; + 5328864916B881710041A07C /* AudioData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5328864716B881710041A07C /* AudioData.cpp */; }; 532C7AF216AF298D00B1A969 /* CVBlob.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 532C792A16AF298900B1A969 /* CVBlob.framework */; }; 532C7CCC16AF301E00B1A969 /* grayson-particle.png in CopyFiles */ = {isa = PBXBuildFile; fileRef = 532C7AC316AF298D00B1A969 /* grayson-particle.png */; }; 532C7CCD16AF301E00B1A969 /* int-texture256-v2.png in CopyFiles */ = {isa = PBXBuildFile; fileRef = 532C7AC416AF298D00B1A969 /* int-texture256-v2.png */; }; @@ -123,6 +125,10 @@ 5325C24F16AF4DBE0051A40B /* world.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = world.h; sourceTree = ""; }; 5325C26216AF4E2C0051A40B /* audio.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = audio.cpp; sourceTree = ""; }; 5325C26316AF4E2C0051A40B /* audio.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = audio.h; sourceTree = ""; }; + 5328864416B87E040041A07C /* AudioSource.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AudioSource.cpp; sourceTree = ""; }; + 5328864516B87E040041A07C /* AudioSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AudioSource.h; sourceTree = ""; }; + 5328864716B881710041A07C /* AudioData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AudioData.cpp; sourceTree = ""; }; + 5328864816B881710041A07C /* AudioData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AudioData.h; sourceTree = ""; }; 532C792A16AF298900B1A969 /* CVBlob.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CVBlob.framework; path = Frameworks/CVBlob.framework; sourceTree = ""; }; 532C7AC316AF298D00B1A969 /* grayson-particle.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "grayson-particle.png"; sourceTree = ""; }; 532C7AC416AF298D00B1A969 /* int-texture256-v2.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "int-texture256-v2.png"; sourceTree = ""; }; @@ -633,6 +639,10 @@ 5325C24F16AF4DBE0051A40B /* world.h */, 539853CC16B765EE00B2D585 /* UDPSocket.cpp */, 539853CD16B765EE00B2D585 /* UDPSocket.h */, + 5328864416B87E040041A07C /* AudioSource.cpp */, + 5328864516B87E040041A07C /* AudioSource.h */, + 5328864716B881710041A07C /* AudioData.cpp */, + 5328864816B881710041A07C /* AudioData.h */, ); path = Source; sourceTree = ""; @@ -1374,6 +1384,8 @@ 5325C26116AF4DBE0051A40B /* util.cpp in Sources */, 5325C26416AF4E2C0051A40B /* audio.cpp in Sources */, 539853CE16B765EE00B2D585 /* UDPSocket.cpp in Sources */, + 5328864616B87E040041A07C /* AudioSource.cpp in Sources */, + 5328864916B881710041A07C /* AudioData.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; };