diff --git a/interface/src/Audio.cpp b/interface/src/Audio.cpp index 8a455ec419..20d39f6f00 100644 --- a/interface/src/Audio.cpp +++ b/interface/src/Audio.cpp @@ -105,10 +105,19 @@ int audioCallback (const void *inputBuffer, AudioData *data = (AudioData *) userData; int16_t *inputLeft = ((int16_t **) inputBuffer)[0]; + int16_t *outputLeft = ((int16_t **) outputBuffer)[0]; + int16_t *outputRight = ((int16_t **) outputBuffer)[1]; + + // Compare the input and output streams to look for correlation + data->analyzeEcho(inputLeft, outputLeft, BUFFER_LENGTH_SAMPLES); // Add Procedural effects to input samples data->addProceduralSounds(inputLeft, BUFFER_LENGTH_SAMPLES); + // add data to the scope + scope->addSamples(1, outputLeft, PACKET_LENGTH_SAMPLES_PER_CHANNEL); + scope->addSamples(2, outputRight, PACKET_LENGTH_SAMPLES_PER_CHANNEL); + if (inputLeft != NULL) { // Measure the loudness of the signal from the microphone and store in audio object @@ -169,10 +178,7 @@ int audioCallback (const void *inputBuffer, data->audioSocket->send((sockaddr *)&audioMixerSocket, dataPacket, BUFFER_LENGTH_BYTES + leadingBytes); } } - - int16_t *outputLeft = ((int16_t **) outputBuffer)[0]; - int16_t *outputRight = ((int16_t **) outputBuffer)[1]; - + memset(outputLeft, 0, PACKET_LENGTH_BYTES_PER_CHANNEL); memset(outputRight, 0, PACKET_LENGTH_BYTES_PER_CHANNEL); @@ -265,11 +271,7 @@ int audioCallback (const void *inputBuffer, outputLeft[s] = leftSample; outputRight[s] = rightSample; } - - // add data to the scope - scope->addSamples(1, outputLeft, PACKET_LENGTH_SAMPLES_PER_CHANNEL); - scope->addSamples(2, outputRight, PACKET_LENGTH_SAMPLES_PER_CHANNEL); - + ringBuffer->setNextOutput(ringBuffer->getNextOutput() + PACKET_LENGTH_SAMPLES); if (ringBuffer->getNextOutput() == ringBuffer->getBuffer() + RING_BUFFER_SAMPLES) { @@ -278,6 +280,13 @@ int audioCallback (const void *inputBuffer, } } + if (randFloat() < 0.01) { + printLog("Ping!\n"); + for (int i = 0; i < BUFFER_LENGTH_SAMPLES; i++) { + outputLeft[i] = (int16_t) (cosf((float)i / 8.f * 2000.f)); + } + } + gettimeofday(&data->lastCallback, NULL); return paContinue; } diff --git a/interface/src/AudioData.cpp b/interface/src/AudioData.cpp index 83b53b0ea3..faa0a27a83 100644 --- a/interface/src/AudioData.cpp +++ b/interface/src/AudioData.cpp @@ -44,5 +44,36 @@ void AudioData::addProceduralSounds(int16_t* inputBuffer, int numSamples) { return; } +void AudioData::analyzeEcho(int16_t* inputBuffer, int16_t* outputBuffer, int numSamples) { + // Compare output and input streams, looking for evidence of correlation needing echo cancellation + // + // OFFSET_RANGE tells us how many samples to vary the analysis window when looking for correlation, + // and should be equal to the largest physical distance between speaker and microphone, where + // OFFSET_RANGE = 1 / (speedOfSound (meters / sec) / SamplingRate (samples / sec)) * distance + // + const int OFFSET_RANGE = 10; + const int SIGNAL_FLOOR = 1000; + float correlation[2 * OFFSET_RANGE + 1]; + int numChecked = 0; + bool foundSignal = false; + for (int offset = -OFFSET_RANGE; offset <= OFFSET_RANGE; offset++) { + for (int i = 0; i < numSamples; i++) { + if ((i + offset >= 0) && (i + offset < numSamples)) { + correlation[offset + OFFSET_RANGE] += + (float) abs(inputBuffer[i] - outputBuffer[i + offset]); + numChecked++; + foundSignal |= (inputBuffer[i] > SIGNAL_FLOOR); + } + } + correlation[offset + OFFSET_RANGE] /= numChecked; + numChecked = 0; + if (foundSignal) { + printLog("%4.2f, ", correlation[offset + OFFSET_RANGE]); + } + } + if (foundSignal) printLog("\n"); +} + + #endif diff --git a/interface/src/AudioData.h b/interface/src/AudioData.h index 80de3df6dc..a98c40b38a 100644 --- a/interface/src/AudioData.h +++ b/interface/src/AudioData.h @@ -43,8 +43,9 @@ class AudioData { void setLastVelocity(glm::vec3 v) { _lastVelocity = v; }; void setLastAcceleration(glm::vec3 a) { _lastAcceleration = a; }; void addProceduralSounds(int16_t* inputBuffer, int numSamples); + void analyzeEcho(int16_t* inputBuffer, int16_t* outputBuffer, int numSamples); - private: + private: glm::vec3 _lastVelocity; glm::vec3 _lastAcceleration;