Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
55 commits
Select commit Hold shift + click to select a range
d263bbf
New spectrum analyzer work in progress / init
he29-net Mar 4, 2019
47fba16
Implement resizability and X axis linear/log scale
he29-net Mar 8, 2019
c0563e2
Rework Y axis drawing and add linear scale; various cleanup
he29-net Mar 9, 2019
3e13296
Implement waterfall graph basics; variety of other stuff
he29-net Mar 10, 2019
c71692f
Fix that silly stereo rendering bug; minor waterfall cleanup
he29-net Mar 10, 2019
95e5713
WIP commit before branch switch
he29-net Mar 14, 2019
dcfa7bc
window precomputing update
he29-net Mar 14, 2019
b2ca051
Fix bug with disappearing curves; implement averaging; ref. freeze WIP
he29-net Mar 14, 2019
bbaee49
WIP on FFT block size switching (currently broken)
he29-net Mar 17, 2019
280bd8f
Finished block size and window type switching; many small fixes
he29-net Mar 21, 2019
b80b214
Log scale for waterfall
he29-net Mar 23, 2019
f9f4ef7
WIP on range switching
he29-net Mar 24, 2019
feed0fb
Implemented cursor display and readings for spectrum view
he29-net Mar 24, 2019
66bea0e
Many small improvements, mainly range switching
he29-net Mar 29, 2019
b1b9146
paintEvent rewrite and optimization, peak hold implementation
he29-net Mar 30, 2019
6d1a244
Config GUI overhaul
he29-net Mar 31, 2019
44f1240
Big cleanup in progress
he29-net Mar 31, 2019
d48349b
Continued cleanup; finished waterfall hiding, added zero padding
he29-net Apr 7, 2019
1700b80
Fine-tuning and cleanup done, ready for rebase
he29-net Apr 14, 2019
1decd33
Cleanup of fft_helpers
he29-net Apr 16, 2019
29d89df
Replace std::mutex with QMutex; some additional fine-tuning
he29-net Apr 17, 2019
d6fd391
Fix EffectView mistake; boost gamma curve slightly to make low values…
he29-net May 6, 2019
c7db22a
Update src/core/fft_helpers.cpp
he29-net Jun 1, 2019
134619e
Update src/core/fft_helpers.cpp
he29-net Jun 1, 2019
8ef716a
fft_helpers.h indentation fix
he29-net Jun 1, 2019
5e07a28
fft_helpers: Add @return tags to function commets; mark pointer and r…
he29-net Jun 1, 2019
ba85822
Move opening brackets to separate line
he29-net Jun 1, 2019
9e40dc4
Fix Doxygen syntax in fft_helpers
he29-net Jun 1, 2019
2b59149
Fix of the previous 'Doxygen fix' fix
he29-net Jun 2, 2019
0058626
Add tool-tips
he29-net Jun 2, 2019
b03d48d
Update plugins/SpectrumAnalyzer/SaProcessor.h
he29-net Jun 14, 2019
5f18863
Update plugins/SpectrumAnalyzer/Analyzer.h
he29-net Jun 14, 2019
cec0768
Update plugins/SpectrumAnalyzer/SaProcessor.cpp
he29-net Jun 14, 2019
b9d3e0d
Update plugins/SpectrumAnalyzer/SaControlsDialog.cpp
he29-net Jun 14, 2019
70b964c
Update plugins/SpectrumAnalyzer/SaControlsDialog.h
he29-net Jun 14, 2019
def85bc
Update plugins/SpectrumAnalyzer/SaSpectrumView.h
he29-net Jun 14, 2019
57a5b6e
Remove EffectControlDialog pointer from SaControls, add a replacement…
he29-net Jun 14, 2019
8c5c35a
Use markdown syntax for readme file
he29-net Jun 14, 2019
4431e6e
Fix the markdown syntax I just added xD
he29-net Jun 14, 2019
86f01ff
... and change changelog formatting, since apparently tabs here are 8…
he29-net Jun 14, 2019
d0a7f70
Arrgh! And fix a typo in the title >_<
he29-net Jun 14, 2019
78d328e
Avoid waterfall history updates when there is no input
he29-net Jun 15, 2019
be824e1
Display black rectangle instead waterfall when no data are available
he29-net Jun 15, 2019
0e6aa9e
Add 'override's to overriding methods; mark additional constructors a…
he29-net Jun 15, 2019
aa41b84
Remove iostream include from SaWaterfall
he29-net Jun 16, 2019
1556187
Update plugins/SpectrumAnalyzer/SaProcessor.cpp
he29-net Jun 23, 2019
ec9615c
Update plugins/SpectrumAnalyzer/SaProcessor.cpp
he29-net Jun 23, 2019
ff13ca3
Update plugins/SpectrumAnalyzer/SaProcessor.cpp
he29-net Jun 23, 2019
217f629
Update plugins/SpectrumAnalyzer/SaProcessor.cpp
he29-net Jun 23, 2019
b359881
First batch of changes for second review round
he29-net Jun 23, 2019
f4510ec
Make some -Weverything warnings go away (mainly implicit signed vs. u…
he29-net Jun 26, 2019
c8a105c
Cleanup includes, update comments in SaProcessor
he29-net Jun 26, 2019
89d4703
Batch of changes for the third review
he29-net Jul 11, 2019
14e9008
Restrict cursor drawing to graph ranges
JohannesLorenz Jul 14, 2019
1409f1f
Spectrum View: Use existing cursor boundaries
JohannesLorenz Jul 16, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Log scale for waterfall
  • Loading branch information
he29-net committed Apr 16, 2019
commit b80b214b28b572bbc8244c9810382a21797bf5e4
2 changes: 1 addition & 1 deletion plugins/SpectrumAnalyzer/SaControls.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ SaControls::SaControls(Analyzer *effect) :

m_inProgress(false)
{
m_colorL = QColor(51, 148, 204, 204);
m_colorL = QColor(51, 148, 204, 135);
m_colorR = QColor(204, 107, 51, 135);
m_colorMono = QColor(51, 148, 204, 204);
m_colorBG = QColor(7, 7, 7, 255); // 20 % gray
Expand Down
9 changes: 9 additions & 0 deletions plugins/SpectrumAnalyzer/SaControls.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,16 @@ class Analyzer;
// FIXME: move this somewhere appropriate
const int LOWEST_FREQ = 10; // arbitrary low frequency limit for log. scale (Hz, >0)
const int LOWEST_AMP = -5; // arbitrary low amplitude limit for log. scale (10*dB)
const int RANGE_AUDIBLE_START = 20;
const int RANGE_AUDIBLE_END = 20000;
const int RANGE_BASS_START = 20;
const int RANGE_BASS_END = 300;
const int RANGE_MID_START = 200;
const int RANGE_MID_SEND = 5000;
const int RANGE_HIGH_START = 4000;
const int RANGE_HIGH_END = 20000;
const int WATERFALL_HEIGHT = 256;

#define DEBUG 1

class SaControls : public EffectControls
Expand Down
109 changes: 97 additions & 12 deletions plugins/SpectrumAnalyzer/SaProcessor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -144,21 +144,49 @@ void SaProcessor::analyse(sampleFrame *in_buffer, const fpp_t frame_count)
std::copy( pixel,
pixel + binCount() * WATERFALL_HEIGHT - binCount(),
pixel + binCount());
memset(pixel, 0, binCount() * sizeof (QRgb));

int target;
float accL = 0;
float accR = 0;

for (int i = 0; i < binCount(); i++) {
// apply gamma correction to make small values more visible
// (should be around 0.42 to 0.45 for sRGB displays)
float ampL = powf(m_normSpectrumL[i], 0.42);
float ampR = powf(m_normSpectrumR[i], 0.42);

if (stereo) {
pixel[i] = qRgb(m_controls->m_colorL.red() * ampL + m_controls->m_colorR.red() * ampR,
m_controls->m_colorL.green() * ampL + m_controls->m_colorR.green() * ampR,
m_controls->m_colorL.blue() * ampL + m_controls->m_colorR.blue() * ampR);
if (m_controls->m_logXModel.value()) {
// Logarithmic
float band_start = freqToXPixel(binToFreq(i) - binBandwidth() / 2.0, binCount() -1);
float band_end = freqToXPixel(binToFreq(i + 1) - binBandwidth() / 2.0, binCount() -1);

if (band_end - band_start > 1.0) {
// draw all pixels covered by this band
for (target = band_start; target < band_end; target++) {
if (target >= 0 && target < binCount()) {
pixel[target] = makePixel(m_normSpectrumL[i], m_normSpectrumR[i]);
}
}
accL = (band_end - (int)band_end) * m_normSpectrumL[i];
accR = (band_end - (int)band_end) * m_normSpectrumR[i];
} else {
// sub-pixel drawing; add contribution of current band
target = band_start;
if ((int)band_start == (int)band_end) {
accL += (band_end - band_start) * m_normSpectrumL[i];
accR += (band_end - band_start) * m_normSpectrumR[i];
} else {
// make sure contribution is split correctly on pixel boundary
accL += ((int)band_end - band_start) * m_normSpectrumL[i];
accR += ((int)band_end - band_start) * m_normSpectrumR[i];

if (target >= 0 && target < binCount()) {
pixel[target] = makePixel(accL, accR);
}
// save remaining portion of the band for the following band / pixel
accL = (band_end - (int)band_end) * m_normSpectrumL[i];
accR = (band_end - (int)band_end) * m_normSpectrumR[i];
}
}
} else {
pixel[i] = qRgb(m_controls->m_colorMono.lighter().red() * ampL,
m_controls->m_colorMono.lighter().green() * ampL,
m_controls->m_colorMono.lighter().blue() * ampL);
// Linear: simple 1:1 assignment
pixel[i] = makePixel(m_normSpectrumL[i], m_normSpectrumR[i]);
}
}

Expand All @@ -175,6 +203,63 @@ void SaProcessor::analyse(sampleFrame *in_buffer, const fpp_t frame_count)
}
}


QRgb SaProcessor::makePixel(float left, float right) {
// apply gamma correction to make small values more visible
// (should be around 0.42 to 0.45 for sRGB displays)
if (m_controls->m_stereoModel.value()) {
float ampL = powf(left, 0.42);
float ampR = powf(right, 0.42);
return qRgb(m_controls->m_colorL.red() * ampL + m_controls->m_colorR.red() * ampR,
m_controls->m_colorL.green() * ampL + m_controls->m_colorR.green() * ampR,
m_controls->m_colorL.blue() * ampL + m_controls->m_colorR.blue() * ampR);
} else {
float ampL = powf(left, 0.42);
return qRgb(m_controls->m_colorMono.lighter().red() * ampL,
m_controls->m_colorMono.lighter().green() * ampL,
m_controls->m_colorMono.lighter().blue() * ampL);
}
}

float SaProcessor::binToFreq(int index)
{
return (index * getSampleRate() / 2.0) / binCount();
}

float SaProcessor::binBandwidth()
{
return (getSampleRate() / 2.0) / binCount();
}

float SaProcessor::freqToXPixel(float freq, int width)
{
if (m_controls->m_logXModel.value()) {
if (freq <= 1) {return 0;}
float min = log10f(LOWEST_FREQ);
float max = log10f(getSampleRate() / 2);
float range = max - min;
return (log10f(freq) - min) / range * width;
} else {
float range = getSampleRate() / 2;
return freq / range * width;
}
}


float SaProcessor::ampToYPixel(float amplitude, int height)
{
if (m_controls->m_logYModel.value()){
if (log10f(amplitude) < LOWEST_AMP){
return height;
} else {
return height * log10f(amplitude) / LOWEST_AMP;
}
} else {
return height - height * amplitude;
}
}


int SaProcessor::getSampleRate() const
{
return m_sampleRate;
Expand Down
7 changes: 7 additions & 0 deletions plugins/SpectrumAnalyzer/SaProcessor.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,11 @@ class SaProcessor

void reallocateBuffers(int new_size_index);

float freqToXPixel(float frequency, int width);
float ampToYPixel(float amplitude, int height);
float binToFreq(int index);
float binBandwidth();

std::mutex m_dataAccess;

private:
Expand Down Expand Up @@ -80,6 +85,8 @@ class SaProcessor
bool m_active;
bool m_inProgress;

QRgb makePixel(float left, float right);

friend class SaSpectrumView;
friend class SaWaterfallView;
};
Expand Down
30 changes: 6 additions & 24 deletions plugins/SpectrumAnalyzer/SaSpectrumView.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -194,8 +194,8 @@ void SaSpectrumView::paintEvent(QPaintEvent *event)
(*m_bandHeight)[x] = bands[x];
}

if (freqToXPixel(bandToFreq(x), displayWidth) >= 0) {
m_path.lineTo( freqToXPixel(bandToFreq(x), displayWidth) + displayLeft,
if (freqToXPixel(binToFreq(x), displayWidth) >= 0) {
m_path.lineTo( freqToXPixel(binToFreq(x), displayWidth) + displayLeft,
ampToYPixel((*m_bandHeight)[x], displayBottom));
m_decaySum += (*m_bandHeight)[x];
}
Expand Down Expand Up @@ -269,39 +269,21 @@ void SaSpectrumView::paintEvent(QPaintEvent *event)
}


float SaSpectrumView::bandToFreq(int index)
float SaSpectrumView::binToFreq(int index)
{
return index * m_processor->getSampleRate() / (m_processor->binCount() * 2);
return m_processor->binToFreq(index);
}


float SaSpectrumView::freqToXPixel(float freq, int width)
{
if (m_controls->m_logXModel.value()){
float min = log10f(LOWEST_FREQ);
float max = log10f(m_processor->getSampleRate() / 2);
float range = max - min;
return (log10f(freq) - min) / range * width;
} else {
float min = LOWEST_FREQ;
float max = m_processor->getSampleRate() / 2;
float range = max - min;
return (freq - min) / range * width;
}
return m_processor->freqToXPixel(freq, width);
}


float SaSpectrumView::ampToYPixel(float amplitude, int height)
{
if (m_controls->m_logYModel.value()){
if (log10f(amplitude) < LOWEST_AMP){
return height;
} else {
return height * log10f(amplitude) / LOWEST_AMP;
}
} else {
return height - height * amplitude;
}
return m_processor->ampToYPixel(amplitude, height);
}


Expand Down
2 changes: 1 addition & 1 deletion plugins/SpectrumAnalyzer/SaSpectrumView.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,6 @@ private slots:

float freqToXPixel(float frequency, int width);
float ampToYPixel(float amplitude, int height);
float bandToFreq(int index);
float binToFreq(int index);
};
#endif // SASPECTRUMVIEW_H