Skip to content

Commit

Permalink
Add visualiser for clipping algo (#54)
Browse files Browse the repository at this point in the history
  • Loading branch information
vvvar authored Jan 22, 2023
1 parent acbc3ff commit 01a2a86
Show file tree
Hide file tree
Showing 18 changed files with 452 additions and 203 deletions.
12 changes: 6 additions & 6 deletions .github/workflows/execute_merge_checks.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name: Execute nmerger checks
run-name: 'Merge checks for PR #${{ github.event.number }}'
run-name: "Merge checks for PR #${{ github.event.number }}"
on: pull_request
env:
BUILD_TYPE: Release
Expand All @@ -8,8 +8,8 @@ env:
LV2_TARGET_NAME: PeakEater_LV2
CLAP_TARGET_NAME: PeakEater_CLAP
JUCE_REVISION: 4e68af7
VERSION: 0.3.5
BUILD_ID: '${{ github.run_id }}.${{ github.run_number }}.${{ github.run_attempt }}'
VERSION: 0.4.0
BUILD_ID: "${{ github.run_id }}.${{ github.run_number }}.${{ github.run_attempt }}"
jobs:
macos:
name: macOS
Expand All @@ -31,7 +31,7 @@ jobs:
npm --version
which npm
- name: Install Python Dependencies
run: python -m pip install -r ${{github.workspace}}/requirements.txt
run: python -m pip install -r ${{github.workspace}}/requirements.txt
- name: Init Git Submodules
run: git submodule update --init --recursive
- name: Checkout JUCE
Expand Down Expand Up @@ -63,7 +63,7 @@ jobs:
run: git submodule update --init --recursive
- name: Checkout JUCE
run: cd ${{github.workspace}}\Dependencies\JUCE && git checkout ${{env.JUCE_REVISION}}
- name: Configure CMake
- name: Configure CMake
run: cmake . -B ${{github.workspace}}\build -G 'Visual Studio 17 2022' -A x64 -DCMAKE_EXPORT_COMPILE_COMMANDS=TRUE -DJUCE_BUILD_EXAMPLES=OFF -DJUCE_BUILD_EXTRAS=ON
- name: Build VST3
run: cmake --build ${{github.workspace}}\build --config ${{env.BUILD_TYPE}} --target ${{env.VST_TARGET_NAME}}
Expand Down Expand Up @@ -94,7 +94,7 @@ jobs:
sudo apt-get install libwebkit2gtk-4.0-37 libwebkit2gtk-4.0-dev
- name: Checkout JUCE
run: cd ${{github.workspace}}/Dependencies/JUCE && git checkout ${{env.JUCE_REVISION}}
- name: Configure CMake
- name: Configure CMake
run: cmake . -B ${{github.workspace}}/build -DCMAKE_EXPORT_COMPILE_COMMANDS=TRUE -DJUCE_BUILD_EXAMPLES=OFF -DJUCE_BUILD_EXTRAS=ON
- name: Build VST3
run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} --target ${{env.VST_TARGET_NAME}}
Expand Down
25 changes: 15 additions & 10 deletions .github/workflows/publish_release_draft.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name: Publish Release Draft
run-name: Create release draft for v0.3.5
run-name: Create release draft for v0.4.0
on:
push:
branches:
Expand All @@ -12,9 +12,9 @@ env:
LV2_TARGET_NAME: PeakEater_LV2
CLAP_TARGET_NAME: PeakEater_CLAP
JUCE_REVISION: 4e68af7
MACOS_RELEASE_NAME: PeakEater_v0.3.5_macOS
WINDOWS_RELEASE_NAME: PeakEater_v0.3.5_Windows
LINUX_RELEASE_NAME: PeakEater_v0.3.5_Linux
MACOS_RELEASE_NAME: PeakEater_v0.4.0_macOS
WINDOWS_RELEASE_NAME: PeakEater_v0.4.0_Windows
LINUX_RELEASE_NAME: PeakEater_v0.4.0_Linux
jobs:
macos:
name: macOS
Expand Down Expand Up @@ -81,12 +81,12 @@ jobs:
MACOS_APPLE_ID: ${{ secrets.MACOS_APPLE_ID }}
MACOS_APPLE_PASSWORD: ${{ secrets.MACOS_APPLE_PASSWORD }}
MACOS_APPLE_TEAM_ID: ${{ secrets.MACOS_APPLE_TEAM_ID }}
run: python ${{github.workspace}}/Scripts/Release/MacOS.py --release_type=${{env.BUILD_TYPE}} --sign_and_notarize=True --release_version=0.3.5
run: python ${{github.workspace}}/Scripts/Release/MacOS.py --release_type=${{env.BUILD_TYPE}} --sign_and_notarize=True --release_version=0.4.0
- name: Upload Artifacts
uses: actions/upload-artifact@v3
with:
name: ${{ env.MACOS_RELEASE_NAME }}
path: ${{github.workspace}}/build/release/PeakEater-0.3.5.dmg
path: ${{github.workspace}}/build/release/PeakEater-0.4.0.dmg

windows:
name: Windows
Expand All @@ -97,7 +97,7 @@ jobs:
run: git submodule update --init --recursive
- name: Checkout JUCE
run: cd ${{github.workspace}}\Dependencies\JUCE && git checkout ${{env.JUCE_REVISION}}
- name: Configure CMake
- name: Configure CMake
run: cmake . -B ${{github.workspace}}\build -G 'Visual Studio 17 2022' -A x64 -DCMAKE_EXPORT_COMPILE_COMMANDS=TRUE -DJUCE_BUILD_EXAMPLES=OFF -DJUCE_BUILD_EXTRAS=ON
- name: Build VST3
run: cmake --build ${{github.workspace}}\build --config ${{env.BUILD_TYPE}} --target ${{env.VST_TARGET_NAME}}
Expand Down Expand Up @@ -128,7 +128,7 @@ jobs:
sudo apt-get install libwebkit2gtk-4.0-37 libwebkit2gtk-4.0-dev
- name: Checkout JUCE
run: cd ${{github.workspace}}/Dependencies/JUCE && git checkout ${{env.JUCE_REVISION}}
- name: Configure CMake
- name: Configure CMake
run: cmake . -B ${{github.workspace}}/build -DCMAKE_EXPORT_COMPILE_COMMANDS=TRUE -DJUCE_BUILD_EXAMPLES=OFF -DJUCE_BUILD_EXTRAS=ON
- name: Build VST3
run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} --target ${{env.VST_TARGET_NAME}}
Expand All @@ -146,7 +146,7 @@ jobs:
${{github.workspace}}/build/PeakEater_artefacts/CLAP/PeakEater.clap
release:
name: Publish Release Draft
name: Publish Release Draft
runs-on: ubuntu-latest
needs: [macos, windows, linux]
steps:
Expand All @@ -168,6 +168,11 @@ jobs:
- name: Archive Artifacts
run: |
zip -r ${{ env.MACOS_RELEASE_NAME }}{.zip,}
mkdir ${{ env.WINDOWS_RELEASE_NAME }}/tmp
mv ${{ env.WINDOWS_RELEASE_NAME }}/VST3/PeakEater.vst3/Contents/x86_64-win/PeakEater.vst3 ${{ env.WINDOWS_RELEASE_NAME }}/tmp
rm -rf ${{ env.WINDOWS_RELEASE_NAME }}/VST3/PeakEater.vst3
mv ${{ env.WINDOWS_RELEASE_NAME }}/tmp/PeakEater.vst3 ${{ env.WINDOWS_RELEASE_NAME }}/VST3
rm -rf ${{ env.WINDOWS_RELEASE_NAME }}/tmp
zip -r ${{ env.WINDOWS_RELEASE_NAME }}{.zip,}
zip -r ${{ env.LINUX_RELEASE_NAME }}{.zip,}
- name: Display structure of downloaded files
Expand All @@ -178,5 +183,5 @@ jobs:
draft: true
removeArtifacts: true
makeLatest: true
tag: "v0.3.5"
tag: "v0.4.0"
artifacts: "${{ env.MACOS_RELEASE_NAME }}.zip,${{ env.WINDOWS_RELEASE_NAME }}.zip,${{ env.LINUX_RELEASE_NAME }}.zip"
5 changes: 4 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
cmake_minimum_required(VERSION 3.15)
project(PeakEater VERSION 0.3.5)
project(PeakEater VERSION 0.4.0)
set(CMAKE_CXX_STANDARD 20)

add_subdirectory(Dependencies/JUCE)
Expand Down Expand Up @@ -31,6 +31,9 @@ target_sources(PeakEater
Source/GUIv2/linkinout/LinkInOut.cpp
Source/GUIv2/bypass/BypassButton.cpp
Source/GUIv2/levelmeter/LevelMeterComponent.cpp
Source/GUIv2/analyser/peakanalyzer/PeakMeter.cpp
Source/GUIv2/analyser/peakanalyzer/PeakAnalyzerComponent.cpp
Source/GUIv2/analyser/cliptype/ClipTypeComponent.cpp
Source/GUIv2/analyser/AnalyserComponent.cpp
Source/GUIv2/ControlPanel.cpp
Source/GUIv2/LinkingPanel.cpp
Expand Down
23 changes: 15 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<p align="center">Free open-source VST3/AU/LV2/CLAP wave shaping plugin for macOS, Windows and Linux.</p>
<p align="center">
<a href="https://github.com/vvvar/PeakEater/releases/latest"><b>Download</b></a>
· <a target="_blank" href="https://github.com/vvvar/PeakEater/issues/new/choose"><b>Report Bug</b></a>
· <a target="_blank" href="https://github.com/vvvar/PeakEater/issues/new?assignees=&labels=Feature+Request&template=feature_request.md&title="><b>Request Feature</b></a> · <a target="_blank" href="https://github.com/vvvar/PeakEater/issues/new?assignees=&labels=Bug&template=bug_report.md&title=%5BBug%5D"><b>Report Bug</b></a>
</p>

![screenshot](Resources/screenshots/screenshot-mac.png)
Expand Down Expand Up @@ -33,18 +33,23 @@
<li><a href="#available-on-all-major-platforms">macOS, Windows and Linux Support</a></li>
</ul>
</li>
<li><a href="#installation">Installation</a></li>
<li>
<a href="#getting-started">Getting Started</a>
<a href="#installation">Installation</a>
<ul>
<li><a href="#macos">macOS</a></li>
<li><a href="#windows">Windows</a></li>
<li><a href="#linux">Linux</a></li>
</ul>
</li>
<li>
<a href="#building-from-sources">Building from sources</a>
<ul>
<li><a href="#prerequisites">Prerequisites</a></li>
<li><a href="#installation">Installation</a></li>
<li><a href="#build">Build</a></li>
</ul>
</li>
<li><a href="#contributing">Contributing</a></li>
<li><a href="#license">License</a></li>
<li><a href="#contact">Contact</a></li>
<li><a href="#donations">Donations</a></li>
<li><a href="#acknowledgements">Acknowledgements</a></li>
</ol>
</details>
Expand Down Expand Up @@ -91,7 +96,7 @@ See how your peaks were eaten with visualizer.

<img src="Resources/screenshots/screenshot-analyzer.png" alt="clip-analyzer" height="100"/>

Shows approximated RMS that was cut("Eaten") in last 2 seconds. Double-click to drop it to zero and force to re-calculate.
Shows approximated RMS that was cut("Eaten") in last 2 seconds and current clipping algorithm. Double-click on numbers to drop it to zero and force to re-calculate.

### 6 Clipping Types

Expand Down Expand Up @@ -193,14 +198,16 @@ Extract zip and copy plugin in format of choice into folder with your plugins.
<!-- GETTING STARTED -->

## Building the project from sources
## Building from sources

### Prerequisites

- [Git](https://git-scm.com) 2.39.0+
- [CMake](https://cmake.org) 3.15+
- [Python](https://www.python.org) 3.8.1+

### Build

Clone this repo:

```
Expand Down
Binary file modified Resources/screenshots/screenshot-analyzer.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified Resources/screenshots/screenshot-mac.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion Scripts/Release/configs/appdmg-config.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"title": "PeakEater v0.3.5",
"title": "PeakEater v0.4.0",
"icon": "icon-mac.icns",
"format": "ULFO",
"window": {
Expand Down
2 changes: 1 addition & 1 deletion Scripts/Release/configs/inno-config.iss
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[Setup]
AppName=PeakEater
AppVersion=0.3.5
AppVersion=0.4.0
DefaultDirName={cf}
DefaultGroupName=PeakEater
OutputBaseFilename=PeakEater-windows
Expand Down
2 changes: 1 addition & 1 deletion Scripts/Release/configs/wix-config.wxs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Product Id="*" UpgradeCode="12345678-1111-2222-3333-666666666666" Name="PeakEater" Version="0.3.5.0" Manufacturer="T-Audio" Language="1033">
<Product Id="*" UpgradeCode="12345678-1111-2222-3333-666666666666" Name="PeakEater" Version="0.4.0.0" Manufacturer="T-Audio" Language="1033">
<Package InstallerVersion="200" InstallScope="perMachine" Compressed="yes" Comments="PeakEater is a free open-source VST3/AU waveshaper plugin"/>
<MediaTemplate EmbedCab="yes" />

Expand Down
2 changes: 1 addition & 1 deletion Source/GUIv2/CentralPanel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ void CentralPanel::resized()
.withTrimmedRight (toRemoveFromSides));

mAnalyserComponent.setBounds(localBounds
.withWidth(localBounds.proportionOfWidth (0.17f))
.withWidth(localBounds.proportionOfWidth (0.28f))
.withHeight(localBounds.proportionOfHeight (0.155f))
.withX(localBounds.proportionOfWidth (0.1f))
.withY(localBounds.proportionOfHeight (0.05f)));
Expand Down
116 changes: 18 additions & 98 deletions Source/GUIv2/analyser/AnalyserComponent.cpp
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
#include "AnalyserComponent.h"

#include <JuceHeader.h>
#include <cmath>

#include "../Utils.h"
#include "../../DSP/ClippingFunctions.h"
#include "../ColourScheme.h"

namespace pe
Expand All @@ -11,34 +13,19 @@ namespace gui
{
namespace
{
// DSP configuration
int constexpr gAnalyzerSampleRateHz = 30;
float constexpr gMinDbValInOut = -36.0f;
float constexpr gMinDbValEaten = 0.0f;
// GUI configuration
int constexpr gBorderWidth = 1;
int constexpr gBorderRadius = 10;

template <typename T>
bool gIsInBounds (const T& value, const T& low, const T& high)
{
return !(value < low) && (value < high);
}
} // namespace
AnalyserComponent::AnalyserComponent (std::shared_ptr<juce::AudioProcessorValueTreeState> parameters,
std::shared_ptr<pe::dsp::LevelMeter<float> > inputLevelMeter,
std::shared_ptr<pe::dsp::LevelMeter<float> > clippingLevelMeter,
std::shared_ptr<pe::dsp::LevelMeter<float> > outputLevelMeter)
: mInputLevelMeter (inputLevelMeter)
, mClippingLevelMeter (clippingLevelMeter)
, mOutputLevelMeter (outputLevelMeter)
, mInputAnalyzer (gAnalyzerSampleRateHz, gMinDbValInOut)
, mOutputAnalyzer (gAnalyzerSampleRateHz, gMinDbValInOut)
, mEatenAnalyzer (gAnalyzerSampleRateHz, gMinDbValEaten)
, mAnalyzerUpdateTimer (std::bind (&AnalyserComponent::onAnalyzerUpdateTick, this))
: mClipTypeComponent(parameters)
, mPeakAnalyzerComponent(inputLevelMeter, clippingLevelMeter, outputLevelMeter)
{
setMouseCursor (juce::MouseCursor::PointingHandCursor);
mAnalyzerUpdateTimer.startTimerHz (gAnalyzerSampleRateHz);
addAndMakeVisible(mClipTypeComponent);
addAndMakeVisible(mPeakAnalyzerComponent);
}

AnalyserComponent::~AnalyserComponent()
Expand All @@ -48,90 +35,23 @@ AnalyserComponent::~AnalyserComponent()

void AnalyserComponent::resized()
{
juce::Grid grid;
using Track = juce::Grid::TrackInfo;
using Fr = juce::Grid::Fr;
using Item = juce::GridItem;
grid.templateRows = { Track (Fr (1)) };
grid.templateColumns = { Track (Fr (2)), Track (Fr (3)) };
grid.items = { Item (mClipTypeComponent), Item (mPeakAnalyzerComponent).withMargin({5, 0, 5, 2}) };
grid.performLayout (getLocalBounds());
}

void AnalyserComponent::paint (juce::Graphics& g)
{
drawLevels (mInputAnalyzer.getMagnitude(), mOutputAnalyzer.getMagnitude(), mEatenAnalyzer.getMagnitude(), g);
}

void AnalyserComponent::drawLevels (float inputLevel,
float outputLevel,
float eatenAmount,
juce::Graphics& g)
{
auto const bounds = getBounds().toFloat().reduced (gBorderWidth / 2);
auto const width = bounds.getWidth();
auto const height = bounds.getHeight();

int const poxX = 0;
int const posY = 0;
int const boxWidth = width;
int const boxHeight = height;
auto const fontSize = calculatePrimaryTextSize (getTopLevelComponent()->getBounds().getWidth(), getTopLevelComponent()->getBounds().getHeight());
auto const newlinePadding = fontSize * 0.7f;

juce::Colour borderColor = colourscheme::BackgroundSecondary;
juce::Colour backgroundColor = colourscheme::BackgroundSecondary.withAlpha(0.9f);
juce::Colour textColor = colourscheme::TextFocusLevel0;
if (!isEnabled())
{
textColor = colourscheme::TextFocusLevel3;
}

juce::Rectangle<float> area (poxX, posY, boxWidth, boxHeight);
area = area.reduced (gBorderWidth);
g.setColour (backgroundColor);
g.fillRoundedRectangle (area, gBorderRadius);
auto bounds = getLocalBounds().toFloat().reduced (gBorderWidth);
g.setColour (colourscheme::BackgroundSecondary.withAlpha(0.9f));
g.fillRoundedRectangle (bounds, gBorderRadius);
g.setColour (colourscheme::BackgroundTertiary.withAlpha(0.5f));
g.drawRoundedRectangle (area, gBorderRadius, gBorderWidth);

std::string const inputLevelText = "Input: " + gToStringWithPrecision (gRoundDb (inputLevel), 1) + " dB";
std::string const outLevelText = "Output: " + gToStringWithPrecision (gRoundDb (outputLevel), 1) + " dB";
std::string const eatenLevelText = "Eaten: " + gToStringWithPrecision (gRoundDb (eatenAmount), 1) + " dB";
g.setFont (fontSize);
g.setColour (textColor);
g.drawText (inputLevelText, poxX + newlinePadding, posY + newlinePadding, boxWidth, fontSize, juce::Justification::left, true);
g.drawText (outLevelText, poxX + newlinePadding, posY + newlinePadding + fontSize + newlinePadding, boxWidth, fontSize, juce::Justification::left, true);
if (gIsInBounds (eatenAmount, 5.0f, 10.0f))
{
g.setColour (colourscheme::Warning);
}
else if (gIsInBounds (eatenAmount, 10.0f, std::numeric_limits<float>::max()))
{
g.setColour (colourscheme::ForegroundSecondary);
}
else
{
g.setColour (textColor);
}
g.drawText (eatenLevelText, poxX + newlinePadding, posY + newlinePadding + (fontSize * 2) + (newlinePadding * 2), boxWidth, fontSize, juce::Justification::left, true);
}

void AnalyserComponent::mouseDown (juce::MouseEvent const& event)
{
if (event.getNumberOfClicks() == 2)
{
mInputAnalyzer.reset();
mOutputAnalyzer.reset();
mEatenAnalyzer.reset();
repaint();
} else if (event.getNumberOfClicks() == 4) // Only for debug, to show current version
{
std::string const lModalBoxTitle = std::string(ProjectInfo::projectName) + " by " + std::string(ProjectInfo::companyName);
std::string const lModalBoxText = "Version: " + std::string(ProjectInfo::versionString);
juce::NativeMessageBox::showMessageBoxAsync(juce::AlertWindow::InfoIcon, lModalBoxTitle, lModalBoxText, nullptr, nullptr);
}
}

void AnalyserComponent::onAnalyzerUpdateTick()
{
auto const inputLevel = static_cast<float> (mInputLevelMeter->getDecibels());
auto const outputLevel = static_cast<float> (mOutputLevelMeter->getDecibels());
auto const clippingLevel = static_cast<float> (mClippingLevelMeter->getDecibels());
mInputAnalyzer.push (inputLevel);
mOutputAnalyzer.push (outputLevel);
mEatenAnalyzer.push (inputLevel - clippingLevel);
g.drawRoundedRectangle (bounds, gBorderRadius, gBorderWidth);
}
} // namespace gui
} // namespace pe
Loading

0 comments on commit 01a2a86

Please sign in to comment.