LMMS
Loading...
Searching...
No Matches
SaProcessor.h
Go to the documentation of this file.
1/* SaProcessor.h - declaration of SaProcessor class.
2 *
3 * Copyright (c) 2019 Martin Pavelek <he29/dot/HS/at/gmail/dot/com>
4 *
5 * Based partially on Eq plugin code,
6 * Copyright (c) 2014 David French <dave/dot/french3/at/googlemail/dot/com>
7 *
8 * This file is part of LMMS - https://lmms.io
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public
12 * License as published by the Free Software Foundation; either
13 * version 2 of the License, or (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public
21 * License along with this program (see COPYING); if not, write to the
22 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
23 * Boston, MA 02110-1301 USA.
24 *
25 */
26
27#ifndef SAPROCESSOR_H
28#define SAPROCESSOR_H
29
30#include <atomic>
31#include <fftw3.h>
32#include <QMutex>
33#include <QRgb>
34#include <vector>
35
36
37
38namespace lmms
39{
40
41template<class T>
43
44class SaControls;
45class SampleFrame;
46
47
50{
51public:
52 explicit SaProcessor(const SaControls *controls);
53 virtual ~SaProcessor();
54
55 // analysis thread and a method to terminate it
57 void terminate() {m_terminate = true;}
58
59 // inform processor if any processing is actually required
60 void setSpectrumActive(bool active);
61 void setWaterfallActive(bool active);
62 void flipRequest() {m_flipRequest = true;} // request refresh of history buffer
63
64 // configuration is taken from models in SaControls; some changes require
65 // an exlicit update request (reallocation and window rebuild)
66 void reallocateBuffers();
67 void rebuildWindow();
68 void clear();
69 void clearHistory();
70
71 const float *getSpectrumL() const {return m_normSpectrumL.data();}
72 const float *getSpectrumR() const {return m_normSpectrumR.data();}
73 const uchar *getHistory() const {return m_history.data();}
74
75 // information about results and unit conversion helpers
76 unsigned int inBlockSize() const {return m_inBlockSize;}
77 unsigned int binCount() const;
78 bool spectrumNotEmpty();
79
80 unsigned int waterfallWidth() const;
81 unsigned int waterfallHeight() const {return m_waterfallHeight;}
83
84 float binToFreq(unsigned int bin_index) const;
85 float binBandwidth() const;
86
87 float freqToXPixel(float frequency, unsigned int width) const;
88 float xPixelToFreq(float x, unsigned int width) const;
89
90 float ampToYPixel(float amplitude, unsigned int height) const;
91 float yPixelToAmp(float y, unsigned int height) const;
92
93 unsigned int getSampleRate() const;
94 float getNyquistFreq() const;
95
96 float getFreqRangeMin(bool linear = false) const;
97 float getFreqRangeMax() const;
98 float getAmpRangeMin(bool linear = false) const;
99 float getAmpRangeMax() const;
100
101 // Reallocation lock prevents the processor from changing size of its buffers.
102 // It is used to keep consistent bin-to-frequency mapping while drawing the
103 // spectrum and to make sure reading side does not find itself out of bounds.
104 // The processor is meanwhile free to work on another block.
106 // Data access lock prevents the processor from changing both size and content
107 // of its buffers. It is used when writing to a result buffer, or when a friendly
108 // class reads them and needs guaranteed data consistency.
109 // It causes FFT analysis to be paused, so this lock should be used sparingly.
110 // If using both locks at the same time, reallocation lock MUST be acquired first.
112
113
114private:
116
117 // thread communication and control
119
120 // currently valid configuration
121 unsigned int m_zeroPadFactor = 2;
122 std::atomic<unsigned int> m_inBlockSize;
123 unsigned int m_fftBlockSize;
124 unsigned int m_sampleRate;
125
126 // data buffers (roughly in the order of processing, from input to output)
127 unsigned int m_framesFilledUp;
128 std::vector<float> m_bufferL;
129 std::vector<float> m_bufferR;
130 std::vector<float> m_fftWindow;
131 std::vector<float> m_filteredBufferL;
132 std::vector<float> m_filteredBufferR;
133 fftwf_plan m_fftPlanL;
134 fftwf_plan m_fftPlanR;
135 fftwf_complex *m_spectrumL;
136 fftwf_complex *m_spectrumR;
137 std::vector<float> m_absSpectrumL;
138 std::vector<float> m_absSpectrumR;
139 std::vector<float> m_normSpectrumL;
140 std::vector<float> m_normSpectrumR;
141
142 // spectrum history for waterfall: new normSpectrum lines are added on top
143 std::vector<uchar> m_history_work;
144 std::vector<uchar> m_history;
146 std::atomic<unsigned int> m_waterfallHeight;
147 // Note: high values may make it harder to see transients.
148 const unsigned int m_waterfallMaxWidth = 3840;
149
150 // book keeping
153 std::atomic<unsigned int> m_waterfallNotEmpty;
155
156 // merge L and R channels and apply gamma correction to make a spectrogram pixel
157 QRgb makePixel(float left, float right) const;
158
159 #ifdef SA_DEBUG
160 unsigned int m_last_dump_time;
161 unsigned int m_dump_count;
162 float m_sum_execution;
163 float m_max_execution;
164 #endif
165};
166
167
168} // namespace lmms
169
170#endif // SAPROCESSOR_H
171
unsigned char uchar
Definition CarlaDefines.h:325
A convenience layer for a realtime-safe and thread-safe multi-reader ringbuffer.
Definition LocklessRingBuffer.h:41
Definition SaControls.h:48
unsigned int m_sampleRate
Definition SaProcessor.h:124
std::vector< float > m_normSpectrumL
frequency domain samples (normalized) (left)
Definition SaProcessor.h:139
fftwf_complex * m_spectrumR
frequency domain samples (complex) (right)
Definition SaProcessor.h:136
unsigned int inBlockSize() const
Definition SaProcessor.h:76
unsigned int waterfallHeight() const
Definition SaProcessor.h:81
std::atomic< unsigned int > m_waterfallNotEmpty
number of lines remaining visible on display
Definition SaProcessor.h:153
void terminate()
Definition SaProcessor.h:57
bool m_spectrumActive
Definition SaProcessor.h:151
float freqToXPixel(float frequency, unsigned int width) const
Definition SaProcessor.cpp:573
bool m_flipRequest
update public buffer only when requested
Definition SaProcessor.h:145
virtual ~SaProcessor()
Definition SaProcessor.cpp:85
const unsigned int m_waterfallMaxWidth
Definition SaProcessor.h:148
std::vector< float > m_filteredBufferR
time domain samples with window function applied (right)
Definition SaProcessor.h:132
std::vector< float > m_absSpectrumL
frequency domain samples (absolute) (left)
Definition SaProcessor.h:137
bool m_reallocating
Definition SaProcessor.h:154
const uchar * getHistory() const
Definition SaProcessor.h:73
float getAmpRangeMin(bool linear=false) const
Definition SaProcessor.cpp:613
void setWaterfallActive(bool active)
Definition SaProcessor.cpp:357
const SaControls * m_controls
Definition SaProcessor.h:115
unsigned int binCount() const
size of output (frequency domain) data block
Definition SaProcessor.cpp:508
std::atomic< unsigned int > m_inBlockSize
size of input (time domain) data block
Definition SaProcessor.h:122
fftwf_plan m_fftPlanL
Definition SaProcessor.h:133
std::atomic< unsigned int > m_waterfallHeight
number of stored lines in history buffer
Definition SaProcessor.h:146
fftwf_complex * m_spectrumL
frequency domain samples (complex) (left)
Definition SaProcessor.h:135
fftwf_plan m_fftPlanR
Definition SaProcessor.h:134
void analyze(LocklessRingBuffer< SampleFrame > &ring_buffer)
Definition SaProcessor.cpp:100
std::vector< uchar > m_history
public buffer for reading
Definition SaProcessor.h:144
const float * getSpectrumR() const
Definition SaProcessor.h:72
float binToFreq(unsigned int bin_index) const
Definition SaProcessor.cpp:526
QMutex m_dataAccess
Definition SaProcessor.h:111
float getFreqRangeMax() const
Definition SaProcessor.cpp:555
unsigned int m_fftBlockSize
size of padded block for FFT processing
Definition SaProcessor.h:123
float getNyquistFreq() const
Definition SaProcessor.cpp:500
float getAmpRangeMax() const
Definition SaProcessor.cpp:628
void reallocateBuffers()
Definition SaProcessor.cpp:364
bool waterfallNotEmpty() const
Definition SaProcessor.h:82
float getFreqRangeMin(bool linear=false) const
Definition SaProcessor.cpp:541
std::vector< float > m_bufferL
time domain samples (left)
Definition SaProcessor.h:128
void rebuildWindow()
Definition SaProcessor.cpp:442
unsigned int m_framesFilledUp
Definition SaProcessor.h:127
std::vector< float > m_absSpectrumR
frequency domain samples (absolute) (right)
Definition SaProcessor.h:138
bool m_waterfallActive
Definition SaProcessor.h:152
float xPixelToFreq(float x, unsigned int width) const
Definition SaProcessor.cpp:592
float ampToYPixel(float amplitude, unsigned int height) const
Definition SaProcessor.cpp:643
void flipRequest()
Definition SaProcessor.h:62
void clear()
Definition SaProcessor.cpp:452
std::vector< float > m_bufferR
time domain samples (right)
Definition SaProcessor.h:129
bool m_terminate
Definition SaProcessor.h:118
void setSpectrumActive(bool active)
Definition SaProcessor.cpp:352
unsigned int m_zeroPadFactor
use n-steps bigger FFT for given block size
Definition SaProcessor.h:121
float binBandwidth() const
Definition SaProcessor.cpp:535
bool spectrumNotEmpty()
check if result buffers contain any non-zero values
Definition SaProcessor.cpp:481
std::vector< float > m_filteredBufferL
time domain samples with window function applied (left)
Definition SaProcessor.h:131
std::vector< uchar > m_history_work
local history buffer for render
Definition SaProcessor.h:143
float yPixelToAmp(float y, unsigned int height) const
Definition SaProcessor.cpp:674
QRgb makePixel(float left, float right) const
Definition SaProcessor.cpp:328
unsigned int waterfallWidth() const
binCount value capped at 3840 (for display)
Definition SaProcessor.cpp:519
SaProcessor(const SaControls *controls)
Definition SaProcessor.cpp:50
const float * getSpectrumL() const
Definition SaProcessor.h:71
std::vector< float > m_fftWindow
precomputed window function coefficients
Definition SaProcessor.h:130
std::vector< float > m_normSpectrumR
frequency domain samples (normalized) (right)
Definition SaProcessor.h:140
QMutex m_reallocationAccess
Definition SaProcessor.h:105
unsigned int getSampleRate() const
Definition SaProcessor.cpp:493
void clearHistory()
Definition SaProcessor.cpp:474
Definition SampleFrame.h:41
int y
Definition inflate.c:1588
unsigned x[BMAX+1]
Definition inflate.c:1586
struct @113205115357366127300225113341150224053346037032::@137033172036070230260373056156374243321245367362 left
struct @113205115357366127300225113341150224053346037032::@137033172036070230260373056156374243321245367362 right
static int int height
Definition pugl.h:1594
static int width
Definition pugl.h:1593
Definition AudioAlsa.cpp:35