first pass audio VU scope

This commit is contained in:
Philip Rosedale 2014-03-28 23:09:51 -07:00
parent 78ee8706d6
commit 27f0214032
3 changed files with 78 additions and 31 deletions

View file

@ -151,6 +151,7 @@ Application::Application(int& argc, char** argv, timeval &startup_time) :
_lastQueriedViewFrustum(),
_lastQueriedTime(usecTimestampNow()),
_audioScope(256, 200, true),
_trailingAudioLoudness(0.f),
_mirrorViewRect(QRect(MIRROR_VIEW_LEFT_PADDING, MIRROR_VIEW_TOP_PADDING, MIRROR_VIEW_WIDTH, MIRROR_VIEW_HEIGHT)),
_mouseX(0),
_mouseY(0),
@ -2504,56 +2505,101 @@ void Application::displayOverlay() {
}
}
// Audio Scope
const int AUDIO_SCOPE_Y_OFFSET = 135;
if (Menu::getInstance()->isOptionChecked(MenuOption::Stats)) {
_audio.renderMuteIcon(1, _glWidget->height() - 50);
if (Menu::getInstance()->isOptionChecked(MenuOption::Oscilloscope)) {
int oscilloscopeTop = _glWidget->height() - 135;
_audioScope.render(25, oscilloscopeTop);
int oscilloscopeTop = _glWidget->height() - AUDIO_SCOPE_Y_OFFSET;
_audioScope.render(MIRROR_VIEW_LEFT_PADDING, oscilloscopeTop);
}
}
const int AUDIO_METER_WIDTH = 200;
// Audio VU Meter and Mute Icon
const int MUTE_ICON_SIZE = 24;
const int AUDIO_METER_INSET = 2;
const int AUDIO_METER_WIDTH = MIRROR_VIEW_WIDTH - MUTE_ICON_SIZE - AUDIO_METER_INSET;
const int AUDIO_METER_SCALE_WIDTH = AUDIO_METER_WIDTH - 2 * AUDIO_METER_INSET;
const int AUDIO_METER_HEIGHT = 8;
const int AUDIO_METER_Y = _glWidget->height() - 40;
const int AUDIO_METER_X = 25;
const int AUDIO_METER_Y_GAP = 8;
const int AUDIO_METER_X = MIRROR_VIEW_LEFT_PADDING + MUTE_ICON_SIZE + AUDIO_METER_INSET;
int audioMeterY;
if (Menu::getInstance()->isOptionChecked(MenuOption::Mirror)) {
audioMeterY = MIRROR_VIEW_HEIGHT + AUDIO_METER_Y_GAP;
} else {
audioMeterY = AUDIO_METER_Y_GAP;
}
_audio.renderMuteIcon(MIRROR_VIEW_LEFT_PADDING, audioMeterY);
const float AUDIO_METER_BLUE[] = {0.0, 0.0, 1.0};
const float AUDIO_METER_GREEN[] = {0.0, 1.0, 0.0};
const float AUDIO_METER_RED[] = {1.0, 0.0, 0.0};
const float AUDIO_GREEN_START = 0.25 * AUDIO_METER_SCALE_WIDTH;
const float AUDIO_RED_START = 0.80 * AUDIO_METER_SCALE_WIDTH;
const float CLIPPING_INDICATOR_TIME = 1.0f;
const float AUDIO_METER_AVERAGING = 0.5;
const float LOG2 = log(2.f);
const float MAX_LOG2_SAMPLE = 15.f;
float audioLevel = 0.f;
float loudness = _audio.getLastInputLoudness() + 1.f;
float log2loudness = log(loudness) / LOG2;
if (loudness < 2048) {
audioLevel = (log2loudness / 11.f) * (AUDIO_METER_SCALE_WIDTH / 5.f);
} else {
audioLevel = (log2loudness - 10.f) * (AUDIO_METER_SCALE_WIDTH / 5.f);
}
_trailingAudioLoudness = AUDIO_METER_AVERAGING * _trailingAudioLoudness + (1.f - AUDIO_METER_AVERAGING) * loudness;
float log2loudness = log(_trailingAudioLoudness) / LOG2;
audioLevel = log2loudness / MAX_LOG2_SAMPLE * AUDIO_METER_SCALE_WIDTH;
bool isClipping = ((_audio.getTimeSinceLastClip() > 0.f) && (_audio.getTimeSinceLastClip() < CLIPPING_INDICATOR_TIME));
glBegin(GL_QUADS);
if (isClipping) {
glColor3f(1, 0, 0);
} else {
glColor3f(0, 0, 0);
}
glBegin(GL_QUADS);
// Draw background Quad
glVertex2i(AUDIO_METER_X, AUDIO_METER_Y);
glVertex2i(AUDIO_METER_X + AUDIO_METER_WIDTH, AUDIO_METER_Y);
glVertex2i(AUDIO_METER_X + AUDIO_METER_WIDTH, AUDIO_METER_Y + AUDIO_METER_HEIGHT);
glVertex2i(AUDIO_METER_X, AUDIO_METER_Y + AUDIO_METER_HEIGHT);
// Draw Meter Quad
if (isClipping) {
glColor3f(1, 1, 1);
} else {
glColor3f(0, 1, 1);
// Draw audio meter background Quad
glVertex2i(AUDIO_METER_X, audioMeterY);
glVertex2i(AUDIO_METER_X + AUDIO_METER_WIDTH, audioMeterY);
glVertex2i(AUDIO_METER_X + AUDIO_METER_WIDTH, audioMeterY + AUDIO_METER_HEIGHT);
glVertex2i(AUDIO_METER_X, audioMeterY + AUDIO_METER_HEIGHT);
if (audioLevel > AUDIO_RED_START) {
if (!isClipping) {
glColor3fv(AUDIO_METER_RED);
} else {
glColor3f(1, 1, 1);
}
// Draw Red Quad
glVertex2i(AUDIO_METER_X + AUDIO_METER_INSET + AUDIO_RED_START, audioMeterY + AUDIO_METER_INSET);
glVertex2i(AUDIO_METER_X + AUDIO_METER_INSET + audioLevel, audioMeterY + AUDIO_METER_INSET);
glVertex2i(AUDIO_METER_X + AUDIO_METER_INSET + audioLevel, audioMeterY + AUDIO_METER_HEIGHT - AUDIO_METER_INSET);
glVertex2i(AUDIO_METER_X + AUDIO_METER_INSET + AUDIO_RED_START, audioMeterY + AUDIO_METER_HEIGHT - AUDIO_METER_INSET);
audioLevel = AUDIO_RED_START;
}
// Draw Meter quad
glVertex2i(AUDIO_METER_X + AUDIO_METER_INSET, AUDIO_METER_Y + AUDIO_METER_INSET);
glVertex2i(AUDIO_METER_X + AUDIO_METER_INSET + audioLevel, AUDIO_METER_Y + AUDIO_METER_INSET);
glVertex2i(AUDIO_METER_X + AUDIO_METER_INSET + audioLevel, AUDIO_METER_Y + AUDIO_METER_HEIGHT - AUDIO_METER_INSET);
glVertex2i(AUDIO_METER_X + AUDIO_METER_INSET, AUDIO_METER_Y + AUDIO_METER_HEIGHT - AUDIO_METER_INSET);
if (audioLevel > AUDIO_GREEN_START) {
if (!isClipping) {
glColor3fv(AUDIO_METER_GREEN);
} else {
glColor3f(1, 1, 1);
}
// Draw Green Quad
glVertex2i(AUDIO_METER_X + AUDIO_METER_INSET + AUDIO_GREEN_START, audioMeterY + AUDIO_METER_INSET);
glVertex2i(AUDIO_METER_X + AUDIO_METER_INSET + audioLevel, audioMeterY + AUDIO_METER_INSET);
glVertex2i(AUDIO_METER_X + AUDIO_METER_INSET + audioLevel, audioMeterY + AUDIO_METER_HEIGHT - AUDIO_METER_INSET);
glVertex2i(AUDIO_METER_X + AUDIO_METER_INSET + AUDIO_GREEN_START, audioMeterY + AUDIO_METER_HEIGHT - AUDIO_METER_INSET);
audioLevel = AUDIO_GREEN_START;
}
// Draw Blue Quad
if (!isClipping) {
glColor3fv(AUDIO_METER_BLUE);
} else {
glColor3f(1, 1, 1);
}
// Draw Blue (low level) quad
glVertex2i(AUDIO_METER_X + AUDIO_METER_INSET, audioMeterY + AUDIO_METER_INSET);
glVertex2i(AUDIO_METER_X + AUDIO_METER_INSET + audioLevel, audioMeterY + AUDIO_METER_INSET);
glVertex2i(AUDIO_METER_X + AUDIO_METER_INSET + audioLevel, audioMeterY + AUDIO_METER_HEIGHT - AUDIO_METER_INSET);
glVertex2i(AUDIO_METER_X + AUDIO_METER_INSET, audioMeterY + AUDIO_METER_HEIGHT - AUDIO_METER_INSET);
glEnd();
if (Menu::getInstance()->isOptionChecked(MenuOption::HeadMouse)) {

View file

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

View file

@ -241,7 +241,7 @@ 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, true);
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()));