From cf47418d5883b4f54cf92b568ea10b92ccb7aeaf Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 9 Apr 2014 17:16:29 -0700 Subject: [PATCH] remove the audio scope --- interface/src/Application.cpp | 15 +-- interface/src/Application.h | 1 - interface/src/Audio.cpp | 14 +-- interface/src/Audio.h | 6 +- interface/src/Menu.cpp | 1 - interface/src/Menu.h | 1 - interface/src/ui/Oscilloscope.cpp | 192 ------------------------------ interface/src/ui/Oscilloscope.h | 84 ------------- 8 files changed, 3 insertions(+), 311 deletions(-) delete mode 100644 interface/src/ui/Oscilloscope.cpp delete mode 100644 interface/src/ui/Oscilloscope.h diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 6005ae085e..85efdcc2b4 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -150,7 +150,6 @@ Application::Application(int& argc, char** argv, timeval &startup_time) : _viewFrustum(), _lastQueriedViewFrustum(), _lastQueriedTime(usecTimestampNow()), - _audioScope(256, 200, true), _mirrorViewRect(QRect(MIRROR_VIEW_LEFT_PADDING, MIRROR_VIEW_TOP_PADDING, MIRROR_VIEW_WIDTH, MIRROR_VIEW_HEIGHT)), _mouseX(0), _mouseY(0), @@ -161,7 +160,7 @@ Application::Application(int& argc, char** argv, timeval &startup_time) : _touchAvgY(0.0f), _isTouchPressed(false), _mousePressed(false), - _audio(&_audioScope, STARTUP_JITTER_SAMPLES), + _audio(STARTUP_JITTER_SAMPLES), _enableProcessVoxelsThread(true), _voxelProcessor(), _voxelHideShowThread(&_voxels), @@ -744,9 +743,6 @@ void Application::keyPressEvent(QKeyEvent* event) { case Qt::Key_Period: Menu::getInstance()->handleViewFrustumOffsetKeyModifier(event->key()); break; - case Qt::Key_Apostrophe: - _audioScope.inputPaused = !_audioScope.inputPaused; - break; case Qt::Key_L: if (isShifted) { Menu::getInstance()->triggerOption(MenuOption::LodTools); @@ -2509,15 +2505,6 @@ void Application::displayOverlay() { } } - // Audio Scope - const int AUDIO_SCOPE_Y_OFFSET = 135; - if (Menu::getInstance()->isOptionChecked(MenuOption::Stats)) { - if (Menu::getInstance()->isOptionChecked(MenuOption::Oscilloscope)) { - int oscilloscopeTop = _glWidget->height() - AUDIO_SCOPE_Y_OFFSET; - _audioScope.render(MIRROR_VIEW_LEFT_PADDING, oscilloscopeTop); - } - } - // Audio VU Meter and Mute Icon const int MUTE_ICON_SIZE = 24; const int AUDIO_METER_INSET = 2; diff --git a/interface/src/Application.h b/interface/src/Application.h index 61c2a15f95..6238d09ded 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -407,7 +407,6 @@ private: ViewFrustum _shadowViewFrustum; quint64 _lastQueriedTime; - Oscilloscope _audioScope; float _trailingAudioLoudness; OctreeQuery _octreeQuery; // NodeData derived class for querying voxels from voxel server diff --git a/interface/src/Audio.cpp b/interface/src/Audio.cpp index a98d276acc..5dcd54050c 100644 --- a/interface/src/Audio.cpp +++ b/interface/src/Audio.cpp @@ -50,7 +50,7 @@ static const int NUMBER_OF_NOISE_SAMPLE_FRAMES = 300; // Mute icon configration static const int MUTE_ICON_SIZE = 24; -Audio::Audio(Oscilloscope* scope, int16_t initialJitterBufferSamples, QObject* parent) : +Audio::Audio(int16_t initialJitterBufferSamples, QObject* parent) : AbstractAudioInterface(parent), _audioInput(NULL), _desiredInputFormat(), @@ -67,7 +67,6 @@ Audio::Audio(Oscilloscope* scope, int16_t initialJitterBufferSamples, QObject* p _proceduralOutputDevice(NULL), _inputRingBuffer(0), _ringBuffer(NETWORK_BUFFER_LENGTH_BYTES_PER_CHANNEL), - _scope(scope), _averagedLatency(0.0), _measuredJitter(0), _jitterBufferSamples(initialJitterBufferSamples), @@ -555,12 +554,6 @@ void Audio::handleAudioInput() { _lastInputLoudness = 0; } } - - // add input data just written to the scope - QMetaObject::invokeMethod(_scope, "addSamples", Qt::QueuedConnection, - Q_ARG(QByteArray, QByteArray((char*) monoAudioSamples, - NETWORK_BUFFER_LENGTH_BYTES_PER_CHANNEL)), - Q_ARG(bool, false), Q_ARG(bool, true)); } else { // our input loudness is 0, since we're muted _lastInputLoudness = 0; @@ -724,11 +717,6 @@ void Audio::processReceivedAudio(const QByteArray& audioByteArray) { if (_outputDevice) { _outputDevice->write(outputBuffer); - - // add output (@speakers) data just written to the scope - QMetaObject::invokeMethod(_scope, "addSamples", Qt::QueuedConnection, - Q_ARG(QByteArray, QByteArray((char*) ringBufferSamples, numNetworkOutputSamples)), - Q_ARG(bool, true), Q_ARG(bool, false)); } delete[] ringBufferSamples; } diff --git a/interface/src/Audio.h b/interface/src/Audio.h index c529fc2651..bfb3450d72 100644 --- a/interface/src/Audio.h +++ b/interface/src/Audio.h @@ -34,9 +34,6 @@ #include #include -#include "ui/Oscilloscope.h" - - static const int NUM_AUDIO_CHANNELS = 2; class QAudioInput; @@ -47,7 +44,7 @@ class Audio : public AbstractAudioInterface { Q_OBJECT public: // setup for audio I/O - Audio(Oscilloscope* scope, int16_t initialJitterBufferSamples, QObject* parent = 0); + Audio(int16_t initialJitterBufferSamples, QObject* parent = 0); float getLastInputLoudness() const { return glm::max(_lastInputLoudness - _noiseGateMeasuredFloor, 0.f); } float getTimeSinceLastClip() const { return _timeSinceLastClip; } @@ -126,7 +123,6 @@ private: QString _inputAudioDeviceName; QString _outputAudioDeviceName; - Oscilloscope* _scope; StDev _stdev; timeval _lastReceiveTime; float _averagedLatency; diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 70e69597f6..f0aa746d00 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -252,7 +252,6 @@ Menu::Menu() : addDisabledActionAndSeparator(viewMenu, "Stats"); addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::Stats, Qt::Key_Slash); addActionToQMenuAndActionHash(viewMenu, MenuOption::Log, Qt::CTRL | Qt::Key_L, appInstance, SLOT(toggleLogDialog())); - addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::Oscilloscope, 0, false); addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::Bandwidth, 0, true); addActionToQMenuAndActionHash(viewMenu, MenuOption::BandwidthDetails, 0, this, SLOT(bandwidthDetails())); addActionToQMenuAndActionHash(viewMenu, MenuOption::OctreeStats, 0, this, SLOT(octreeStatsDetails())); diff --git a/interface/src/Menu.h b/interface/src/Menu.h index 5bc48f916f..cdefa18273 100644 --- a/interface/src/Menu.h +++ b/interface/src/Menu.h @@ -287,7 +287,6 @@ namespace MenuOption { const QString OctreeStats = "Voxel and Particle Statistics"; const QString OffAxisProjection = "Off-Axis Projection"; const QString OldVoxelCullingMode = "Old Voxel Culling Mode"; - const QString Oscilloscope = "Audio Oscilloscope"; const QString Pair = "Pair"; const QString Particles = "Particles"; const QString PasteToVoxel = "Paste to Voxel..."; diff --git a/interface/src/ui/Oscilloscope.cpp b/interface/src/ui/Oscilloscope.cpp deleted file mode 100644 index af10539c43..0000000000 --- a/interface/src/ui/Oscilloscope.cpp +++ /dev/null @@ -1,192 +0,0 @@ -// -// Oscilloscope.cpp -// interface/src/ui -// -// Created by Philip on 1/28/13. -// Copyright 2013 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -#include -#include -#include - -#include -#include - -#include "InterfaceConfig.h" - -#include "Oscilloscope.h" - -// Reimplemented 4/26/13 (tosh) - don't blame Philip for bugs - -using namespace std; - -namespace { // everything in here only exists while compiling this .cpp file - - // one sample buffer per channel - unsigned const MAX_SAMPLES = Oscilloscope::MAX_SAMPLES_PER_CHANNEL * Oscilloscope::MAX_CHANNELS; - - // adding an x-coordinate yields twice the amount of vertices - unsigned const MAX_COORDS_PER_CHANNEL = Oscilloscope::MAX_SAMPLES_PER_CHANNEL * 2; - // allocated once for each channel - unsigned const MAX_COORDS = MAX_COORDS_PER_CHANNEL * Oscilloscope::MAX_CHANNELS; - - // total amount of memory to allocate (in 16-bit integers) - unsigned const N_INT16_TO_ALLOC = MAX_SAMPLES + MAX_COORDS; -} - - -Oscilloscope::Oscilloscope(int w, int h, bool isEnabled) : - enabled(isEnabled), - inputPaused(false), - _width(w), - _height(h), - _samples(0l), - _vertices(0l), - // some filtering (see details in Log.h) - _lowPassCoeff(0.4f), - // three in -> one out - _downsampleRatio(3) { - - // allocate enough space for the sample data and to turn it into - // vertices and since they're all 'short', do so in one shot - _samples = new short[N_INT16_TO_ALLOC]; - memset(_samples, 0, N_INT16_TO_ALLOC * sizeof(short)); - _vertices = _samples + MAX_SAMPLES; - - // initialize write positions to start of each channel's region - for (unsigned ch = 0; ch < MAX_CHANNELS; ++ch) { - _writePos[ch] = MAX_SAMPLES_PER_CHANNEL * ch; - } - - _colors[0] = 0xffffff; - _colors[1] = 0x00ffff; - _colors[2] = 0x00ffff; -} - -Oscilloscope::~Oscilloscope() { - - delete[] _samples; -} - -void Oscilloscope::addSamples(const QByteArray& audioByteArray, bool isStereo, bool isInput) { - - if (! enabled || inputPaused) { - return; - } - - unsigned numSamplesPerChannel = audioByteArray.size() / (sizeof(int16_t) * (isStereo ? 2 : 1)); - int16_t* samples = (int16_t*) audioByteArray.data(); - - for (int channel = 0; channel < (isStereo ? 2 : 1); channel++) { - // add samples for each of the channels - - // determine start/end offset of this channel's region - unsigned baseOffs = MAX_SAMPLES_PER_CHANNEL * (channel + !isInput); - unsigned endOffs = baseOffs + MAX_SAMPLES_PER_CHANNEL; - - // fetch write position for this channel - unsigned writePos = _writePos[channel + !isInput]; - - // determine write position after adding the samples - unsigned newWritePos = writePos + numSamplesPerChannel; - unsigned n2 = 0; - if (newWritePos >= endOffs) { - // passed boundary of the circular buffer? -> we need to copy two blocks - n2 = newWritePos - endOffs; - newWritePos = baseOffs + n2; - numSamplesPerChannel -= n2; - } - - if (!isStereo) { - // copy data - memcpy(_samples + writePos, samples, numSamplesPerChannel * sizeof(int16_t)); - if (n2 > 0) { - memcpy(_samples + baseOffs, samples + numSamplesPerChannel, n2 * sizeof(int16_t)); - } - } else { - // we have interleaved samples we need to separate into two channels - for (unsigned i = 0; i < numSamplesPerChannel + n2; i++) { - if (i < numSamplesPerChannel - n2) { - _samples[writePos] = samples[(i * 2) + channel]; - } else { - _samples[baseOffs] = samples[(i * 2) + channel]; - } - } - } - - // set new write position for this channel - _writePos[channel + !isInput] = newWritePos; - } -} - -void Oscilloscope::render(int x, int y) { - - if (! enabled) { - return; - } - - // fetch low pass factor (and convert to fix point) / downsample factor - int lowPassFixPt = -(int)(std::numeric_limits::min()) * _lowPassCoeff; - unsigned downsample = _downsampleRatio; - // keep half of the buffer for writing and ensure an even vertex count - unsigned usedWidth = min(_width, MAX_SAMPLES_PER_CHANNEL / (downsample * 2)) & ~1u; - unsigned usedSamples = usedWidth * downsample; - - // expand samples to vertex data - for (unsigned ch = 0; ch < MAX_CHANNELS; ++ch) { - // for each channel: determine memory regions - short const* basePtr = _samples + MAX_SAMPLES_PER_CHANNEL * ch; - short const* endPtr = basePtr + MAX_SAMPLES_PER_CHANNEL; - short const* inPtr = _samples + _writePos[ch]; - short* outPtr = _vertices + MAX_COORDS_PER_CHANNEL * ch; - int sample = 0, x = usedWidth; - for (int i = (int)usedSamples; --i >= 0 ;) { - if (inPtr == basePtr) { - // handle boundary, reading the circular sample buffer - inPtr = endPtr; - } - // read and (eventually) filter sample - sample += ((*--inPtr - sample) * lowPassFixPt) >> 15; - // write every nth as y with a corresponding x-coordinate - if (i % downsample == 0) { - *outPtr++ = short(--x); - *outPtr++ = short(sample); - } - } - } - - // set up rendering state (vertex data lives at _vertices) - glLineWidth(1.0); - glDisable(GL_LINE_SMOOTH); - glPushMatrix(); - glTranslatef((float)x + 0.0f, (float)y + _height / 2.0f, 0.0f); - glScaled(1.0f, _height / 32767.0f, 1.0f); - glVertexPointer(2, GL_SHORT, 0, _vertices); - glEnableClientState(GL_VERTEX_ARRAY); - glDisableClientState(GL_COLOR_ARRAY); - glDisableClientState(GL_INDEX_ARRAY); - glDisableClientState(GL_NORMAL_ARRAY); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - - // render channel 0 - glColor3ub(GLubyte(_colors[0] >> 16), GLubyte((_colors[0] >> 8) & 0xff), GLubyte(_colors[0] & 0xff)); - glDrawArrays(GL_LINES, MAX_SAMPLES_PER_CHANNEL * 0, usedWidth); - - // render channel 1 - glColor3f(0.0f, 1.0f ,1.0f); - glColor3ub(GLubyte(_colors[1] >> 16), GLubyte((_colors[1] >> 8) & 0xff), GLubyte(_colors[1] & 0xff)); - glDrawArrays(GL_LINES, MAX_SAMPLES_PER_CHANNEL * 1, usedWidth); - - // render channel 2 - glColor3ub(GLubyte(_colors[2] >> 16), GLubyte((_colors[2] >> 8) & 0xff), GLubyte(_colors[2] & 0xff)); - glDrawArrays(GL_LINES, MAX_SAMPLES_PER_CHANNEL * 2, usedWidth); - - // reset rendering state - glDisableClientState(GL_VERTEX_ARRAY); - glPopMatrix(); -} - diff --git a/interface/src/ui/Oscilloscope.h b/interface/src/ui/Oscilloscope.h deleted file mode 100644 index 6eff547530..0000000000 --- a/interface/src/ui/Oscilloscope.h +++ /dev/null @@ -1,84 +0,0 @@ -// -// Oscilloscope.h -// interface/src/ui -// -// Created by Philip on 1/28/13. -// Copyright 2013 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -#ifndef hifi_Oscilloscope_h -#define hifi_Oscilloscope_h - -#include - -#include - -class Oscilloscope : public QObject { - Q_OBJECT -public: - Oscilloscope(int width, int height, bool isEnabled); - ~Oscilloscope(); - - void render(int x, int y); - - // Switches: On/Off, Stop Time - volatile bool enabled; - volatile bool inputPaused; - - // Limits - static unsigned const MAX_CHANNELS = 3; - static unsigned const MAX_SAMPLES_PER_CHANNEL = 4096; - - // Sets the color for a specific channel. - void setColor(unsigned ch, unsigned rgb) { assert(ch < MAX_CHANNELS); if (! inputPaused) { _colors[ch] = rgb; } } - - // Controls a simple one pole IIR low pass filter that is provided to - // reduce high frequencies aliasing (to lower ones) when downsampling. - // - // The parameter sets the influence of the input in respect to the - // feed-back signal on the output. - // - // +---------+ - // in O--------------|+ ideal |--o--------------O out - // .---|- op amp | | - // | +---------+ | - // | | - // o-------||-------o - // | | - // | __V__ - // -------------|_____|-------+ - // : : | - // 0.0 - 1.0 (GND) - // - // The values in range 0.0 - 1.0 correspond to "all closed" (input has - // no influence on the output) to "all open" (feedback has no influence - // on the output) configurations. - void setLowpassOpenness(float w) { assert(w >= 0.0f && w <= 1.0f); _lowPassCoeff = w; } - - // Sets the number of input samples per output sample. Without filtering - // just uses every nTh sample. - void setDownsampleRatio(unsigned n) { assert(n > 0); _downsampleRatio = n; } -public slots: - void addSamples(const QByteArray& audioByteArray, bool isStereo, bool isInput); -private: - // don't copy/assign - Oscilloscope(Oscilloscope const&); // = delete; - Oscilloscope& operator=(Oscilloscope const&); // = delete; - - // state variables - - unsigned _width; - unsigned _height; - short* _samples; - short* _vertices; - unsigned _writePos[MAX_CHANNELS]; - - float _lowPassCoeff; - unsigned _downsampleRatio; - unsigned _colors[MAX_CHANNELS]; -}; - -#endif // hifi_Oscilloscope_h