From 5652d0dcd398ce565362a0a166fa0e8e69af403c Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 8 Mar 2013 17:18:28 -0800 Subject: [PATCH] add a flange effect when turning head with gyros --- interface/src/Audio.cpp | 57 ++++++++++++++++++++++++++++++++++------- interface/src/Head.cpp | 6 ++--- interface/src/Head.h | 3 ++- voxel/src/main.cpp | 2 +- 4 files changed, 54 insertions(+), 14 deletions(-) diff --git a/interface/src/Audio.cpp b/interface/src/Audio.cpp index 15d6240ee8..7db5a87ee5 100644 --- a/interface/src/Audio.cpp +++ b/interface/src/Audio.cpp @@ -36,20 +36,18 @@ const int SAMPLE_RATE = 22050; const float JITTER_BUFFER_LENGTH_MSECS = 30.0; const short JITTER_BUFFER_SAMPLES = JITTER_BUFFER_LENGTH_MSECS * (SAMPLE_RATE / 1000.0); -const short NUM_AUDIO_SOURCES = 2; -const short ECHO_SERVER_TEST = 1; +const int FLANGE_EFFECT_THRESHOLD = 200; +const float FLANGE_RATE = 4; +const float FLANGE_SAMPLE_WEIGHT = 0.50; const int AGENT_LOOPBACK_MODIFIER = 307; -const char LOCALHOST_MIXER[] = "0.0.0.0"; -const char WORKCLUB_MIXER[] = "192.168.1.19"; -const char EC2_WEST_MIXER[] = "54.241.92.53"; - const int AUDIO_UDP_LISTEN_PORT = 55444; int starve_counter = 0; StDev stdev; bool stopAudioReceiveThread = false; +int samplesLeftForFlange = 0; #define LOG_SAMPLE_DELAY 1 @@ -177,8 +175,49 @@ int audioCallback (const void *inputBuffer, ringBuffer->setStarted(true); // play whatever we have in the audio buffer - memcpy(outputLeft, ringBuffer->getNextOutput(), PACKET_LENGTH_BYTES_PER_CHANNEL); - memcpy(outputRight, ringBuffer->getNextOutput() + PACKET_LENGTH_SAMPLES_PER_CHANNEL, PACKET_LENGTH_BYTES_PER_CHANNEL); + // if we haven't fired off the flange effect, check if we should + if (!samplesLeftForFlange && fabsf(data->linkedHead->getLastMeasuredYaw()) > FLANGE_EFFECT_THRESHOLD) { + // we should flange for one second + samplesLeftForFlange = SAMPLE_RATE; + } + + for (int s = 0; s < PACKET_LENGTH_SAMPLES_PER_CHANNEL; s++) { + + int leftSample = ringBuffer->getNextOutput()[s]; + int rightSample = ringBuffer->getNextOutput()[s + PACKET_LENGTH_SAMPLES_PER_CHANNEL]; + + if (samplesLeftForFlange > 0) { + float exponent = (SAMPLE_RATE - samplesLeftForFlange - (SAMPLE_RATE / FLANGE_RATE)) / (SAMPLE_RATE / FLANGE_RATE); + int sampleFlangeDelay = (SAMPLE_RATE / 1000.0) * powf(2, exponent); + + if (samplesLeftForFlange != SAMPLE_RATE || s >= (SAMPLE_RATE / 2000)) { + // we have a delayed sample to add to this sample + + int16_t *flangeFrame = ringBuffer->getNextOutput(); + int flangeIndex = s - sampleFlangeDelay; + + if (flangeIndex < 0) { + // we need to grab the flange sample from earlier in the buffer + flangeFrame = ringBuffer->getNextOutput() != ringBuffer->getBuffer() + ? ringBuffer->getNextOutput() - PACKET_LENGTH_SAMPLES + : ringBuffer->getNextOutput() + RING_BUFFER_SAMPLES - PACKET_LENGTH_SAMPLES; + + flangeIndex = PACKET_LENGTH_SAMPLES_PER_CHANNEL + (s - sampleFlangeDelay); + } + + int16_t leftFlangeSample = flangeFrame[flangeIndex]; + int16_t rightFlangeSample = flangeFrame[flangeIndex + PACKET_LENGTH_SAMPLES_PER_CHANNEL]; + + leftSample = (1 - FLANGE_SAMPLE_WEIGHT) * leftSample + (FLANGE_SAMPLE_WEIGHT * leftFlangeSample); + rightSample = (1 - FLANGE_SAMPLE_WEIGHT) * rightSample + (FLANGE_SAMPLE_WEIGHT * rightFlangeSample); + + samplesLeftForFlange--; + } + } + + outputLeft[s] = leftSample; + outputRight[s] = rightSample; + } ringBuffer->setNextOutput(ringBuffer->getNextOutput() + PACKET_LENGTH_SAMPLES); @@ -336,7 +375,7 @@ void Audio::getInputLoudness(float * lastLoudness, float * averageLoudness) { void Audio::render(int screenWidth, int screenHeight) { - if (initialized && ECHO_SERVER_TEST) { + if (initialized) { glBegin(GL_LINES); glColor3f(1,1,1); diff --git a/interface/src/Head.cpp b/interface/src/Head.cpp index 1e5b3c4203..d3caf98f95 100644 --- a/interface/src/Head.cpp +++ b/interface/src/Head.cpp @@ -87,7 +87,7 @@ void Head::UpdatePos(float frametime, SerialInterface * serialInterface, int hea const float PITCH_ACCEL_COUPLING = 0.5; const float ROLL_ACCEL_COUPLING = -1.0; float measured_pitch_rate = serialInterface->getRelativeValue(PITCH_RATE); - float measured_yaw_rate = serialInterface->getRelativeValue(YAW_RATE); + yawRate = serialInterface->getRelativeValue(YAW_RATE); float measured_lateral_accel = serialInterface->getRelativeValue(ACCEL_X) - ROLL_ACCEL_COUPLING*serialInterface->getRelativeValue(ROLL_RATE); float measured_fwd_accel = serialInterface->getRelativeValue(ACCEL_Z) - @@ -115,11 +115,11 @@ void Head::UpdatePos(float frametime, SerialInterface * serialInterface, int hea if (head_mirror) { if ((Yaw < MAX_YAW) && (Yaw > MIN_YAW)) - addYaw(-measured_yaw_rate * HEAD_ROTATION_SCALE * frametime); + addYaw(-yawRate * HEAD_ROTATION_SCALE * frametime); addLean(-measured_lateral_accel * frametime * HEAD_LEAN_SCALE, -measured_fwd_accel*frametime * HEAD_LEAN_SCALE); } else { if ((Yaw < MAX_YAW) && (Yaw > MIN_YAW)) - addYaw(measured_yaw_rate * -HEAD_ROTATION_SCALE * frametime); + addYaw(yawRate * -HEAD_ROTATION_SCALE * frametime); addLean(measured_lateral_accel * frametime * -HEAD_LEAN_SCALE, measured_fwd_accel*frametime * HEAD_LEAN_SCALE); } } diff --git a/interface/src/Head.h b/interface/src/Head.h index a6aaec725c..2b1863b2bd 100644 --- a/interface/src/Head.h +++ b/interface/src/Head.h @@ -58,6 +58,7 @@ class Head : public AgentData { float getAverageLoudness() {return averageLoudness;}; void setAverageLoudness(float al) {averageLoudness = al;}; void setLoudness(float l) {loudness = l;}; + float getLastMeasuredYaw() {return yawRate;}; void SetNewHeadTarget(float, float); glm::vec3 getPos() { return position; }; @@ -71,7 +72,7 @@ class Head : public AgentData { float Yaw; float Roll; float PitchRate; - float YawRate; + float yawRate; float RollRate; float EyeballPitch[2]; float EyeballYaw[2]; diff --git a/voxel/src/main.cpp b/voxel/src/main.cpp index 689395ac5b..0a8fdf5d19 100644 --- a/voxel/src/main.cpp +++ b/voxel/src/main.cpp @@ -32,7 +32,7 @@ const float DEATH_STAR_RADIUS = 4.0; const float MAX_CUBE = 0.05; char DOMAIN_HOSTNAME[] = "highfidelity.below92.com"; -char DOMAIN_IP[100] = "192.168.1.47"; // IP Address will be re-set by lookup on startup +char DOMAIN_IP[100] = ""; // IP Address will be re-set by lookup on startup const int DOMAINSERVER_PORT = 40102; AgentList agentList(VOXEL_LISTEN_PORT);