mirror of
https://github.com/overte-org/overte.git
synced 2025-04-20 18:44:01 +02:00
Merge pull request #2138 from PhilipRosedale/master
Travelling noises removed, audio bargraph removed, improve jitter rebuffer behavior
This commit is contained in:
commit
88af57eaeb
7 changed files with 71 additions and 198 deletions
|
@ -2469,6 +2469,8 @@ void Application::computeOffAxisFrustum(float& left, float& right, float& bottom
|
|||
_viewFrustum.computeOffAxisFrustum(left, right, bottom, top, nearVal, farVal, nearClipPlane, farClipPlane);
|
||||
}
|
||||
|
||||
const float WHITE_TEXT[] = { 0.93, 0.93, 0.93 };
|
||||
|
||||
void Application::displayOverlay() {
|
||||
PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), "Application::displayOverlay()");
|
||||
|
||||
|
@ -2491,16 +2493,13 @@ void Application::displayOverlay() {
|
|||
}
|
||||
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::Stats)) {
|
||||
displayStatsBackground(0x33333399, 0, _glWidget->height() - 68, 296, 68);
|
||||
_audio.render(_glWidget->width(), _glWidget->height());
|
||||
_audio.renderMuteIcon(1, _glWidget->height() - 50);
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::Oscilloscope)) {
|
||||
int oscilloscopeTop = Menu::getInstance()->isOptionChecked(MenuOption::Mirror) ? 130 : 25;
|
||||
int oscilloscopeTop = _glWidget->height() - 135;
|
||||
_audioScope.render(25, oscilloscopeTop);
|
||||
}
|
||||
}
|
||||
|
||||
//noiseTest(_glWidget->width(), _glWidget->height());
|
||||
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::HeadMouse)) {
|
||||
_myAvatar->renderHeadMouse();
|
||||
}
|
||||
|
@ -2542,8 +2541,7 @@ void Application::displayOverlay() {
|
|||
(Menu::getInstance()->isOptionChecked(MenuOption::Stats) &&
|
||||
Menu::getInstance()->isOptionChecked(MenuOption::Bandwidth))
|
||||
? 80 : 20;
|
||||
drawtext(_glWidget->width() - 100, _glWidget->height() - timerBottom, 0.30f, 0, 1.0f, 0, frameTimer, 0, 0, 0);
|
||||
drawtext(_glWidget->width() - 102, _glWidget->height() - timerBottom - 2, 0.30f, 0, 1.0f, 0, frameTimer, 1, 1, 1);
|
||||
drawText(_glWidget->width() - 100, _glWidget->height() - timerBottom, 0.30f, 1.0f, 0, frameTimer, WHITE_TEXT);
|
||||
}
|
||||
|
||||
if (_pieMenu.isDisplayed()) {
|
||||
|
@ -2571,6 +2569,7 @@ void Application::displayStatsBackground(unsigned int rgba, int x, int y, int wi
|
|||
}
|
||||
|
||||
// display expanded or contracted stats
|
||||
|
||||
void Application::displayStats() {
|
||||
unsigned int backgroundColor = 0x33333399;
|
||||
int verticalOffset = 0, horizontalOffset = 0, lines = 0;
|
||||
|
@ -2601,22 +2600,22 @@ void Application::displayStats() {
|
|||
sprintf(framesPerSecond, "Framerate: %3.0f FPS", _fps);
|
||||
|
||||
verticalOffset += STATS_PELS_PER_LINE;
|
||||
drawtext(horizontalOffset, verticalOffset, 0.10f, 0, 1.0f, 2, serverNodes, .93f, .93f, .93f);
|
||||
drawText(horizontalOffset, verticalOffset, 0.10f, 0, 2, serverNodes, WHITE_TEXT);
|
||||
verticalOffset += STATS_PELS_PER_LINE;
|
||||
drawtext(horizontalOffset, verticalOffset, 0.10f, 0, 1.0f, 2, avatarNodes, .93f, .93f, .93f);
|
||||
drawText(horizontalOffset, verticalOffset, 0.10f, 0, 2, avatarNodes, WHITE_TEXT);
|
||||
verticalOffset += STATS_PELS_PER_LINE;
|
||||
drawtext(horizontalOffset, verticalOffset, 0.10f, 0, 1.0, 2, framesPerSecond, .93f, .93f, .93f);
|
||||
drawText(horizontalOffset, verticalOffset, 0.10f, 0, 2, framesPerSecond, WHITE_TEXT);
|
||||
|
||||
if (_statsExpanded) {
|
||||
char packetsPerSecond[30];
|
||||
sprintf(packetsPerSecond, "Pkts/sec: %d", _packetsPerSecond);
|
||||
char averageMegabitsPerSecond[30];
|
||||
sprintf(averageMegabitsPerSecond, "Avg Mbps: %3.2f", (float)_bytesPerSecond * 8.f / 1000000.f);
|
||||
sprintf(averageMegabitsPerSecond, "Mbps: %3.2f", (float)_bytesPerSecond * 8.f / 1000000.f);
|
||||
|
||||
verticalOffset += STATS_PELS_PER_LINE;
|
||||
drawtext(horizontalOffset, verticalOffset, 0.10f, 0, 1.0, 2, packetsPerSecond, .93f, .93f, .93f);
|
||||
drawText(horizontalOffset, verticalOffset, 0.10f, 0, 2, packetsPerSecond, WHITE_TEXT);
|
||||
verticalOffset += STATS_PELS_PER_LINE;
|
||||
drawtext(horizontalOffset, verticalOffset, 0.10f, 0, 1.0, 2, averageMegabitsPerSecond, .93f, .93f, .93f);
|
||||
drawText(horizontalOffset, verticalOffset, 0.10f, 0, 2, averageMegabitsPerSecond, WHITE_TEXT);
|
||||
}
|
||||
|
||||
verticalOffset = 0;
|
||||
|
@ -2654,26 +2653,36 @@ void Application::displayStats() {
|
|||
displayStatsBackground(backgroundColor, horizontalOffset, 0, 175, lines * STATS_PELS_PER_LINE + 10);
|
||||
horizontalOffset += 5;
|
||||
|
||||
char audioJitter[30];
|
||||
sprintf(audioJitter,
|
||||
"Buffer msecs %.1f",
|
||||
(float) (_audio.getNetworkBufferLengthSamplesPerChannel() + (float) _audio.getJitterBufferSamples()) /
|
||||
(float)_audio.getNetworkSampleRate() * 1000.f);
|
||||
drawText(30, _glWidget->height() - 22, 0.10f, 0, 2, audioJitter, WHITE_TEXT);
|
||||
|
||||
|
||||
char audioPing[30];
|
||||
sprintf(audioPing, "Audio ping: %d", pingAudio);
|
||||
|
||||
|
||||
char avatarPing[30];
|
||||
sprintf(avatarPing, "Avatar ping: %d", pingAvatar);
|
||||
char voxelAvgPing[30];
|
||||
sprintf(voxelAvgPing, "Voxel avg ping: %d", pingVoxel);
|
||||
|
||||
verticalOffset += STATS_PELS_PER_LINE;
|
||||
drawtext(horizontalOffset, verticalOffset, 0.10f, 0, 1.0, 2, audioPing, .93f, .93f, .93f);
|
||||
drawText(horizontalOffset, verticalOffset, 0.10f, 0, 2, audioPing, WHITE_TEXT);
|
||||
verticalOffset += STATS_PELS_PER_LINE;
|
||||
drawtext(horizontalOffset, verticalOffset, 0.10f, 0, 1.0, 2, avatarPing, .93f, .93f, .93f);
|
||||
drawText(horizontalOffset, verticalOffset, 0.10f, 0, 2, avatarPing, WHITE_TEXT);
|
||||
verticalOffset += STATS_PELS_PER_LINE;
|
||||
drawtext(horizontalOffset, verticalOffset, 0.10f, 0, 1.0, 2, voxelAvgPing, .93f, .93f, .93f);
|
||||
drawText(horizontalOffset, verticalOffset, 0.10f, 0, 2, voxelAvgPing, WHITE_TEXT);
|
||||
|
||||
if (_statsExpanded) {
|
||||
char voxelMaxPing[30];
|
||||
sprintf(voxelMaxPing, "Voxel max ping: %d", pingVoxelMax);
|
||||
|
||||
verticalOffset += STATS_PELS_PER_LINE;
|
||||
drawtext(horizontalOffset, verticalOffset, 0.10f, 0, 1.0, 2, voxelMaxPing, .93f, .93f, .93f);
|
||||
drawText(horizontalOffset, verticalOffset, 0.10f, 0, 2, voxelMaxPing, WHITE_TEXT);
|
||||
}
|
||||
|
||||
verticalOffset = 0;
|
||||
|
@ -2692,20 +2701,20 @@ void Application::displayStats() {
|
|||
sprintf(avatarPosition, "Pos: %.0f,%.0f,%.0f", avatarPos.x, avatarPos.y, avatarPos.z);
|
||||
} else {
|
||||
// longhand way
|
||||
sprintf(avatarPosition, "Position: %.3f, %.3f, %.3f", avatarPos.x, avatarPos.y, avatarPos.z);
|
||||
sprintf(avatarPosition, "Position: %.1f, %.1f, %.1f", avatarPos.x, avatarPos.y, avatarPos.z);
|
||||
}
|
||||
char avatarVelocity[30];
|
||||
sprintf(avatarVelocity, "Velocity: %.1f", glm::length(_myAvatar->getVelocity()));
|
||||
char avatarBodyYaw[30];
|
||||
sprintf(avatarBodyYaw, "Yaw: %.2f", _myAvatar->getBodyYaw());
|
||||
sprintf(avatarBodyYaw, "Yaw: %.1f", _myAvatar->getBodyYaw());
|
||||
char avatarMixerStats[200];
|
||||
|
||||
verticalOffset += STATS_PELS_PER_LINE;
|
||||
drawtext(horizontalOffset, verticalOffset, 0.10f, 0, 1.0, 2, avatarPosition, .93f, .93f, .93f);
|
||||
drawText(horizontalOffset, verticalOffset, 0.10f, 0, 2, avatarPosition, WHITE_TEXT);
|
||||
verticalOffset += STATS_PELS_PER_LINE;
|
||||
drawtext(horizontalOffset, verticalOffset, 0.10f, 0, 1.0, 2, avatarVelocity, .93f, .93f, .93f);
|
||||
drawText(horizontalOffset, verticalOffset, 0.10f, 0, 2, avatarVelocity, WHITE_TEXT);
|
||||
verticalOffset += STATS_PELS_PER_LINE;
|
||||
drawtext(horizontalOffset, verticalOffset, 0.10f, 0, 1.0, 2, avatarBodyYaw, .93f, .93f, .93f);
|
||||
drawText(horizontalOffset, verticalOffset, 0.10f, 0, 2, avatarBodyYaw, WHITE_TEXT);
|
||||
|
||||
if (_statsExpanded) {
|
||||
SharedNodePointer avatarMixer = NodeList::getInstance()->soloNodeOfType(NodeType::AvatarMixer);
|
||||
|
@ -2718,7 +2727,7 @@ void Application::displayStats() {
|
|||
}
|
||||
|
||||
verticalOffset += STATS_PELS_PER_LINE;
|
||||
drawtext(horizontalOffset, verticalOffset, 0.10f, 0, 1.0, 2, avatarMixerStats, .93f, .93f, .93f);
|
||||
drawText(horizontalOffset, verticalOffset, 0.10f, 0, 2, avatarMixerStats, WHITE_TEXT);
|
||||
}
|
||||
|
||||
verticalOffset = 0;
|
||||
|
@ -2733,7 +2742,7 @@ void Application::displayStats() {
|
|||
voxelStats.str("");
|
||||
voxelStats << "Voxels Memory Nodes: " << VoxelTreeElement::getTotalMemoryUsage() / 1000000.f << "MB";
|
||||
verticalOffset += STATS_PELS_PER_LINE;
|
||||
drawtext(horizontalOffset, verticalOffset, 0.10f, 0, 1.0, 2, (char*)voxelStats.str().c_str(), .93f, .93f, .93f);
|
||||
drawText(horizontalOffset, verticalOffset, 0.10f, 0, 2, (char*)voxelStats.str().c_str(), WHITE_TEXT);
|
||||
|
||||
voxelStats.str("");
|
||||
voxelStats <<
|
||||
|
@ -2743,14 +2752,14 @@ void Application::displayStats() {
|
|||
voxelStats << " / GPU: " << _voxels.getVoxelMemoryUsageGPU() / 1000000.f << "MB";
|
||||
}
|
||||
verticalOffset += STATS_PELS_PER_LINE;
|
||||
drawtext(horizontalOffset, verticalOffset, 0.10f, 0, 1.0, 2, (char*)voxelStats.str().c_str(), .93f, .93f, .93f);
|
||||
drawText(horizontalOffset, verticalOffset, 0.10f, 0, 2, (char*)voxelStats.str().c_str(), WHITE_TEXT);
|
||||
|
||||
// Voxel Rendering
|
||||
voxelStats.str("");
|
||||
voxelStats.precision(4);
|
||||
voxelStats << "Voxel Rendering Slots Max: " << _voxels.getMaxVoxels() / 1000.f << "K";
|
||||
verticalOffset += STATS_PELS_PER_LINE;
|
||||
drawtext(horizontalOffset, verticalOffset, 0.10f, 0, 1.0, 2, (char*)voxelStats.str().c_str(), .93f, .93f, .93f);
|
||||
drawText(horizontalOffset, verticalOffset, 0.10f, 0, 2, (char*)voxelStats.str().c_str(), WHITE_TEXT);
|
||||
}
|
||||
|
||||
voxelStats.str("");
|
||||
|
@ -2758,7 +2767,7 @@ void Application::displayStats() {
|
|||
voxelStats << "Drawn: " << _voxels.getVoxelsWritten() / 1000.f << "K " <<
|
||||
"Abandoned: " << _voxels.getAbandonedVoxels() / 1000.f << "K ";
|
||||
verticalOffset += STATS_PELS_PER_LINE;
|
||||
drawtext(horizontalOffset, verticalOffset, 0.10f, 0, 1.0, 2, (char*)voxelStats.str().c_str(), .93f, .93f, .93f);
|
||||
drawText(horizontalOffset, verticalOffset, 0.10f, 0, 2, (char*)voxelStats.str().c_str(), WHITE_TEXT);
|
||||
|
||||
// iterate all the current voxel stats, and list their sending modes, and total voxel counts
|
||||
std::stringstream sendingMode("");
|
||||
|
@ -2802,7 +2811,7 @@ void Application::displayStats() {
|
|||
sendingMode << " <SCENE STABLE>";
|
||||
}
|
||||
verticalOffset += STATS_PELS_PER_LINE;
|
||||
drawtext(horizontalOffset, verticalOffset, 0.10f, 0, 1.0, 2, (char*)sendingMode.str().c_str(), .93f, .93f, .93f);
|
||||
drawText(horizontalOffset, verticalOffset, 0.10f, 0, 2, (char*)sendingMode.str().c_str(), WHITE_TEXT);
|
||||
}
|
||||
|
||||
// Incoming packets
|
||||
|
@ -2814,7 +2823,7 @@ void Application::displayStats() {
|
|||
voxelStats << "Voxel Packets to Process: " << packetsString.toLocal8Bit().constData()
|
||||
<< " [Recent Max: " << maxString.toLocal8Bit().constData() << "]";
|
||||
verticalOffset += STATS_PELS_PER_LINE;
|
||||
drawtext(horizontalOffset, verticalOffset, 0.10f, 0, 1.0, 2, (char*)voxelStats.str().c_str(), .93f, .93f, .93f);
|
||||
drawText(horizontalOffset, verticalOffset, 0.10f, 0, 2, (char*)voxelStats.str().c_str(), WHITE_TEXT);
|
||||
}
|
||||
|
||||
if (_resetRecentMaxPacketsSoon && voxelPacketsToProcess > 0) {
|
||||
|
@ -2837,7 +2846,7 @@ void Application::displayStats() {
|
|||
voxelStats.str("");
|
||||
voxelStats << "Server voxels: " << serversTotalString.toLocal8Bit().constData();
|
||||
verticalOffset += STATS_PELS_PER_LINE;
|
||||
drawtext(horizontalOffset, verticalOffset, 0.10f, 0, 1.0, 2, (char*)voxelStats.str().c_str(), .93f, .93f, .93f);
|
||||
drawText(horizontalOffset, verticalOffset, 0.10f, 0, 2, (char*)voxelStats.str().c_str(), WHITE_TEXT);
|
||||
|
||||
if (_statsExpanded) {
|
||||
QString serversInternalString = locale.toString((uint)totalInternal);
|
||||
|
@ -2848,7 +2857,7 @@ void Application::displayStats() {
|
|||
"Internal: " << serversInternalString.toLocal8Bit().constData() << " " <<
|
||||
"Leaves: " << serversLeavesString.toLocal8Bit().constData() << "";
|
||||
verticalOffset += STATS_PELS_PER_LINE;
|
||||
drawtext(horizontalOffset, verticalOffset, 0.10f, 0, 1.0, 2, (char*)voxelStats.str().c_str(), .93f, .93f, .93f);
|
||||
drawText(horizontalOffset, verticalOffset, 0.10f, 0, 2, (char*)voxelStats.str().c_str(), WHITE_TEXT);
|
||||
}
|
||||
|
||||
unsigned long localTotal = VoxelTreeElement::getNodeCount();
|
||||
|
@ -2858,7 +2867,7 @@ void Application::displayStats() {
|
|||
voxelStats.str("");
|
||||
voxelStats << "Local voxels: " << localTotalString.toLocal8Bit().constData();
|
||||
verticalOffset += STATS_PELS_PER_LINE;
|
||||
drawtext(horizontalOffset, verticalOffset, 0.10f, 0, 1.0, 2, (char*)voxelStats.str().c_str(), .93f, .93f, .93f);
|
||||
drawText(horizontalOffset, verticalOffset, 0.10f, 0, 2, (char*)voxelStats.str().c_str(), WHITE_TEXT);
|
||||
|
||||
if (_statsExpanded) {
|
||||
unsigned long localInternal = VoxelTreeElement::getInternalNodeCount();
|
||||
|
@ -2871,7 +2880,7 @@ void Application::displayStats() {
|
|||
"Internal: " << localInternalString.toLocal8Bit().constData() << " " <<
|
||||
"Leaves: " << localLeavesString.toLocal8Bit().constData() << "";
|
||||
verticalOffset += STATS_PELS_PER_LINE;
|
||||
drawtext(horizontalOffset, verticalOffset, 0.10f, 0, 1.0, 2, (char*)voxelStats.str().c_str(), .93f, .93f, .93f);
|
||||
drawText(horizontalOffset, verticalOffset, 0.10f, 0, 2, (char*)voxelStats.str().c_str(), WHITE_TEXT);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -40,10 +40,7 @@ static const float AUDIO_CALLBACK_MSECS = (float) NETWORK_BUFFER_LENGTH_SAMPLES_
|
|||
static const int NUMBER_OF_NOISE_SAMPLE_FRAMES = 300;
|
||||
|
||||
// Mute icon configration
|
||||
static const int ICON_SIZE = 24;
|
||||
static const int ICON_LEFT = 0;
|
||||
static const int ICON_TOP = 115;
|
||||
static const int ICON_TOP_MIRROR = 220;
|
||||
static const int MUTE_ICON_SIZE = 24;
|
||||
|
||||
Audio::Audio(Oscilloscope* scope, int16_t initialJitterBufferSamples, QObject* parent) :
|
||||
AbstractAudioInterface(parent),
|
||||
|
@ -281,6 +278,7 @@ void Audio::start() {
|
|||
// setup our general output device for audio-mixer audio
|
||||
_audioOutput = new QAudioOutput(outputDeviceInfo, _outputFormat, this);
|
||||
_audioOutput->setBufferSize(_ringBuffer.getSampleCapacity() * sizeof(int16_t));
|
||||
qDebug() << "Ring Buffer capacity in samples: " << _ringBuffer.getSampleCapacity();
|
||||
_outputDevice = _audioOutput->start();
|
||||
|
||||
// setup a loopback audio output device
|
||||
|
@ -563,12 +561,14 @@ void Audio::addReceivedAudioToBuffer(const QByteArray& audioByteArray) {
|
|||
QByteArray outputBuffer;
|
||||
outputBuffer.resize(numDeviceOutputSamples * sizeof(int16_t));
|
||||
|
||||
if (!_ringBuffer.isNotStarvedOrHasMinimumSamples(NETWORK_BUFFER_LENGTH_SAMPLES_STEREO
|
||||
+ (_jitterBufferSamples * 2))) {
|
||||
// starved and we don't have enough to start, keep waiting
|
||||
//qDebug() << "Buffer is starved and doesn't have enough samples to start. Held back.";
|
||||
int numSamplesNeededToStartPlayback = NETWORK_BUFFER_LENGTH_SAMPLES_STEREO + (_jitterBufferSamples * 2);
|
||||
|
||||
if (!_ringBuffer.isNotStarvedOrHasMinimumSamples(numSamplesNeededToStartPlayback)) {
|
||||
// We are still waiting for enough samples to begin playback
|
||||
// qDebug() << numNetworkOutputSamples << " samples so far, waiting for " << numSamplesNeededToStartPlayback;
|
||||
} else {
|
||||
// We are either already playing back, or we have enough audio to start playing back.
|
||||
//qDebug() << "pushing " << numNetworkOutputSamples;
|
||||
_ringBuffer.setIsStarved(false);
|
||||
|
||||
// copy the samples we'll resample from the ring buffer - this also
|
||||
|
@ -621,122 +621,11 @@ void Audio::toggleAudioNoiseReduction() {
|
|||
_noiseGateEnabled = !_noiseGateEnabled;
|
||||
}
|
||||
|
||||
void Audio::render(int screenWidth, int screenHeight) {
|
||||
if (_audioInput && _audioOutput) {
|
||||
glLineWidth(2.0);
|
||||
glBegin(GL_LINES);
|
||||
glColor3f(.93f, .93f, .93f);
|
||||
|
||||
int startX = 20.0;
|
||||
int currentX = startX;
|
||||
int topY = screenHeight - 45;
|
||||
int bottomY = screenHeight - 25;
|
||||
float frameWidth = 23.0;
|
||||
float halfY = topY + ((bottomY - topY) / 2.0);
|
||||
|
||||
// draw the lines for the base of the ring buffer
|
||||
|
||||
glVertex2f(currentX, topY);
|
||||
glVertex2f(currentX, bottomY);
|
||||
|
||||
for (int i = 0; i < RING_BUFFER_LENGTH_FRAMES; i++) {
|
||||
glVertex2f(currentX, halfY);
|
||||
glVertex2f(currentX + frameWidth, halfY);
|
||||
currentX += frameWidth;
|
||||
|
||||
glVertex2f(currentX, topY);
|
||||
glVertex2f(currentX, bottomY);
|
||||
}
|
||||
glEnd();
|
||||
|
||||
// show a bar with the amount of audio remaining in ring buffer and output device
|
||||
// beyond the current playback
|
||||
|
||||
int bytesLeftInAudioOutput = _audioOutput->bufferSize() - _audioOutput->bytesFree();
|
||||
float secondsLeftForAudioOutput = (bytesLeftInAudioOutput / sizeof(int16_t))
|
||||
/ ((float) _outputFormat.sampleRate() * _outputFormat.channelCount());
|
||||
float secondsLeftForRingBuffer = _ringBuffer.samplesAvailable()
|
||||
/ ((float) _desiredOutputFormat.sampleRate() * _desiredOutputFormat.channelCount());
|
||||
float msLeftForAudioOutput = (secondsLeftForAudioOutput + secondsLeftForRingBuffer) * 1000;
|
||||
|
||||
if (_numFramesDisplayStarve == 0) {
|
||||
glColor3f(0, .8f, .4f);
|
||||
} else {
|
||||
glColor3f(0.5 + (_numFramesDisplayStarve / 20.0f), .2f, .4f);
|
||||
_numFramesDisplayStarve--;
|
||||
}
|
||||
|
||||
if (_averagedLatency == 0.0) {
|
||||
_averagedLatency = msLeftForAudioOutput;
|
||||
} else {
|
||||
_averagedLatency = 0.99f * _averagedLatency + 0.01f * (msLeftForAudioOutput);
|
||||
}
|
||||
|
||||
glBegin(GL_QUADS);
|
||||
glVertex2f(startX + 1, topY + 2);
|
||||
glVertex2f(startX + _averagedLatency / AUDIO_CALLBACK_MSECS * frameWidth + 1, topY + 2);
|
||||
glVertex2f(startX + _averagedLatency / AUDIO_CALLBACK_MSECS * frameWidth + 1, bottomY - 2);
|
||||
glVertex2f(startX + 1, bottomY - 2);
|
||||
glEnd();
|
||||
|
||||
// Show a yellow bar with the averaged msecs latency you are hearing (from time of packet receipt)
|
||||
glColor3f(1, .8f, 0);
|
||||
glBegin(GL_QUADS);
|
||||
glVertex2f(startX + _averagedLatency / AUDIO_CALLBACK_MSECS * frameWidth - 1, topY - 2);
|
||||
glVertex2f(startX + _averagedLatency / AUDIO_CALLBACK_MSECS * frameWidth + 3, topY - 2);
|
||||
glVertex2f(startX + _averagedLatency / AUDIO_CALLBACK_MSECS * frameWidth + 3, bottomY + 2);
|
||||
glVertex2f(startX + _averagedLatency / AUDIO_CALLBACK_MSECS * frameWidth - 1, bottomY + 2);
|
||||
glEnd();
|
||||
|
||||
char out[40];
|
||||
sprintf(out, "%3.0f\n", _averagedLatency);
|
||||
drawtext(startX + _averagedLatency / AUDIO_CALLBACK_MSECS * frameWidth - 10, topY - 9, 0.10f, 0, 1, 2, out, 1, .8f, 0);
|
||||
|
||||
// Show a red bar with the 'start' point of one frame plus the jitter buffer
|
||||
|
||||
glColor3f(1, .2f, .4f);
|
||||
int jitterBufferPels = (1.f + (float)getJitterBufferSamples()
|
||||
/ (float) NETWORK_BUFFER_LENGTH_SAMPLES_PER_CHANNEL) * frameWidth;
|
||||
sprintf(out, "%.0f\n", getJitterBufferSamples() / SAMPLE_RATE * 1000.f);
|
||||
drawtext(startX + jitterBufferPels - 5, topY - 9, 0.10f, 0, 1, 2, out, 1, .2f, .4f);
|
||||
sprintf(out, "j %.1f\n", _measuredJitter);
|
||||
if (Menu::getInstance()->getAudioJitterBufferSamples() == 0) {
|
||||
drawtext(startX + jitterBufferPels - 5, bottomY + 12, 0.10f, 0, 1, 2, out, 1, .2f, .4f);
|
||||
} else {
|
||||
drawtext(startX, bottomY + 12, 0.10f, 0, 1, 2, out, 1, .2f, .4f);
|
||||
}
|
||||
|
||||
glBegin(GL_QUADS);
|
||||
glVertex2f(startX + jitterBufferPels - 1, topY - 2);
|
||||
glVertex2f(startX + jitterBufferPels + 3, topY - 2);
|
||||
glVertex2f(startX + jitterBufferPels + 3, bottomY + 2);
|
||||
glVertex2f(startX + jitterBufferPels - 1, bottomY + 2);
|
||||
glEnd();
|
||||
|
||||
}
|
||||
renderToolIcon(screenHeight);
|
||||
}
|
||||
|
||||
// Take a pointer to the acquired microphone input samples and add procedural sounds
|
||||
void Audio::addProceduralSounds(int16_t* monoInput, int numSamples) {
|
||||
const float MAX_AUDIBLE_VELOCITY = 6.0f;
|
||||
const float MIN_AUDIBLE_VELOCITY = 0.1f;
|
||||
const int VOLUME_BASELINE = 400;
|
||||
const float SOUND_PITCH = 8.f;
|
||||
|
||||
float speed = glm::length(_lastVelocity);
|
||||
float volume = VOLUME_BASELINE * (1.f - speed / MAX_AUDIBLE_VELOCITY);
|
||||
|
||||
float sample;
|
||||
|
||||
// Travelling noise
|
||||
// Add a noise-modulated sinewave with volume that tapers off with speed increasing
|
||||
if ((speed > MIN_AUDIBLE_VELOCITY) && (speed < MAX_AUDIBLE_VELOCITY)) {
|
||||
for (int i = 0; i < numSamples; i++) {
|
||||
monoInput[i] += (int16_t)(sinf((float) (_proceduralEffectSample + i) / SOUND_PITCH )
|
||||
* volume * (1.f + randFloat() * 0.25f) * speed);
|
||||
}
|
||||
}
|
||||
const float COLLISION_SOUND_CUTOFF_LEVEL = 0.01f;
|
||||
const float COLLISION_SOUND_MAX_VOLUME = 1000.f;
|
||||
const float UP_MAJOR_FIFTH = powf(1.5f, 4.0f);
|
||||
|
@ -814,11 +703,9 @@ void Audio::handleAudioByteArray(const QByteArray& audioByteArray) {
|
|||
// or send to the mixer and use delayed loopback
|
||||
}
|
||||
|
||||
void Audio::renderToolIcon(int screenHeight) {
|
||||
void Audio::renderMuteIcon(int x, int y) {
|
||||
|
||||
int iconTop = Menu::getInstance()->isOptionChecked(MenuOption::Mirror) ? ICON_TOP_MIRROR : ICON_TOP;
|
||||
|
||||
_iconBounds = QRect(ICON_LEFT, iconTop, ICON_SIZE, ICON_SIZE);
|
||||
_iconBounds = QRect(x, y, MUTE_ICON_SIZE, MUTE_ICON_SIZE);
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, _micTextureId);
|
||||
|
|
|
@ -42,9 +42,7 @@ class Audio : public AbstractAudioInterface {
|
|||
public:
|
||||
// setup for audio I/O
|
||||
Audio(Oscilloscope* scope, int16_t initialJitterBufferSamples, QObject* parent = 0);
|
||||
|
||||
void render(int screenWidth, int screenHeight);
|
||||
|
||||
|
||||
float getLastInputLoudness() const { return glm::max(_lastInputLoudness - _noiseGateMeasuredFloor, 0.f); }
|
||||
float getAudioAverageInputLoudness() const { return _lastInputLoudness; }
|
||||
|
||||
|
@ -70,6 +68,11 @@ public:
|
|||
void init(QGLWidget *parent = 0);
|
||||
bool mousePressEvent(int x, int y);
|
||||
|
||||
void renderMuteIcon(int x, int y);
|
||||
|
||||
int getNetworkSampleRate() { return SAMPLE_RATE; }
|
||||
int getNetworkBufferLengthSamplesPerChannel() { return NETWORK_BUFFER_LENGTH_SAMPLES_PER_CHANNEL; }
|
||||
|
||||
public slots:
|
||||
void start();
|
||||
void addReceivedAudioToBuffer(const QByteArray& audioByteArray);
|
||||
|
@ -148,7 +151,6 @@ private:
|
|||
// Add sounds that we want the user to not hear themselves, by adding on top of mic input signal
|
||||
void addProceduralSounds(int16_t* monoInput, int numSamples);
|
||||
|
||||
void renderToolIcon(int screenHeight);
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -262,8 +262,6 @@ Menu::Menu() :
|
|||
SLOT(setTCPEnabled(bool)));
|
||||
addCheckableActionToQMenuAndActionHash(avatarOptionsMenu, MenuOption::ChatCircling, 0, false);
|
||||
|
||||
addAvatarCollisionSubMenu(avatarOptionsMenu);
|
||||
|
||||
QMenu* handOptionsMenu = developerMenu->addMenu("Hand Options");
|
||||
|
||||
addCheckableActionToQMenuAndActionHash(handOptionsMenu,
|
||||
|
@ -852,6 +850,7 @@ void Menu::editPreferences() {
|
|||
|
||||
_faceshiftEyeDeflection = faceshiftEyeDeflection->value() / (float)faceshiftEyeDeflection->maximum();
|
||||
}
|
||||
QMetaObject::invokeMethod(applicationInstance->getAudio(), "reset", Qt::QueuedConnection);
|
||||
|
||||
sendFakeEnterEvent();
|
||||
}
|
||||
|
|
|
@ -226,29 +226,6 @@ void drawVector(glm::vec3 * vector) {
|
|||
|
||||
}
|
||||
|
||||
// Render a 2D set of squares using perlin/fractal noise
|
||||
void noiseTest(int w, int h) {
|
||||
const float CELLS = 500;
|
||||
const float NOISE_SCALE = 10.0;
|
||||
float xStep = (float) w / CELLS;
|
||||
float yStep = (float) h / CELLS;
|
||||
glBegin(GL_QUADS);
|
||||
for (float x = 0; x < (float)w; x += xStep) {
|
||||
for (float y = 0; y < (float)h; y += yStep) {
|
||||
// Generate a vector varying between 0-1 corresponding to the screen location
|
||||
glm::vec2 position(NOISE_SCALE * x / (float) w, NOISE_SCALE * y / (float) h);
|
||||
// Set the cell color using the noise value at that location
|
||||
float color = glm::perlin(position);
|
||||
glColor4f(color, color, color, 1.0);
|
||||
glVertex2f(x, y);
|
||||
glVertex2f(x + xStep, y);
|
||||
glVertex2f(x + xStep, y + yStep);
|
||||
glVertex2f(x, y + yStep);
|
||||
}
|
||||
}
|
||||
glEnd();
|
||||
}
|
||||
|
||||
void renderWorldBox() {
|
||||
// Show edge of world
|
||||
float red[] = {1, 0, 0};
|
||||
|
@ -337,24 +314,21 @@ float widthChar(float scale, int mono, char ch) {
|
|||
return textRenderer(mono)->computeWidth(ch) * (scale / 0.10);
|
||||
}
|
||||
|
||||
void drawtext(int x, int y, float scale, float rotate, float thick, int mono,
|
||||
char const* string, float r, float g, float b) {
|
||||
void drawText(int x, int y, float scale, float rotate, int mono,
|
||||
char const* string, const float* color) {
|
||||
//
|
||||
// Draws text on screen as stroked so it can be resized
|
||||
//
|
||||
glPushMatrix();
|
||||
glTranslatef(static_cast<float>(x), static_cast<float>(y), 0.0f);
|
||||
glColor3f(r,g,b);
|
||||
glColor3fv(color);
|
||||
glRotated(rotate,0,0,1);
|
||||
// glLineWidth(thick);
|
||||
glScalef(scale / 0.10, scale / 0.10, 1.0);
|
||||
|
||||
textRenderer(mono)->draw(0, 0, string);
|
||||
|
||||
glPopMatrix();
|
||||
|
||||
}
|
||||
|
||||
|
||||
void drawvec3(int x, int y, float scale, float rotate, float thick, int mono, glm::vec3 vec, float r, float g, float b) {
|
||||
//
|
||||
// Draws text on screen as stroked so it can be resized
|
||||
|
|
|
@ -30,13 +30,13 @@ const glm::vec3 randVector();
|
|||
void renderWorldBox();
|
||||
int widthText(float scale, int mono, char const* string);
|
||||
float widthChar(float scale, int mono, char ch);
|
||||
void drawtext(int x, int y, float scale, float rotate, float thick, int mono,
|
||||
char const* string, float r=1.0, float g=1.0, float b=1.0);
|
||||
|
||||
void drawText(int x, int y, float scale, float rotate, int mono,
|
||||
char const* string, const float* color);
|
||||
|
||||
void drawvec3(int x, int y, float scale, float rotate, float thick, int mono, glm::vec3 vec,
|
||||
float r=1.0, float g=1.0, float b=1.0);
|
||||
|
||||
void noiseTest(int w, int h);
|
||||
|
||||
void drawVector(glm::vec3* vector);
|
||||
|
||||
void printVector(glm::vec3 vec);
|
||||
|
|
|
@ -73,6 +73,8 @@ bool ChatEntry::keyPressEvent(QKeyEvent* event) {
|
|||
}
|
||||
}
|
||||
|
||||
const float ALL_WHITE[] = { 1.0f, 1.0f, 1.0f };
|
||||
|
||||
void ChatEntry::render(int screenWidth, int screenHeight) {
|
||||
// draw a gray background so that we can actually see what we're typing
|
||||
int bottom = screenHeight - 150, top = screenHeight - 165;
|
||||
|
@ -85,8 +87,8 @@ void ChatEntry::render(int screenWidth, int screenHeight) {
|
|||
glVertex2f(right + 5, top - 3);
|
||||
glVertex2f(left - 5, top - 3);
|
||||
glEnd();
|
||||
|
||||
drawtext(left, bottom, 0.10f, 0, 1.0f, 0, _contents.c_str(), 1, 1, 1);
|
||||
|
||||
drawText(left, bottom, 0.10f, 0, 2, _contents.c_str(), ALL_WHITE);
|
||||
|
||||
float width = 0;
|
||||
for (string::iterator it = _contents.begin(), end = it + _cursorPos; it != end; it++) {
|
||||
|
|
Loading…
Reference in a new issue