From 1265e5b12d20f58b35cee087c1ba632e5a391c8c Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Thu, 3 Apr 2014 09:23:10 -0700 Subject: [PATCH 1/2] just echo --- interface/src/AudioReflector.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/interface/src/AudioReflector.cpp b/interface/src/AudioReflector.cpp index e7d5c29e25..402b111c26 100644 --- a/interface/src/AudioReflector.cpp +++ b/interface/src/AudioReflector.cpp @@ -193,30 +193,29 @@ void AudioReflector::calculateReflections(const glm::vec3& origin, const glm::ve void AudioReflector::processSpatialAudio(unsigned int sampleTime, const QByteArray& samples, const QAudioFormat& format) { - //qDebug() << "AudioReflector::processSpatialAudio()...sampleTime=" << sampleTime << " threadID=" << QThread::currentThreadId(); + qDebug() << "AudioReflector::processSpatialAudio()...sampleTime=" << sampleTime << " threadID=" << QThread::currentThreadId(); - /* int totalNumberOfSamples = samples.size() / (sizeof(int16_t)); - int numFrameSamples = format.sampleRate() * format.channelCount(); qDebug() << " totalNumberOfSamples=" << totalNumberOfSamples; - qDebug() << " numFrameSamples=" << numFrameSamples; qDebug() << " samples.size()=" << samples.size(); qDebug() << " sizeof(int16_t)=" << sizeof(int16_t); AudioRingBuffer samplesRingBuffer(totalNumberOfSamples); qint64 bytesCopied = samplesRingBuffer.writeData(samples.constData(),samples.size()); + + /* for(int i = 0; i < totalNumberOfSamples; i++) { samplesRingBuffer[i] = samplesRingBuffer[i] * 0.25f; } + */ qDebug() << " bytesCopied=" << bytesCopied; _audio->addSpatialAudioToBuffer(sampleTime + 12000, samplesRingBuffer); return; - */ quint64 start = usecTimestampNow(); From 06adaa009cc6c679a3df5d513a71f8b8b30c75f8 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Thu, 3 Apr 2014 12:40:35 -0700 Subject: [PATCH 2/2] add first cut at simple low pass filter --- interface/src/Audio.cpp | 43 ++++++++++++++++++++++++++++++++++++++++- interface/src/Audio.h | 2 +- interface/src/Menu.cpp | 3 +++ interface/src/Menu.h | 1 + 4 files changed, 47 insertions(+), 2 deletions(-) diff --git a/interface/src/Audio.cpp b/interface/src/Audio.cpp index 374976c691..62eaacc7c8 100644 --- a/interface/src/Audio.cpp +++ b/interface/src/Audio.cpp @@ -468,7 +468,8 @@ void Audio::handleAudioInput() { } // Add tone injection if enabled - const float TONE_FREQ = 220.f / SAMPLE_RATE * TWO_PI; + //const float TONE_FREQ = 220.f / SAMPLE_RATE * TWO_PI; + const float TONE_FREQ = 440.f / SAMPLE_RATE * TWO_PI; const float QUARTER_VOLUME = 8192.f; if (_toneInjectionEnabled) { loudness = 0.f; @@ -760,11 +761,20 @@ void Audio::processReceivedAudio(unsigned int sampleTime, AudioRingBuffer& ringB // copy the samples we'll resample from the ring buffer - this also // pushes the read pointer of the ring buffer forwards ringBuffer.readSamples(ringBufferSamples, numNetworkOutputSamples); + + } // add the next numNetworkOutputSamples from each QByteArray // in our _localInjectionByteArrays QVector to the localInjectedSamples + + if (Menu::getInstance()->isOptionChecked(MenuOption::LowPassFilter)) { + int channels = _desiredOutputFormat.channelCount(); + int filterSamples = numNetworkOutputSamples / channels; + lowPassFilter(ringBufferSamples, filterSamples, channels); + } + // copy the packet from the RB to the output linearResampling(ringBufferSamples, (int16_t*) outputBuffer.data(), @@ -894,6 +904,37 @@ void Audio::addProceduralSounds(int16_t* monoInput, int numSamples) { } } + +// simple 3 pole low pass filter +void Audio::lowPassFilter(int16_t* inputBuffer, int samples, int channels) { + + //qDebug() << "lowPassFilter() samples=" << samples << " channels=" << channels; + //const int POLE_COUNT = 3; + + for (int c = 0; c < channels; c++) { + const float C1 = 0.0f; // 0.25f; + const float C2 = 1.0f; // 0.5f; + const float C3 = 0.0f; // 0.25f; + int16_t S1,S2,S3; + S1 = inputBuffer[c]; // start with the Nth sample, based on the current channel, this is the fist sample for the channel + for (int i = 0; i < samples; i++) { + int sampleAt = (i * channels) + c; + int nextSampleAt = sampleAt + channels; + S2 = inputBuffer[sampleAt]; + if (i == samples - 1) { + S3 = inputBuffer[sampleAt]; + } else { + S3 = inputBuffer[nextSampleAt]; + } + // save our S1 for next time before we mod this + S1 = inputBuffer[sampleAt]; + inputBuffer[sampleAt] = (C1 * S1) + (C2 * S2) + (C3 * S3); + //qDebug() << "channel=" << c << " sampleAt=" << sampleAt; + } + } +} + + // Starts a collision sound. magnitude is 0-1, with 1 the loudest possible sound. void Audio::startCollisionSound(float magnitude, float frequency, float noise, float duration, bool flashScreen) { _collisionSoundMagnitude = magnitude; diff --git a/interface/src/Audio.h b/interface/src/Audio.h index 052eb06bdd..fe3a6cbb7c 100644 --- a/interface/src/Audio.h +++ b/interface/src/Audio.h @@ -55,7 +55,7 @@ public: void setJitterBufferSamples(int samples) { _jitterBufferSamples = samples; } int getJitterBufferSamples() { return _jitterBufferSamples; } - void lowPassFilter(int16_t* inputBuffer); + void lowPassFilter(int16_t* inputBuffer, int samples, int channels); virtual void startCollisionSound(float magnitude, float frequency, float noise, float duration, bool flashScreen); virtual void startDrumSound(float volume, float frequency, float duration, float decay); diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 3dd4733c64..9bb63b4a34 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -371,6 +371,9 @@ Menu::Menu() : false, appInstance->getAudio(), SLOT(toggleAudioSpatialProcessing())); + addCheckableActionToQMenuAndActionHash(audioDebugMenu, MenuOption::LowPassFilter, + Qt::CTRL | Qt::SHIFT | Qt::Key_F, + false); addActionToQMenuAndActionHash(developerMenu, MenuOption::PasteToVoxel, diff --git a/interface/src/Menu.h b/interface/src/Menu.h index b6feb2e2f5..99df84784a 100644 --- a/interface/src/Menu.h +++ b/interface/src/Menu.h @@ -270,6 +270,7 @@ namespace MenuOption { const QString Login = "Login"; const QString Logout = "Logout"; const QString LookAtVectors = "Look-at Vectors"; + const QString LowPassFilter = "Low Pass Filter"; const QString MetavoxelEditor = "Metavoxel Editor..."; const QString Chat = "Chat..."; const QString Metavoxels = "Metavoxels";