diff --git a/DemoPlugin/PluginEditor.cpp b/DemoPlugin/PluginEditor.cpp index d2ac378..42a4012 100644 --- a/DemoPlugin/PluginEditor.cpp +++ b/DemoPlugin/PluginEditor.cpp @@ -2,10 +2,13 @@ //------------------------------------------------------------------------------------------------------- -SpectrumAnalyzerAudioProcessorEditor::SpectrumAnalyzerAudioProcessorEditor(juce::AudioProcessor &p, vsa::AudioBufferFifo &source) +SpectrumAnalyzerAudioProcessorEditor::SpectrumAnalyzerAudioProcessorEditor(juce::AudioProcessor &p, + vsa::AudioBufferFifo &source) : juce::AudioProcessorEditor(p) - , m_analyzer(source) + , m_thread("fft") + , m_analyzer(source, m_thread) { + m_thread.startThread(); setSize(1000, 400); addAndMakeVisible(m_analyzer); m_analyzer.startTimerHz(60); @@ -13,7 +16,11 @@ SpectrumAnalyzerAudioProcessorEditor::SpectrumAnalyzerAudioProcessorEditor(juce: //------------------------------------------------------------------------------------------------------- -SpectrumAnalyzerAudioProcessorEditor::~SpectrumAnalyzerAudioProcessorEditor() = default; +SpectrumAnalyzerAudioProcessorEditor::~SpectrumAnalyzerAudioProcessorEditor() +{ + m_thread.removeAllClients(); + m_thread.stopThread(100); +} //------------------------------------------------------------------------------------------------------- diff --git a/DemoPlugin/PluginEditor.h b/DemoPlugin/PluginEditor.h index 25c3dc6..3e04875 100644 --- a/DemoPlugin/PluginEditor.h +++ b/DemoPlugin/PluginEditor.h @@ -17,8 +17,8 @@ class SpectrumAnalyzerAudioProcessorEditor final : public juce::AudioProcessorEd void resized() override; private: + juce::TimeSliceThread m_thread; vsa::SpectrumAnalyzerComponent m_analyzer; }; //------------------------------------------------------------------------------------------------------- - diff --git a/Modules/vsa_spectrum_analyzer/SpectrumAnalyzer/SpectrumAnalyzer.cpp b/Modules/vsa_spectrum_analyzer/SpectrumAnalyzer/SpectrumAnalyzer.cpp index 0b0536e..079b16a 100644 --- a/Modules/vsa_spectrum_analyzer/SpectrumAnalyzer/SpectrumAnalyzer.cpp +++ b/Modules/vsa_spectrum_analyzer/SpectrumAnalyzer/SpectrumAnalyzer.cpp @@ -2,60 +2,46 @@ //----------------------------------------------------------------------------- -class vsa::SpectrumAnalyzer::SpectrumAnalyzerTimeSliceThread : public juce::TimeSliceThread -{ -public: - SpectrumAnalyzerTimeSliceThread() : juce::TimeSliceThread("fft") { startThread(); } - ~SpectrumAnalyzerTimeSliceThread() override { stopThread(100); } -}; - -//----------------------------------------------------------------------------- - void vsa::SpectrumAnalyzer::init() { const int fftSize = m_fft.getSize() * 2; const int stepSize = fftSize / static_cast(m_buffers.size()); - for(const auto &[index, buffer] : juce::enumerate(m_buffers)) + for (const auto &[index, buffer] : juce::enumerate(m_buffers)) { buffer.setSize(static_cast(fftSize)); const int writeSize = stepSize * static_cast(index); if (writeSize != 0) buffer.skip(writeSize); } - - m_thread->addTimeSliceClient(this); } //----------------------------------------------------------------------------- -vsa::SpectrumAnalyzer::SpectrumAnalyzer(vsa::AudioBufferFifo &source) +vsa::SpectrumAnalyzer::SpectrumAnalyzer(vsa::AudioBufferFifo &source, juce::TimeSliceThread &thread, int fftSize) : m_audioFifoFloat(&source) + , m_fft(fftSize) { + thread.addTimeSliceClient(this); init(); } //----------------------------------------------------------------------------- -vsa::SpectrumAnalyzer::SpectrumAnalyzer(vsa::AudioBufferFifo &source) +vsa::SpectrumAnalyzer::SpectrumAnalyzer(vsa::AudioBufferFifo &source, juce::TimeSliceThread &thread, int fftSize) : m_audioFifoDouble(&source) + , m_fft(fftSize) { + thread.addTimeSliceClient(this); init(); } //----------------------------------------------------------------------------- -vsa::SpectrumAnalyzer::~SpectrumAnalyzer() -{ - m_thread->removeTimeSliceClient(this); -} - -//----------------------------------------------------------------------------- - int vsa::SpectrumAnalyzer::useTimeSlice() { if (populateConduitBuffer()) { - for(auto &b : m_buffers) + for (auto &b : m_buffers) { b.write(m_conduitBuffer); @@ -63,7 +49,8 @@ int vsa::SpectrumAnalyzer::useTimeSlice() { auto fftSpan{ b.getFftSpan() }; - m_windowingFunction.multiplyWithWindowingTable(fftSpan.data(), std::min(fftSpan.size(), static_cast(m_fft.getSize()))); + m_windowingFunction.multiplyWithWindowingTable( + fftSpan.data(), std::min(fftSpan.size(), static_cast(m_fft.getSize()))); m_fft.performFrequencyOnlyForwardTransform(fftSpan.data()); m_analyzerCurve.pushCurve(fftSpan); @@ -75,21 +62,6 @@ int vsa::SpectrumAnalyzer::useTimeSlice() } //----------------------------------------------------------------------------- - -void vsa::SpectrumAnalyzer::startThread() -{ - m_thread->startThread(); -} - -//----------------------------------------------------------------------------- - -void vsa::SpectrumAnalyzer::suspendThread() -{ - m_thread->stopThread(100); -} - -//----------------------------------------------------------------------------- - bool vsa::SpectrumAnalyzer::populateConduitBuffer() { if (m_audioFifoFloat && m_audioFifoFloat->getAvailableSamples() > 0) @@ -128,7 +100,8 @@ bool vsa::SpectrumAnalyzer::populateConduitBuffer() vsa::SpectrumAnalyzerCurve::LockedCurve vsa::SpectrumAnalyzer::getAnalyzerCurve() { - m_analyzerCurve.setSampleRate(m_audioFifoFloat ? m_audioFifoFloat->getSampleRate() : m_audioFifoDouble->getSampleRate()); + m_analyzerCurve.setSampleRate(m_audioFifoFloat ? m_audioFifoFloat->getSampleRate() + : m_audioFifoDouble->getSampleRate()); return m_analyzerCurve.getCurve(); } diff --git a/Modules/vsa_spectrum_analyzer/SpectrumAnalyzer/SpectrumAnalyzer.h b/Modules/vsa_spectrum_analyzer/SpectrumAnalyzer/SpectrumAnalyzer.h index 7d3ac58..3d2a4a4 100644 --- a/Modules/vsa_spectrum_analyzer/SpectrumAnalyzer/SpectrumAnalyzer.h +++ b/Modules/vsa_spectrum_analyzer/SpectrumAnalyzer/SpectrumAnalyzer.h @@ -16,22 +16,21 @@ BEGIN_VSA_NAMESPACE /** * @class SpectrumAnalyzer * @brief runs an fft in a time slice thread over whatever data it gets -*/ + */ class SpectrumAnalyzer : public juce::TimeSliceClient { + class SpectrumAnalyzerTimeSliceThread; + public: - explicit SpectrumAnalyzer(AudioBufferFifo &source); - explicit SpectrumAnalyzer(AudioBufferFifo &source); - ~SpectrumAnalyzer() override; + explicit SpectrumAnalyzer(AudioBufferFifo &source, juce::TimeSliceThread &thread, int fftSize = 11); + explicit SpectrumAnalyzer(AudioBufferFifo &source, juce::TimeSliceThread &thread, int fftSize = 11); + ~SpectrumAnalyzer() override = default; SpectrumAnalyzerCurve::LockedCurve getAnalyzerCurve(); - + // juce::TimeSliceClient int useTimeSlice() override; - void startThread(); - void suspendThread(); - private: bool populateConduitBuffer(); void init(); @@ -44,15 +43,12 @@ class SpectrumAnalyzer : public juce::TimeSliceClient std::array m_buffers; - - juce::dsp::FFT m_fft{ 11 }; - juce::dsp::WindowingFunction m_windowingFunction{ static_cast(m_fft.getSize()), juce::dsp::WindowingFunction::hann, true }; + juce::dsp::FFT m_fft; + juce::dsp::WindowingFunction m_windowingFunction{ static_cast(m_fft.getSize()), + juce::dsp::WindowingFunction::hann, true }; SpectrumAnalyzerCurve m_analyzerCurve{ m_fft.getSize() }; - class SpectrumAnalyzerTimeSliceThread; - juce::SharedResourcePointer m_thread; - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(SpectrumAnalyzer) }; diff --git a/Modules/vsa_spectrum_analyzer/SpectrumAnalyzer/SpectrumAnalyzerComponent.cpp b/Modules/vsa_spectrum_analyzer/SpectrumAnalyzer/SpectrumAnalyzerComponent.cpp index d4c8c07..5c4ff85 100644 --- a/Modules/vsa_spectrum_analyzer/SpectrumAnalyzer/SpectrumAnalyzerComponent.cpp +++ b/Modules/vsa_spectrum_analyzer/SpectrumAnalyzer/SpectrumAnalyzerComponent.cpp @@ -3,15 +3,15 @@ //----------------------------------------------------------------------------- -vsa::SpectrumAnalyzerComponent::SpectrumAnalyzerComponent(AudioBufferFifo &source) - : m_fft(source) +vsa::SpectrumAnalyzerComponent::SpectrumAnalyzerComponent(AudioBufferFifo &source, juce::TimeSliceThread &thread, int fftSize) + : m_fft(source, thread, fftSize) { } //----------------------------------------------------------------------------- -vsa::SpectrumAnalyzerComponent::SpectrumAnalyzerComponent(AudioBufferFifo& source) - : m_fft(source) +vsa::SpectrumAnalyzerComponent::SpectrumAnalyzerComponent(AudioBufferFifo &source, juce::TimeSliceThread &thread, int fftSize) + : m_fft(source, thread, fftSize) { } @@ -41,14 +41,8 @@ float vsa::SpectrumAnalyzerComponent::getPreSmoothingPathHeightMultiplier(float void vsa::SpectrumAnalyzerComponent::paintAnalyzerCurve(juce::Graphics &g, const juce::Path &p) { - const auto gradient{ - juce::ColourGradient::vertical( - juce::Colours::red, - 0.0f, - juce::Colours::red.withAlpha(0.25f), - static_cast(getHeight()) - ) - }; + const auto gradient{ juce::ColourGradient::vertical(juce::Colours::red, 0.0f, juce::Colours::red.withAlpha(0.25f), + static_cast(getHeight())) }; g.setGradientFill(gradient); g.fillPath(p); diff --git a/Modules/vsa_spectrum_analyzer/SpectrumAnalyzer/SpectrumAnalyzerComponent.h b/Modules/vsa_spectrum_analyzer/SpectrumAnalyzer/SpectrumAnalyzerComponent.h index 80e6af9..966653f 100644 --- a/Modules/vsa_spectrum_analyzer/SpectrumAnalyzer/SpectrumAnalyzerComponent.h +++ b/Modules/vsa_spectrum_analyzer/SpectrumAnalyzer/SpectrumAnalyzerComponent.h @@ -16,14 +16,14 @@ BEGIN_VSA_NAMESPACE * @brief Display a spectrum analyzer from data grabbed from AudioBufferFifo * * @see AudioBufferFifo -*/ + */ class SpectrumAnalyzerComponent : public juce::Component , public juce::Timer { public: - explicit SpectrumAnalyzerComponent(AudioBufferFifo &source); - explicit SpectrumAnalyzerComponent(AudioBufferFifo &source); + explicit SpectrumAnalyzerComponent(AudioBufferFifo &source, juce::TimeSliceThread &thread, int fftSize = 11); + explicit SpectrumAnalyzerComponent(AudioBufferFifo &source, juce::TimeSliceThread &thread, int fftSize = 11); ~SpectrumAnalyzerComponent() override; void paint(juce::Graphics &g) override; diff --git a/Modules/vsa_spectrum_analyzer/SpectrumAnalyzer/SpectrumAnalyzerCurve.cpp b/Modules/vsa_spectrum_analyzer/SpectrumAnalyzer/SpectrumAnalyzerCurve.cpp index c5f09bb..2848726 100644 --- a/Modules/vsa_spectrum_analyzer/SpectrumAnalyzer/SpectrumAnalyzerCurve.cpp +++ b/Modules/vsa_spectrum_analyzer/SpectrumAnalyzer/SpectrumAnalyzerCurve.cpp @@ -41,7 +41,7 @@ static float getParameterValueFromFrequency(const float frequency) const float num = std::log(frequency - MinFrequency); const float den = std::log(MaxFrequency - MinFrequency); - return std::powf(num / den, 2.0f); + return std::pow(num / den, 2.0f); } //----------------------------------------------------------------------------- diff --git a/README.md b/README.md index 12f169a..b3d3189 100644 --- a/README.md +++ b/README.md @@ -20,3 +20,22 @@ m_fifo.pushAudioData(buffer); // push all audio data into the fifo vsa::SpectrumAnalyzerComponent spectrumAnalyzer{ fifo }; addAndMakeVisible(spectrumAnalyzer); ``` + +# Adding it to Your Project + +SpectrumAnalyzer is organized as a JUCE module. +To use it in your project include the `Modules` directory in `CMakeLists.txt`: + +```cmake +add_subdirectory("SpectrumAnalyzer/Modules") +``` + +Link to the following targets: + +```cmake +target_link_libraries("Project" + PRIVATE + vsa::vsa + vsa::vsa_spectrum_analyzer +) +``` diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt index fbd409a..39cdfda 100644 --- a/Tests/CMakeLists.txt +++ b/Tests/CMakeLists.txt @@ -11,6 +11,13 @@ FetchContent_MakeAvailable(gtest) add_executable(Tests Tests.cpp) +target_compile_definitions( + Tests + PUBLIC + JUCE_WEB_BROWSER=0 + JUCE_USE_CURL=0 +) + target_link_libraries( Tests diff --git a/Tests/SpectrumAnalyzerTests.h b/Tests/SpectrumAnalyzerTests.h index 1485ad0..b77ea63 100644 --- a/Tests/SpectrumAnalyzerTests.h +++ b/Tests/SpectrumAnalyzerTests.h @@ -199,10 +199,10 @@ TEST(SpectrumAnalyzerTests, SpectrumAnalyzerBufferTest) float f{ 0.0f }; int loopCount2{ Size }; - for(auto f : fftSpan) + for(auto ff : fftSpan) { loopCount2--; - EXPECT_EQ(f, f); + EXPECT_EQ(ff, f); f += 1.0f; } EXPECT_EQ(loopCount2, 0);