Clementine-audio-player-Mac.../3rdparty/libprojectm/Renderer/Waveform.cpp

125 lines
3.0 KiB
C++

/*
* Waveform.hpp
*
* Created on: Jun 25, 2008
* Author: pete
*/
#ifdef LINUX
#include <GL/gl.h>
#endif
#ifdef WIN32
#include "glew.h"
#endif
#ifdef __APPLE__
#include <OpenGL/gl.h>
#endif
#include "Waveform.hpp"
#include <algorithm>
#include "BeatDetect.hpp"
typedef float floatPair[2];
typedef float floatTriple[3];
typedef float floatQuad[4];
Waveform::Waveform(int samples)
: RenderItem(),samples(samples), points(samples), pointContext(samples)
{
spectrum = false; /* spectrum data or pcm data */
dots = false; /* draw wave as dots or lines */
thick = false; /* draw thicker lines */
additive = false; /* add color values together */
scaling= 1; /* scale factor of waveform */
smoothing = 0; /* smooth factor of waveform */
sep = 0;
}
void Waveform::Draw(RenderContext &context)
{
//if (samples > 2048) samples = 2048;
if (additive) glBlendFunc(GL_SRC_ALPHA, GL_ONE);
else glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
if (thick)
{
glLineWidth(context.texsize <= 512 ? 2 : 2*context.texsize/512);
glPointSize(context.texsize <= 512 ? 2 : 2*context.texsize/512);
}
else glPointSize(context.texsize <= 512 ? 1 : context.texsize/512);
float *value1 = new float[samples];
float *value2 = new float[samples];
context.beatDetect->pcm->getPCM( value1, samples, 0, spectrum, smoothing, 0);
context.beatDetect->pcm->getPCM( value2, samples, 1, spectrum, smoothing, 0);
// printf("%f\n",pcmL[0]);
float mult= scaling*( spectrum ? 0.015f :1.0f);
std::transform(&value1[0],&value1[samples],&value1[0],std::bind2nd(std::multiplies<float>(),mult));
std::transform(&value2[0],&value2[samples],&value2[0],std::bind2nd(std::multiplies<float>(),mult));
WaveformContext waveContext(samples, context.beatDetect);
for(int x=0;x< samples;x++)
{
waveContext.sample = x/(float)(samples - 1);
waveContext.sample_int = x;
waveContext.left = value1[x];
waveContext.right = value2[x];
points[x] = PerPoint(points[x],waveContext);
}
floatQuad *colors = new float[samples][4];
floatPair *p = new float[samples][2];
for(int x=0;x< samples;x++)
{
colors[x][0] = points[x].r;
colors[x][1] = points[x].g;
colors[x][2] = points[x].b;
colors[x][3] = points[x].a * masterAlpha;
p[x][0] = points[x].x;
p[x][1] = -(points[x].y-1);
}
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glVertexPointer(2,GL_FLOAT,0,p);
glColorPointer(4,GL_FLOAT,0,colors);
if (dots) glDrawArrays(GL_POINTS,0,samples);
else glDrawArrays(GL_LINE_STRIP,0,samples);
glPointSize(context.texsize < 512 ? 1 : context.texsize/512);
glLineWidth(context.texsize < 512 ? 1 : context.texsize/512);
#ifndef USE_GLES1
glDisable(GL_LINE_STIPPLE);
#endif
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
// glPopMatrix();
delete[] colors;
delete[] p;
delete[] value1;
delete[] value2;
}