First commit, audio echo detection, also changed scope to show last buffer played rather than next buffer to play.

This commit is contained in:
Philip Rosedale 2013-05-15 13:03:22 -07:00
parent 84d18296d2
commit f6389cac38
3 changed files with 51 additions and 10 deletions

View file

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

View file

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

View file

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