Merge pull request #2640 from birarda/kill-scope

remove the audio scope
This commit is contained in:
Philip Rosedale 2014-04-09 22:11:02 -07:00
commit 3b2b075414
8 changed files with 3 additions and 311 deletions

View file

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

View file

@ -407,7 +407,6 @@ private:
ViewFrustum _shadowViewFrustum;
quint64 _lastQueriedTime;
Oscilloscope _audioScope;
float _trailingAudioLoudness;
OctreeQuery _octreeQuery; // NodeData derived class for querying voxels from voxel server

View file

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

View file

@ -34,9 +34,6 @@
#include <AudioRingBuffer.h>
#include <StdDev.h>
#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;

View file

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

View file

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

View file

@ -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 <limits>
#include <cstring>
#include <algorithm>
#include <stdint.h>
#include <QtCore/QDebug>
#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<short>::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();
}

View file

@ -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 <cassert>
#include <QtCore/QObject>
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