From 0e19f0ebe1d77361aa176d00ab6b05dfd07f2b86 Mon Sep 17 00:00:00 2001 From: mbellew Date: Sun, 10 Mar 2019 20:05:41 -0700 Subject: [PATCH] https://github.com/projectM-visualizer/projectm/issues/161 (#175) fix for https://github.com/projectM-visualizer/projectm/issues/161 --- src/libprojectM/Renderer/BeatDetect.hpp | 14 ++- src/libprojectM/Renderer/MilkdropWaveform.cpp | 94 +++++++++---------- src/libprojectM/Renderer/Waveform.cpp | 12 ++- 3 files changed, 62 insertions(+), 58 deletions(-) diff --git a/src/libprojectM/Renderer/BeatDetect.hpp b/src/libprojectM/Renderer/BeatDetect.hpp index ce1b7e1b5..58cd54747 100755 --- a/src/libprojectM/Renderer/BeatDetect.hpp +++ b/src/libprojectM/Renderer/BeatDetect.hpp @@ -33,6 +33,8 @@ #include "../PCM.hpp" #include "../dlldefs.h" +#include +#include class DLLEXPORT BeatDetect @@ -58,6 +60,14 @@ class DLLEXPORT BeatDetect void reset(); void detectFromSamples(); void getBeatVals ( float *vdataL, float *vdataR ); + float getPCMScale() + { + // added to address https://github.com/projectM-visualizer/projectm/issues/161 + // Returning 1.0 results in using the raw PCM data, which can make the presets look pretty unresponsive + // if the application volume is low. + return 0.5f / std::max(0.0001f,sqrtf(vol_history)); + } + private: /** Vars */ float beat_buffer[32][80], @@ -68,8 +78,8 @@ class DLLEXPORT BeatDetect beat_variance[32]; int beat_buffer_pos; float vol_buffer[80], - vol_instant, - vol_history; + vol_instant; + float vol_history; }; #endif /** !_BEAT_DETECT_H */ diff --git a/src/libprojectM/Renderer/MilkdropWaveform.cpp b/src/libprojectM/Renderer/MilkdropWaveform.cpp index 457cf5726..39a70bf66 100644 --- a/src/libprojectM/Renderer/MilkdropWaveform.cpp +++ b/src/libprojectM/Renderer/MilkdropWaveform.cpp @@ -194,6 +194,10 @@ void MilkdropWaveform::MaximizeColors(RenderContext &context) void MilkdropWaveform::WaveformMath(RenderContext &context) { + float *pcmdataR = context.beatDetect->pcm->pcmdataR; + float *pcmdataL = context.beatDetect->pcm->pcmdataL; + // scale PCM data based on vol_history to make it more or less independent of the application output volume + const float vol_scale = context.beatDetect->getPCMScale(); float r2, theta; @@ -203,7 +207,7 @@ void MilkdropWaveform::WaveformMath(RenderContext &context) float cos_rot; float sin_rot; - float temp_y; + const float temp_y = -1*(y-1.0f); two_waves = false; loop = false; @@ -212,75 +216,67 @@ void MilkdropWaveform::WaveformMath(RenderContext &context) { case Circle: - { + { loop = true; rot = 0; aspectScale=1.0; - temp_y=-1*(y-1.0); - - samples = 0? 512-32 : context.beatDetect->pcm->numsamples; + samples = context.beatDetect->pcm->numsamples; float inv_nverts_minus_one = 1.0f/(float)(samples); - float last_value = context.beatDetect->pcm->pcmdataR[samples-1]+context.beatDetect->pcm->pcmdataL[samples-1]; - float first_value = context.beatDetect->pcm->pcmdataR[0]+context.beatDetect->pcm->pcmdataL[0]; + float last_value = vol_scale * (pcmdataR[samples-1]+pcmdataL[samples-1]); + float first_value = vol_scale * (pcmdataR[0]+pcmdataL[0]); float offset = first_value-last_value; for ( int i=0;ipcm->pcmdataR[i]+context.beatDetect->pcm->pcmdataL[i]; + float value = vol_scale * (pcmdataR[i]+pcmdataL[i]); value += offset * (i/(float)samples); - r2=(0.5 + 0.4f*.12*value*scale + mystery)*.5; + r2=(0.5f + 0.4f*.12f*value*scale + mystery)*.5f; theta=i*inv_nverts_minus_one*6.28f + context.time*0.2f; - wavearray[i][0]=(r2*cos(theta)*(context.aspectCorrect? context.aspectRatio : 1.0)+x); + wavearray[i][0]=(r2*cos(theta)*(context.aspectCorrect? context.aspectRatio : 1.0f)+x); wavearray[i][1]=(r2*sin(theta)+temp_y); } - } - - break; + } + break; case RadialBlob://circularly moving waveform - - rot = 0; + { + rot = 0; aspectScale = context.aspectRatio; - temp_y=-1*(y-1.0); - samples = 512-32; for ( int i=0;i<512-32;i++) { - theta=context.beatDetect->pcm->pcmdataL[i+32]*0.06*scale * 1.57 + context.time*2.3; - r2=(0.53 + 0.43*context.beatDetect->pcm->pcmdataR[i]*0.12*scale+ mystery)*.5; + theta=vol_scale*pcmdataL[i+32]*0.06f*scale * 1.57f + context.time*2.3f; + r2=(0.53f + 0.43f*vol_scale*pcmdataR[i]*0.12f*scale+ mystery)*.5f; - wavearray[i][0]=(r2*cos(theta)*(context.aspectCorrect ? context.aspectRatio : 1.0)+x); + wavearray[i][0]=(r2*cos(theta)*(context.aspectCorrect ? context.aspectRatio : 1.0f)+x); wavearray[i][1]=(r2*sin(theta)+temp_y); } - - break; + } + break; case Blob2://EXPERIMENTAL - temp_y=-1*(y-1.0); rot = 0; aspectScale =1.0; samples = 512-32; for ( int i=0;i<512-32;i++) { - wavearray[i][0]=(context.beatDetect->pcm->pcmdataR[i]*scale*0.5*(context.aspectCorrect ? context.aspectRatio : 1.0) + x); - wavearray[i][1]=(context.beatDetect->pcm->pcmdataL[i+32]*scale*0.5 + temp_y); + wavearray[i][0]=(vol_scale*pcmdataR[i]*scale*0.5f*(context.aspectCorrect ? context.aspectRatio : 1.0f) + x); + wavearray[i][1]=(vol_scale*pcmdataL[i+32]*scale*0.5f + temp_y); } break; case Blob3://EXPERIMENTAL - temp_y=-1*(y-1.0); - rot = 0; aspectScale =1.0; @@ -288,8 +284,8 @@ void MilkdropWaveform::WaveformMath(RenderContext &context) for ( int i=0;i<512-32;i++) { - wavearray[i][0]=(context.beatDetect->pcm->pcmdataR[i] * scale*0.5 + x); - wavearray[i][1]=( (context.beatDetect->pcm->pcmdataL[i+32]*scale*0.5 + temp_y)); + wavearray[i][0]=(vol_scale*pcmdataR[i] * scale*0.5f + x); + wavearray[i][1]=( (vol_scale*pcmdataL[i+32]*scale*0.5f + temp_y)); } break; @@ -299,8 +295,6 @@ void MilkdropWaveform::WaveformMath(RenderContext &context) rot =-mystery*90; aspectScale=1.0; - temp_y=-1*(y-1.0); - float w1 = 0.45f + 0.5f*(mystery*0.5f + 0.5f); float w2 = 1.0f - w1; float xx[512], yy[512]; @@ -308,9 +302,9 @@ void MilkdropWaveform::WaveformMath(RenderContext &context) for (int i=0; i<512-32; i++) { - xx[i] = -1.0f + 2.0f*(i/(512.0-32.0)) + x; - yy[i] =0.4* context.beatDetect->pcm->pcmdataL[i]*0.47f*scale + temp_y; - xx[i] += 0.4*context.beatDetect->pcm->pcmdataR[i]*0.44f*scale; + xx[i] = -1.0f + 2.0f*(i/(512.0f-32.0f)) + x; + yy[i] = 0.4f* vol_scale*pcmdataL[i]*0.47f*scale + temp_y; + xx[i] += 0.4f* vol_scale*pcmdataR[i]*0.44f*scale; if (i>1) { @@ -327,36 +321,34 @@ void MilkdropWaveform::WaveformMath(RenderContext &context) rot = 0; aspectScale =1.0; - temp_y=-1*(y-1.0); - cos_rot = cosf(context.time*0.3f); sin_rot = sinf(context.time*0.3f); samples = 512-32; for ( int i=0;i<512-32;i++) { - float x0 = (context.beatDetect->pcm->pcmdataR[i]*context.beatDetect->pcm->pcmdataL[i+32] + context.beatDetect->pcm->pcmdataL[i+32]*context.beatDetect->pcm->pcmdataR[i]); - float y0 = (context.beatDetect->pcm->pcmdataR[i]*context.beatDetect->pcm->pcmdataR[i] - context.beatDetect->pcm->pcmdataL[i+32]*context.beatDetect->pcm->pcmdataL[i+32]); - wavearray[i][0]=((x0*cos_rot - y0*sin_rot)*scale*0.5*(context.aspectCorrect ? context.aspectRatio : 1.0) + x); - wavearray[i][1]=( (x0*sin_rot + y0*cos_rot)*scale*0.5 + temp_y); + float x0 = (vol_scale*pcmdataR[i]*vol_scale*pcmdataL[i+32] + vol_scale*pcmdataL[i+32]*vol_scale*pcmdataR[i]); + float y0 = (vol_scale*pcmdataR[i]*vol_scale*pcmdataR[i] - vol_scale*pcmdataL[i+32]*vol_scale*pcmdataL[i+32]); + wavearray[i][0]=((x0*cos_rot - y0*sin_rot)*scale*0.5f*(context.aspectCorrect ? context.aspectRatio : 1.0f) + x); + wavearray[i][1]=( (x0*sin_rot + y0*cos_rot)*scale*0.5f + temp_y); } break; case Line://single waveform - wave_x_temp=-2*0.4142*(fabs(fabs(mystery)-.5)-.5); + wave_x_temp=-2*0.4142f*(fabs(fabs(mystery)-.5f)-.5f); rot = -mystery*90; - aspectScale =1.0+wave_x_temp; - wave_x_temp=-1*(x-1.0); - samples = 0 ? 512-32 : context.beatDetect->pcm->numsamples; + aspectScale =1.0f+wave_x_temp; + wave_x_temp=-1*(x-1.0f); + samples = context.beatDetect->pcm->numsamples; for ( int i=0;i< samples;i++) { wavearray[i][0]=i/(float) samples; - wavearray[i][1]=context.beatDetect->pcm->pcmdataR[i]*.04*scale+wave_x_temp; + wavearray[i][1]=vol_scale*pcmdataR[i]*.04f*scale+wave_x_temp; } // printf("%f %f\n",renderTarget->texsize*wave_y_temp,wave_y_temp); @@ -366,29 +358,29 @@ void MilkdropWaveform::WaveformMath(RenderContext &context) case DoubleLine://dual waveforms - wave_x_temp=-2*0.4142*(fabs(fabs(mystery)-.5)-.5); + wave_x_temp=-2*0.4142f*(fabs(fabs(mystery)-.5f)-.5f); rot = -mystery*90; - aspectScale =1.0+wave_x_temp; + aspectScale =1.0f+wave_x_temp; - samples = 0 ? 512-32 : context.beatDetect->pcm->numsamples; + samples = context.beatDetect->pcm->numsamples; two_waves = true; - double y_adj = y*y*.5; + const float y_adj = y*y*.5f; wave_y_temp=-1*(x-1); for ( int i=0;ipcm->pcmdataL[i]*.04*scale+(wave_y_temp+y_adj); + wavearray[i][1]= vol_scale*pcmdataL[i]*.04f*scale+(wave_y_temp+y_adj); } for ( int i=0;ipcm->pcmdataR[i]*.04*scale+(wave_y_temp-y_adj); + wavearray2[i][1]=vol_scale*pcmdataR[i]*.04f*scale+(wave_y_temp-y_adj); } break; diff --git a/src/libprojectM/Renderer/Waveform.cpp b/src/libprojectM/Renderer/Waveform.cpp index c2d0cea8d..ceb157420 100644 --- a/src/libprojectM/Renderer/Waveform.cpp +++ b/src/libprojectM/Renderer/Waveform.cpp @@ -8,13 +8,12 @@ #include "projectM-opengl.h" #include "Waveform.hpp" #include +#include #include "BeatDetect.hpp" #include "ShaderEngine.hpp" #include typedef float floatPair[2]; -typedef float floatTriple[3]; -typedef float floatQuad[4]; Waveform::Waveform(int _samples) : RenderItem(),samples(_samples), points(_samples), pointContext(_samples) @@ -42,7 +41,10 @@ void Waveform::InitVertexAttrib() { void Waveform::Draw(RenderContext &context) { - float *value1 = new float[samples]; + // scale PCM data based on vol_history to make it more or less independent of the application output volume + const float vol_scale = context.beatDetect->getPCMScale(); + + 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); @@ -58,8 +60,8 @@ void Waveform::Draw(RenderContext &context) { waveContext.sample = x/(float)(samples - 1); waveContext.sample_int = x; - waveContext.left = value1[x]; - waveContext.right = value2[x]; + waveContext.left = vol_scale * value1[x]; + waveContext.right = vol_scale * value2[x]; points[x] = PerPoint(points[x],waveContext); }