mirror of
https://github.com/overte-org/overte.git
synced 2025-04-24 05:53:29 +02:00
Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
5e737ce5d4
4 changed files with 157 additions and 50 deletions
|
@ -127,13 +127,9 @@ int audioCallback (const void *inputBuffer,
|
|||
|
||||
loudness /= BUFFER_LENGTH_SAMPLES;
|
||||
data->lastInputLoudness = loudness;
|
||||
|
||||
// If scope is turned on, copy input buffer to scope
|
||||
if (scope->getState()) {
|
||||
for (int i = 0; i < BUFFER_LENGTH_SAMPLES; i++) {
|
||||
scope->addData((float)inputLeft[i]/32767.0, 1, i);
|
||||
}
|
||||
}
|
||||
|
||||
// add data to the scope
|
||||
scope->addSamples(0, inputLeft, BUFFER_LENGTH_SAMPLES);
|
||||
|
||||
if (data->mixerAddress != 0) {
|
||||
sockaddr_in audioMixerSocket;
|
||||
|
@ -278,6 +274,10 @@ int audioCallback (const void *inputBuffer,
|
|||
outputRight[s] = rightSample;
|
||||
}
|
||||
|
||||
// add data to the scope
|
||||
scope->addSamples(1, outputLeft, PACKET_LENGTH_SAMPLES_PER_CHANNEL);
|
||||
scope->addSamples(2, outputRight, PACKET_LENGTH_SAMPLES_PER_CHANNEL);
|
||||
|
||||
ringBuffer->setNextOutput(ringBuffer->getNextOutput() + PACKET_LENGTH_SAMPLES);
|
||||
|
||||
if (ringBuffer->getNextOutput() == ringBuffer->getBuffer() + RING_BUFFER_SAMPLES) {
|
||||
|
@ -330,8 +330,9 @@ void *receiveAudioViaUDP(void *args) {
|
|||
delete[] directory;
|
||||
delete[] filename;
|
||||
}
|
||||
|
||||
|
||||
while (!stopAudioReceiveThread) {
|
||||
|
||||
if (sharedAudioData->audioSocket->receive((void *)receivedData, &receivedBytes)) {
|
||||
|
||||
gettimeofday(¤tReceiveTime, NULL);
|
||||
|
|
|
@ -8,38 +8,123 @@
|
|||
|
||||
#include "Oscilloscope.h"
|
||||
|
||||
Oscilloscope::Oscilloscope(int w,
|
||||
int h, bool isOn) {
|
||||
width = w;
|
||||
height = h;
|
||||
data1 = new float[width];
|
||||
data2 = new float[width];
|
||||
for (int i = 0; i < width; i++) {
|
||||
data1[i] = 0.0;
|
||||
data2[i] = 0.0;
|
||||
#include "InterfaceConfig.h"
|
||||
#include <limits>
|
||||
#include <cstring>
|
||||
#include <algorithm>
|
||||
|
||||
// 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 N_SAMPLES_ALLOC = Oscilloscope::MAX_SAMPLES * Oscilloscope::MAX_CHANNELS;
|
||||
|
||||
// adding an x-coordinate yields twice the amount of vertices
|
||||
unsigned const MAX_COORDS = Oscilloscope::MAX_SAMPLES * 2;
|
||||
unsigned const N_COORDS_ALLOC = MAX_COORDS * Oscilloscope::MAX_CHANNELS;
|
||||
|
||||
unsigned const N_ALLOC_TOTAL = N_SAMPLES_ALLOC + N_COORDS_ALLOC;
|
||||
}
|
||||
|
||||
|
||||
Oscilloscope::Oscilloscope(int w, int h, bool isEnabled) :
|
||||
_valWidth(w), _valHeight(h),
|
||||
_arrSamples(0l), _arrVertices(0l),
|
||||
_valLowpass(0.4f), _valDownsample(3),
|
||||
enabled(isEnabled), inputPaused(false) {
|
||||
|
||||
// allocate enough space for the sample data and to turn it into
|
||||
// vertices and since they're all 'short', do so in one shot
|
||||
_arrSamples = new short[N_ALLOC_TOTAL];
|
||||
memset(_arrSamples, 0, N_ALLOC_TOTAL * sizeof(short));
|
||||
_arrVertices = _arrSamples + N_SAMPLES_ALLOC;
|
||||
|
||||
// initialize write positions
|
||||
for (unsigned ch = 0; ch < MAX_CHANNELS; ++ch) {
|
||||
_arrWritePos[ch] = MAX_SAMPLES * ch;
|
||||
}
|
||||
state = isOn;
|
||||
current_sample = 0;
|
||||
}
|
||||
|
||||
void Oscilloscope::addData(float d, int channel, int position) {
|
||||
if (channel == 1) data1[position] = d;
|
||||
else data2[position] = d;
|
||||
Oscilloscope::~Oscilloscope() {
|
||||
|
||||
delete[] _arrSamples;
|
||||
}
|
||||
|
||||
void Oscilloscope::addSamples(unsigned ch, short const* data, unsigned n) {
|
||||
|
||||
if (! enabled || inputPaused) {
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned baseOffs = MAX_SAMPLES * ch;
|
||||
unsigned endOffs = baseOffs + MAX_SAMPLES;
|
||||
|
||||
unsigned writePos = _arrWritePos[ch];
|
||||
unsigned newWritePos = writePos + n;
|
||||
|
||||
unsigned n2 = 0;
|
||||
if (newWritePos >= endOffs) {
|
||||
n2 = newWritePos - endOffs;
|
||||
newWritePos = baseOffs + n2;
|
||||
n -= n2;
|
||||
}
|
||||
|
||||
memcpy(_arrSamples + writePos, data, n * sizeof(short));
|
||||
if (n2 > 0) {
|
||||
memcpy(_arrSamples + baseOffs, data + n, n2 * sizeof(short));
|
||||
}
|
||||
|
||||
_arrWritePos[ch] = newWritePos;
|
||||
}
|
||||
|
||||
void Oscilloscope::render() {
|
||||
glColor3f(1,1,1);
|
||||
glBegin(GL_LINES);
|
||||
for (int i = 0; i < width; i++) {
|
||||
glVertex2f((float)i, height/2 + data1[i]*(float)height);
|
||||
|
||||
if (! enabled) {
|
||||
return;
|
||||
}
|
||||
glEnd();
|
||||
|
||||
glColor3f(0,1,1);
|
||||
glBegin(GL_LINES);
|
||||
for (int i = 0; i < width; i++) {
|
||||
glVertex2f((float)i, height/2 + data2[i]*(float)height);
|
||||
}
|
||||
glEnd();
|
||||
// expand data to vertex data, now
|
||||
int lowpass = -int(std::numeric_limits<short>::min()) * _valLowpass;
|
||||
unsigned downsample = _valDownsample;
|
||||
// keep half of the buffer for writing and ensure an even vertex count
|
||||
unsigned usedWidth = min(_valWidth, MAX_SAMPLES / (downsample * 2)) & ~1u;
|
||||
unsigned usedSamples = usedWidth * downsample;
|
||||
|
||||
}
|
||||
for (unsigned ch = 0; ch < MAX_CHANNELS; ++ch) {
|
||||
|
||||
short const* basePtr = _arrSamples + MAX_SAMPLES * ch;
|
||||
short const* endPtr = basePtr + MAX_SAMPLES;
|
||||
short const* inPtr = _arrSamples + _arrWritePos[ch];
|
||||
short* outPtr = _arrVertices + MAX_COORDS * ch;
|
||||
int sample = 0, x = usedWidth;
|
||||
for (int i = int(usedSamples); --i >= 0 ;) {
|
||||
|
||||
if (inPtr == basePtr) {
|
||||
inPtr = endPtr;
|
||||
}
|
||||
sample += ((*--inPtr - sample) * lowpass) >> 15;
|
||||
if (i % downsample == 0) {
|
||||
*outPtr++ = short(--x);
|
||||
*outPtr++ = short(sample);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
glPushMatrix();
|
||||
glTranslatef(0.0f, _valHeight / 2.0f, 0.0f);
|
||||
glScaled(1.0f, _valHeight / 32767.0f, 1.0f);
|
||||
glVertexPointer(2, GL_SHORT, 0, _arrVertices);
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
glColor3f(1.0f, 1.0f, 1.0f);
|
||||
glDrawArrays(GL_LINES, MAX_SAMPLES * 0, usedWidth);
|
||||
glColor3f(0.0f, 1.0f ,1.0f);
|
||||
glDrawArrays(GL_LINES, MAX_SAMPLES * 1, usedWidth);
|
||||
glColor3f(1.0f, 1.0f ,0.0f);
|
||||
glDrawArrays(GL_LINES, MAX_SAMPLES * 2, usedWidth);
|
||||
glDisableClientState(GL_VERTEX_ARRAY);
|
||||
glPopMatrix();
|
||||
}
|
||||
|
||||
|
|
|
@ -9,24 +9,45 @@
|
|||
#ifndef __interface__Oscilloscope__
|
||||
#define __interface__Oscilloscope__
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
#include "Util.h"
|
||||
#include "world.h"
|
||||
#include "InterfaceConfig.h"
|
||||
#include <cassert>
|
||||
|
||||
class Oscilloscope {
|
||||
public:
|
||||
Oscilloscope(int width,
|
||||
int height, bool isOn);
|
||||
void addData(float d, int channel, int position);
|
||||
void render();
|
||||
void setState(bool s) {state = s;};
|
||||
bool getState() {return state;};
|
||||
static unsigned const MAX_CHANNELS = 3;
|
||||
static unsigned const MAX_SAMPLES = 4096; // per channel
|
||||
private:
|
||||
int width;
|
||||
int height;
|
||||
float *data1, *data2;
|
||||
int current_sample;
|
||||
bool state;
|
||||
unsigned _valWidth;
|
||||
unsigned _valHeight;
|
||||
short* _arrSamples;
|
||||
short* _arrVertices;
|
||||
unsigned _arrWritePos[MAX_CHANNELS];
|
||||
|
||||
float _valLowpass;
|
||||
unsigned _valDownsample;
|
||||
|
||||
public:
|
||||
|
||||
Oscilloscope(int width, int height, bool isEnabled);
|
||||
~Oscilloscope();
|
||||
|
||||
volatile bool enabled;
|
||||
volatile bool inputPaused;
|
||||
|
||||
|
||||
void addSamples(unsigned ch, short const* data, unsigned n);
|
||||
|
||||
void render();
|
||||
|
||||
void setLowpass(float w) { assert(w > 0.0f && w <= 1.0f); _valLowpass = w; }
|
||||
void setDownsampling(unsigned f) { assert(f > 0); _valDownsample = f; }
|
||||
|
||||
private:
|
||||
// don't copy/assign
|
||||
Oscilloscope(Oscilloscope const&); // = delete;
|
||||
Oscilloscope& operator=(Oscilloscope const&); // = delete;
|
||||
|
||||
// implementation
|
||||
inline short* bufferBase(int i, int channel);
|
||||
};
|
||||
|
||||
#endif /* defined(__interface__oscilloscope__) */
|
||||
|
|
|
@ -860,7 +860,7 @@ void display(void)
|
|||
|
||||
#ifndef _WIN32
|
||||
audio.render(WIDTH, HEIGHT);
|
||||
if (audioScope.getState()) audioScope.render();
|
||||
audioScope.render();
|
||||
#endif
|
||||
|
||||
if (displayHeadMouse && !::lookingInMirror && statsOn) {
|
||||
|
|
Loading…
Reference in a new issue