├── .gitignore
├── Builds
├── MacOSX
│ ├── DSP Testbench.entitlements
│ ├── DSP Testbench.xcodeproj
│ │ └── project.pbxproj
│ ├── Info-App.plist
│ └── RecentFilesMenuTemplate.nib
└── VisualStudio2022
│ ├── DSP Testbench.sln
│ ├── DSP Testbench_App.vcxproj
│ ├── DSP Testbench_App.vcxproj.filters
│ ├── cpp.hint
│ └── resources.rc
├── DSP Testbench.jucer
├── JuceLibraryCode
├── AppConfig.h
├── BinaryData.cpp
├── BinaryData.h
├── JuceHeader.h
├── ReadMe.txt
├── include_juce_audio_basics.cpp
├── include_juce_audio_basics.mm
├── include_juce_audio_devices.cpp
├── include_juce_audio_devices.mm
├── include_juce_audio_formats.cpp
├── include_juce_audio_formats.mm
├── include_juce_audio_processors.cpp
├── include_juce_audio_processors.mm
├── include_juce_audio_processors_ara.cpp
├── include_juce_audio_processors_lv2_libs.cpp
├── include_juce_audio_utils.cpp
├── include_juce_audio_utils.mm
├── include_juce_core.cpp
├── include_juce_core.mm
├── include_juce_core_CompilationTime.cpp
├── include_juce_data_structures.cpp
├── include_juce_data_structures.mm
├── include_juce_dsp.cpp
├── include_juce_dsp.mm
├── include_juce_events.cpp
├── include_juce_events.mm
├── include_juce_graphics.cpp
├── include_juce_graphics.mm
├── include_juce_graphics_Harfbuzz.cpp
├── include_juce_graphics_Sheenbidi.c
├── include_juce_gui_basics.cpp
├── include_juce_gui_basics.mm
├── include_juce_gui_extra.cpp
├── include_juce_gui_extra.mm
├── include_juce_opengl.cpp
└── include_juce_opengl.mm
├── LICENSE
├── README.md
├── Resources
├── about.svg
├── audio_settings.svg
├── configure.svg
├── dashboard_gauge.svg
├── expand.svg
├── mute.svg
├── pause.svg
├── phase_invert.svg
├── play.svg
└── screenshot.svg
├── Source
├── GUI
│ ├── AboutComponent.cpp
│ ├── AboutComponent.h
│ ├── AnalyserComponent.cpp
│ ├── AnalyserComponent.h
│ ├── BenchmarkComponent.cpp
│ ├── BenchmarkComponent.h
│ ├── FftScope.h
│ ├── Goniometer.cpp
│ ├── Goniometer.h
│ ├── LookAndFeel.cpp
│ ├── LookAndFeel.h
│ ├── MainComponent.cpp
│ ├── MainComponent.h
│ ├── MenuBarComponent.cpp
│ ├── MenuBarComponent.h
│ ├── MeteringComponents.cpp
│ ├── MeteringComponents.h
│ ├── MonitoringComponent.cpp
│ ├── MonitoringComponent.h
│ ├── Oscilloscope.cpp
│ ├── Oscilloscope.h
│ ├── ProcessorComponent.cpp
│ ├── ProcessorComponent.h
│ ├── SourceComponent.cpp
│ └── SourceComponent.h
├── Main.cpp
├── Main.h
└── Processing
│ ├── AudioDataTransfer.h
│ ├── AudioScopeProcessor.h
│ ├── FastApproximations.h
│ ├── FftProcessor.h
│ ├── MeteringProcessors.cpp
│ ├── MeteringProcessors.h
│ ├── NoiseGenerators.h
│ ├── PolyBLEP.h
│ ├── ProcessorExamples.cpp
│ ├── ProcessorExamples.h
│ ├── ProcessorHarness.cpp
│ ├── ProcessorHarness.h
│ └── PulseFunctions.h
└── screenshot.png
/.gitignore:
--------------------------------------------------------------------------------
1 | ################################################################################################
2 | # JUCE standard .gitignore
3 | ################################################################################################
4 | ._*
5 | *.mode1v3
6 | *.pbxuser
7 | *.perspectivev3
8 | *.user
9 | *.ncb
10 | *.suo
11 | *.ilk
12 | *.pch
13 | *.pdb
14 | *.dep
15 | *.idb
16 | *.manifest
17 | *.manifest.res
18 | *.o
19 | *.d
20 | *.sdf
21 | *.opensdf
22 | *.VC.db
23 | *.VC.opendb
24 | xcuserdata
25 | *.xccheckout
26 | *.xcscmblueprint
27 | *.xcscheme
28 | contents.xcworkspacedata
29 | .DS_Store
30 | .svn
31 | .deps
32 | .dirstamp
33 | profile
34 | **/MacOSX/build
35 | **/iOS/build
36 | **/IDEWorkspaceChecks.plist
37 | **/Linux/build
38 | **/LinuxMakefile/build
39 | **/VisualStudio[0-9]*/Win32
40 | **/VisualStudio[0-9]*/x64
41 | **/Builds/x64
42 | **/.vs
43 | **/CodeBlocks/bin
44 | **/CodeBlocks/obj
45 | **/CodeBlocks/*.depend
46 | **/CodeBlocks/*.layout
47 | **/Builds/Android/.gradle
48 | **/Builds/Android/.idea
49 | **/Builds/Android/build
50 | **/Builds/Android/**/*.iml
51 | **/Builds/Android/local.properties
52 | **/Builds/Android/app/build
53 | **/Builds/Android/app/.externalNativeBuild
54 | **/Builds/Android/app/.cxx
55 | **/Builds/Android/lib/build
56 | **/Builds/Android/lib/.externalNativeBuild
57 | **/Builds/CLion/cmake-build-*
58 | **/Builds/CLion/.idea
59 | **/Builds/MacOSX/**/Index
60 | **/Builds/MacOSX/**/Intermediates.noindex
61 | **/doxygen/doc
62 | **/doxygen/build
63 | **/.idea
64 | extras/Projucer/JUCECompileEngine.dylib
65 |
66 | .idea
67 | **/cmake-build*
68 |
69 | .vscode
70 | /build
--------------------------------------------------------------------------------
/Builds/MacOSX/DSP Testbench.entitlements:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/Builds/MacOSX/Info-App.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | CFBundleExecutable
7 | ${EXECUTABLE_NAME}
8 | CFBundleIconFile
9 |
10 | CFBundleIdentifier
11 | com.yourcompany.DSPTestbench
12 | CFBundleName
13 | DSP Testbench
14 | CFBundleDisplayName
15 | DSP Testbench
16 | CFBundlePackageType
17 | APPL
18 | CFBundleSignature
19 | ????
20 | CFBundleShortVersionString
21 | 1.1.0
22 | CFBundleVersion
23 | 1.1.0
24 | NSHumanReadableCopyright
25 |
26 | NSHighResolutionCapable
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/Builds/MacOSX/RecentFilesMenuTemplate.nib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AndrewJJ/DSP-Testbench/124080107531336827cfbe153c92a8d5676d2bc3/Builds/MacOSX/RecentFilesMenuTemplate.nib
--------------------------------------------------------------------------------
/Builds/VisualStudio2022/DSP Testbench.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 11.00
3 | # Visual Studio Version 17
4 |
5 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DSP Testbench - App", "DSP Testbench_App.vcxproj", "{E94EA53F-B63F-A591-817A-2D8CDB81386C}"
6 | EndProject
7 | Global
8 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
9 | Debug|x64 = Debug|x64
10 | Release|x64 = Release|x64
11 | EndGlobalSection
12 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
13 | {E94EA53F-B63F-A591-817A-2D8CDB81386C}.Debug|x64.ActiveCfg = Debug|x64
14 | {E94EA53F-B63F-A591-817A-2D8CDB81386C}.Debug|x64.Build.0 = Debug|x64
15 | {E94EA53F-B63F-A591-817A-2D8CDB81386C}.Release|x64.ActiveCfg = Release|x64
16 | {E94EA53F-B63F-A591-817A-2D8CDB81386C}.Release|x64.Build.0 = Release|x64
17 | EndGlobalSection
18 | GlobalSection(SolutionProperties) = preSolution
19 | HideSolutionNode = FALSE
20 | EndGlobalSection
21 | EndGlobal
22 |
--------------------------------------------------------------------------------
/Builds/VisualStudio2022/cpp.hint:
--------------------------------------------------------------------------------
1 | // Hint files help the Visual Studio IDE interpret Visual C++ identifiers
2 | // such as names of functions and macros.
3 | // For more information see https://go.microsoft.com/fwlink/?linkid=865984
4 | #define JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(className) JUCE_DECLARE_NON_COPYABLE(className) JUCE_LEAK_DETECTOR(className)
5 |
--------------------------------------------------------------------------------
/Builds/VisualStudio2022/resources.rc:
--------------------------------------------------------------------------------
1 | #pragma code_page(65001)
2 |
3 | #ifdef JUCE_USER_DEFINED_RC_FILE
4 | #include JUCE_USER_DEFINED_RC_FILE
5 | #else
6 |
7 | #undef WIN32_LEAN_AND_MEAN
8 | #define WIN32_LEAN_AND_MEAN
9 | #include
10 |
11 | VS_VERSION_INFO VERSIONINFO
12 | FILEVERSION 1,1,0,0
13 | BEGIN
14 | BLOCK "StringFileInfo"
15 | BEGIN
16 | BLOCK "040904E4"
17 | BEGIN
18 | VALUE "FileDescription", "DSP Testbench\0"
19 | VALUE "FileVersion", "1.1.0\0"
20 | VALUE "ProductName", "DSP Testbench\0"
21 | VALUE "ProductVersion", "1.1.0\0"
22 | END
23 | END
24 |
25 | BLOCK "VarFileInfo"
26 | BEGIN
27 | VALUE "Translation", 0x409, 1252
28 | END
29 | END
30 |
31 | #endif
32 |
--------------------------------------------------------------------------------
/DSP Testbench.jucer:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
6 |
7 |
8 |
10 |
11 |
13 |
14 |
15 |
16 |
17 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
27 |
29 |
31 |
33 |
35 |
37 |
38 |
39 |
40 |
41 |
42 |
44 |
45 |
47 |
49 |
51 |
53 |
55 |
57 |
59 |
60 |
62 |
64 |
66 |
68 |
69 |
70 |
72 |
74 |
76 |
77 |
79 |
81 |
83 |
84 |
86 |
88 |
90 |
92 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
--------------------------------------------------------------------------------
/JuceLibraryCode/AppConfig.h:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | IMPORTANT! This file is auto-generated each time you save your
4 | project - if you alter its contents, your changes may be overwritten!
5 |
6 | There's a section below where you can add your own custom code safely, and the
7 | Projucer will preserve the contents of that block, but the best way to change
8 | any of these definitions is by using the Projucer's project settings.
9 |
10 | Any commented-out settings will assume their default values.
11 |
12 | */
13 |
14 | #pragma once
15 |
16 | //==============================================================================
17 | // [BEGIN_USER_CODE_SECTION]
18 |
19 | // (You can add your own code in this section, and the Projucer will not overwrite it)
20 |
21 | #ifndef GUI_BASE_SIZE
22 | #define GUI_BASE_SIZE 30.0
23 | #endif
24 |
25 | #ifndef GUI_BASE_SIZE_I
26 | #define GUI_BASE_SIZE_I static_cast (GUI_BASE_SIZE)
27 | #endif
28 |
29 | #ifndef GUI_BASE_SIZE_F
30 | #define GUI_BASE_SIZE_F static_cast (GUI_BASE_SIZE)
31 | #endif
32 |
33 | #ifndef GUI_BASE_SIZE_PX
34 | #define GUI_BASE_SIZE_PX Grid::Px (GUI_BASE_SIZE_I)
35 | #endif
36 |
37 | #ifndef GUI_SIZE
38 | #define GUI_SIZE(N) GUI_BASE_SIZE * (N) // Note that the brackets around the N are needed so that any calculations within the argument are performed correctly
39 | #endif
40 |
41 | #ifndef GUI_SIZE_I
42 | #define GUI_SIZE_I(N) static_cast (GUI_SIZE(N))
43 | #endif
44 |
45 | #ifndef GUI_SIZE_F
46 | #define GUI_SIZE_F(N) static_cast (GUI_SIZE(N))
47 | #endif
48 |
49 | #ifndef GUI_SIZE_PX
50 | #define GUI_SIZE_PX(N) Grid::Px (GUI_SIZE_I(N))
51 | #endif
52 |
53 | #ifndef GUI_BASE_GAP
54 | #define GUI_BASE_GAP 5.0
55 | #endif
56 |
57 | #ifndef GUI_BASE_GAP_I
58 | #define GUI_BASE_GAP_I static_cast (GUI_BASE_GAP)
59 | #endif
60 |
61 | #ifndef GUI_BASE_GAP_F
62 | #define GUI_BASE_GAP_F static_cast (GUI_BASE_GAP)
63 | #endif
64 |
65 | #ifndef GUI_BASE_GAP_PX
66 | #define GUI_BASE_GAP_PX Grid::Px (GUI_BASE_GAP_I)
67 | #endif
68 |
69 | #ifndef GUI_GAP
70 | #define GUI_GAP(N) GUI_BASE_GAP * (N) // Note that the brackets around the N are needed so that any calculations within the argument are performed correctly
71 | #endif
72 |
73 | #ifndef GUI_GAP_I
74 | #define GUI_GAP_I(N) static_cast (GUI_GAP(N))
75 | #endif
76 |
77 | #ifndef GUI_GAP_F
78 | #define GUI_GAP_F(N) static_cast (GUI_GAP(N))
79 | #endif
80 |
81 | #ifndef GUI_GAP_PX
82 | #define GUI_GAP_PX(N) Grid::Px (GUI_GAP_I(N))
83 | #endif
84 |
85 |
86 | // [END_USER_CODE_SECTION]
87 |
88 | #define JUCE_PROJUCER_VERSION 0x80006
89 |
90 | //==============================================================================
91 | #define JUCE_MODULE_AVAILABLE_juce_audio_basics 1
92 | #define JUCE_MODULE_AVAILABLE_juce_audio_devices 1
93 | #define JUCE_MODULE_AVAILABLE_juce_audio_formats 1
94 | #define JUCE_MODULE_AVAILABLE_juce_audio_processors 1
95 | #define JUCE_MODULE_AVAILABLE_juce_audio_utils 1
96 | #define JUCE_MODULE_AVAILABLE_juce_core 1
97 | #define JUCE_MODULE_AVAILABLE_juce_data_structures 1
98 | #define JUCE_MODULE_AVAILABLE_juce_dsp 1
99 | #define JUCE_MODULE_AVAILABLE_juce_events 1
100 | #define JUCE_MODULE_AVAILABLE_juce_graphics 1
101 | #define JUCE_MODULE_AVAILABLE_juce_gui_basics 1
102 | #define JUCE_MODULE_AVAILABLE_juce_gui_extra 1
103 | #define JUCE_MODULE_AVAILABLE_juce_opengl 1
104 |
105 | #define JUCE_GLOBAL_MODULE_SETTINGS_INCLUDED 1
106 |
107 | //==============================================================================
108 | // juce_audio_devices flags:
109 |
110 | #ifndef JUCE_USE_WINRT_MIDI
111 | //#define JUCE_USE_WINRT_MIDI 0
112 | #endif
113 |
114 | #ifndef JUCE_ASIO
115 | #define JUCE_ASIO 1
116 | #endif
117 |
118 | #ifndef JUCE_WASAPI
119 | //#define JUCE_WASAPI 1
120 | #endif
121 |
122 | #ifndef JUCE_DIRECTSOUND
123 | //#define JUCE_DIRECTSOUND 1
124 | #endif
125 |
126 | #ifndef JUCE_ALSA
127 | //#define JUCE_ALSA 1
128 | #endif
129 |
130 | #ifndef JUCE_JACK
131 | //#define JUCE_JACK 0
132 | #endif
133 |
134 | #ifndef JUCE_BELA
135 | //#define JUCE_BELA 0
136 | #endif
137 |
138 | #ifndef JUCE_USE_ANDROID_OBOE
139 | //#define JUCE_USE_ANDROID_OBOE 1
140 | #endif
141 |
142 | #ifndef JUCE_USE_OBOE_STABILIZED_CALLBACK
143 | //#define JUCE_USE_OBOE_STABILIZED_CALLBACK 0
144 | #endif
145 |
146 | #ifndef JUCE_USE_ANDROID_OPENSLES
147 | //#define JUCE_USE_ANDROID_OPENSLES 0
148 | #endif
149 |
150 | #ifndef JUCE_DISABLE_AUDIO_MIXING_WITH_OTHER_APPS
151 | //#define JUCE_DISABLE_AUDIO_MIXING_WITH_OTHER_APPS 0
152 | #endif
153 |
154 | //==============================================================================
155 | // juce_audio_formats flags:
156 |
157 | #ifndef JUCE_USE_FLAC
158 | //#define JUCE_USE_FLAC 1
159 | #endif
160 |
161 | #ifndef JUCE_USE_OGGVORBIS
162 | //#define JUCE_USE_OGGVORBIS 1
163 | #endif
164 |
165 | #ifndef JUCE_USE_MP3AUDIOFORMAT
166 | //#define JUCE_USE_MP3AUDIOFORMAT 0
167 | #endif
168 |
169 | #ifndef JUCE_USE_LAME_AUDIO_FORMAT
170 | //#define JUCE_USE_LAME_AUDIO_FORMAT 0
171 | #endif
172 |
173 | #ifndef JUCE_USE_WINDOWS_MEDIA_FORMAT
174 | //#define JUCE_USE_WINDOWS_MEDIA_FORMAT 1
175 | #endif
176 |
177 | //==============================================================================
178 | // juce_audio_processors flags:
179 |
180 | #ifndef JUCE_PLUGINHOST_VST
181 | //#define JUCE_PLUGINHOST_VST 0
182 | #endif
183 |
184 | #ifndef JUCE_PLUGINHOST_VST3
185 | //#define JUCE_PLUGINHOST_VST3 0
186 | #endif
187 |
188 | #ifndef JUCE_PLUGINHOST_AU
189 | //#define JUCE_PLUGINHOST_AU 0
190 | #endif
191 |
192 | #ifndef JUCE_PLUGINHOST_LADSPA
193 | //#define JUCE_PLUGINHOST_LADSPA 0
194 | #endif
195 |
196 | #ifndef JUCE_PLUGINHOST_LV2
197 | //#define JUCE_PLUGINHOST_LV2 0
198 | #endif
199 |
200 | #ifndef JUCE_PLUGINHOST_ARA
201 | //#define JUCE_PLUGINHOST_ARA 0
202 | #endif
203 |
204 | #ifndef JUCE_CUSTOM_VST3_SDK
205 | //#define JUCE_CUSTOM_VST3_SDK 0
206 | #endif
207 |
208 | //==============================================================================
209 | // juce_audio_utils flags:
210 |
211 | #ifndef JUCE_USE_CDREADER
212 | //#define JUCE_USE_CDREADER 0
213 | #endif
214 |
215 | #ifndef JUCE_USE_CDBURNER
216 | //#define JUCE_USE_CDBURNER 0
217 | #endif
218 |
219 | //==============================================================================
220 | // juce_core flags:
221 |
222 | #ifndef JUCE_FORCE_DEBUG
223 | //#define JUCE_FORCE_DEBUG 0
224 | #endif
225 |
226 | #ifndef JUCE_LOG_ASSERTIONS
227 | //#define JUCE_LOG_ASSERTIONS 0
228 | #endif
229 |
230 | #ifndef JUCE_CHECK_MEMORY_LEAKS
231 | //#define JUCE_CHECK_MEMORY_LEAKS 1
232 | #endif
233 |
234 | #ifndef JUCE_DONT_AUTOLINK_TO_WIN32_LIBRARIES
235 | //#define JUCE_DONT_AUTOLINK_TO_WIN32_LIBRARIES 0
236 | #endif
237 |
238 | #ifndef JUCE_INCLUDE_ZLIB_CODE
239 | //#define JUCE_INCLUDE_ZLIB_CODE 1
240 | #endif
241 |
242 | #ifndef JUCE_USE_CURL
243 | //#define JUCE_USE_CURL 1
244 | #endif
245 |
246 | #ifndef JUCE_LOAD_CURL_SYMBOLS_LAZILY
247 | //#define JUCE_LOAD_CURL_SYMBOLS_LAZILY 0
248 | #endif
249 |
250 | #ifndef JUCE_CATCH_UNHANDLED_EXCEPTIONS
251 | //#define JUCE_CATCH_UNHANDLED_EXCEPTIONS 0
252 | #endif
253 |
254 | #ifndef JUCE_ALLOW_STATIC_NULL_VARIABLES
255 | //#define JUCE_ALLOW_STATIC_NULL_VARIABLES 0
256 | #endif
257 |
258 | #ifndef JUCE_STRICT_REFCOUNTEDPOINTER
259 | //#define JUCE_STRICT_REFCOUNTEDPOINTER 0
260 | #endif
261 |
262 | #ifndef JUCE_ENABLE_ALLOCATION_HOOKS
263 | //#define JUCE_ENABLE_ALLOCATION_HOOKS 0
264 | #endif
265 |
266 | //==============================================================================
267 | // juce_dsp flags:
268 |
269 | #ifndef JUCE_ASSERTION_FIRFILTER
270 | //#define JUCE_ASSERTION_FIRFILTER 1
271 | #endif
272 |
273 | #ifndef JUCE_DSP_USE_INTEL_MKL
274 | //#define JUCE_DSP_USE_INTEL_MKL 0
275 | #endif
276 |
277 | #ifndef JUCE_DSP_USE_SHARED_FFTW
278 | //#define JUCE_DSP_USE_SHARED_FFTW 0
279 | #endif
280 |
281 | #ifndef JUCE_DSP_USE_STATIC_FFTW
282 | //#define JUCE_DSP_USE_STATIC_FFTW 0
283 | #endif
284 |
285 | #ifndef JUCE_DSP_ENABLE_SNAP_TO_ZERO
286 | //#define JUCE_DSP_ENABLE_SNAP_TO_ZERO 1
287 | #endif
288 |
289 | //==============================================================================
290 | // juce_events flags:
291 |
292 | #ifndef JUCE_EXECUTE_APP_SUSPEND_ON_BACKGROUND_TASK
293 | //#define JUCE_EXECUTE_APP_SUSPEND_ON_BACKGROUND_TASK 0
294 | #endif
295 |
296 | //==============================================================================
297 | // juce_graphics flags:
298 |
299 | #ifndef JUCE_USE_COREIMAGE_LOADER
300 | //#define JUCE_USE_COREIMAGE_LOADER 1
301 | #endif
302 |
303 | #ifndef JUCE_DISABLE_COREGRAPHICS_FONT_SMOOTHING
304 | //#define JUCE_DISABLE_COREGRAPHICS_FONT_SMOOTHING 0
305 | #endif
306 |
307 | //==============================================================================
308 | // juce_gui_basics flags:
309 |
310 | #ifndef JUCE_ENABLE_REPAINT_DEBUGGING
311 | //#define JUCE_ENABLE_REPAINT_DEBUGGING 0
312 | #endif
313 |
314 | #ifndef JUCE_USE_XRANDR
315 | //#define JUCE_USE_XRANDR 1
316 | #endif
317 |
318 | #ifndef JUCE_USE_XINERAMA
319 | //#define JUCE_USE_XINERAMA 1
320 | #endif
321 |
322 | #ifndef JUCE_USE_XSHM
323 | //#define JUCE_USE_XSHM 1
324 | #endif
325 |
326 | #ifndef JUCE_USE_XRENDER
327 | //#define JUCE_USE_XRENDER 0
328 | #endif
329 |
330 | #ifndef JUCE_USE_XCURSOR
331 | //#define JUCE_USE_XCURSOR 1
332 | #endif
333 |
334 | #ifndef JUCE_WIN_PER_MONITOR_DPI_AWARE
335 | //#define JUCE_WIN_PER_MONITOR_DPI_AWARE 1
336 | #endif
337 |
338 | //==============================================================================
339 | // juce_gui_extra flags:
340 |
341 | #ifndef JUCE_WEB_BROWSER
342 | //#define JUCE_WEB_BROWSER 1
343 | #endif
344 |
345 | #ifndef JUCE_USE_WIN_WEBVIEW2_WITH_STATIC_LINKING
346 | //#define JUCE_USE_WIN_WEBVIEW2_WITH_STATIC_LINKING 0
347 | #endif
348 |
349 | #ifndef JUCE_USE_WIN_WEBVIEW2
350 | //#define JUCE_USE_WIN_WEBVIEW2 0
351 | #endif
352 |
353 | #ifndef JUCE_ENABLE_LIVE_CONSTANT_EDITOR
354 | //#define JUCE_ENABLE_LIVE_CONSTANT_EDITOR 0
355 | #endif
356 |
357 | //==============================================================================
358 | #ifndef JUCE_STANDALONE_APPLICATION
359 | #if defined(JucePlugin_Name) && defined(JucePlugin_Build_Standalone)
360 | #define JUCE_STANDALONE_APPLICATION JucePlugin_Build_Standalone
361 | #else
362 | #define JUCE_STANDALONE_APPLICATION 1
363 | #endif
364 | #endif
365 |
--------------------------------------------------------------------------------
/JuceLibraryCode/BinaryData.h:
--------------------------------------------------------------------------------
1 | /* =========================================================================================
2 |
3 | This is an auto-generated file: Any edits you make may be overwritten!
4 |
5 | */
6 |
7 | #pragma once
8 |
9 | namespace BinaryData
10 | {
11 | extern const char* about_svg;
12 | const int about_svgSize = 1108;
13 |
14 | extern const char* audio_settings_svg;
15 | const int audio_settings_svgSize = 2610;
16 |
17 | extern const char* configure_svg;
18 | const int configure_svgSize = 1998;
19 |
20 | extern const char* dashboard_gauge_svg;
21 | const int dashboard_gauge_svgSize = 1781;
22 |
23 | extern const char* expand_svg;
24 | const int expand_svgSize = 1044;
25 |
26 | extern const char* mute_svg;
27 | const int mute_svgSize = 1263;
28 |
29 | extern const char* pause_svg;
30 | const int pause_svgSize = 811;
31 |
32 | extern const char* play_svg;
33 | const int play_svgSize = 797;
34 |
35 | extern const char* phase_invert_svg;
36 | const int phase_invert_svgSize = 1297;
37 |
38 | extern const char* screenshot_svg;
39 | const int screenshot_svgSize = 2475;
40 |
41 | // Number of elements in the namedResourceList and originalFileNames arrays.
42 | const int namedResourceListSize = 10;
43 |
44 | // Points to the start of a list of resource names.
45 | extern const char* namedResourceList[];
46 |
47 | // Points to the start of a list of resource filenames.
48 | extern const char* originalFilenames[];
49 |
50 | // If you provide the name of one of the binary resource variables above, this function will
51 | // return the corresponding data and its size (or a null pointer if the name isn't found).
52 | const char* getNamedResource (const char* resourceNameUTF8, int& dataSizeInBytes);
53 |
54 | // If you provide the name of one of the binary resource variables above, this function will
55 | // return the corresponding original, non-mangled filename (or a null pointer if the name isn't found).
56 | const char* getNamedResourceOriginalFilename (const char* resourceNameUTF8);
57 | }
58 |
--------------------------------------------------------------------------------
/JuceLibraryCode/JuceHeader.h:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | IMPORTANT! This file is auto-generated each time you save your
4 | project - if you alter its contents, your changes may be overwritten!
5 |
6 | This is the header file that your files should include in order to get all the
7 | JUCE library headers. You should avoid including the JUCE headers directly in
8 | your own source files, because that wouldn't pick up the correct configuration
9 | options for your app.
10 |
11 | */
12 |
13 | #pragma once
14 |
15 | #include "AppConfig.h"
16 |
17 | #include
18 | #include
19 | #include
20 | #include
21 | #include
22 | #include
23 | #include
24 | #include
25 | #include
26 | #include
27 | #include
28 | #include
29 | #include
30 |
31 | #include "BinaryData.h"
32 |
33 | #if defined (JUCE_PROJUCER_VERSION) && JUCE_PROJUCER_VERSION < JUCE_VERSION
34 | /** If you've hit this error then the version of the Projucer that was used to generate this project is
35 | older than the version of the JUCE modules being included. To fix this error, re-save your project
36 | using the latest version of the Projucer or, if you aren't using the Projucer to manage your project,
37 | remove the JUCE_PROJUCER_VERSION define.
38 | */
39 | #error "This project was last saved using an outdated version of the Projucer! Re-save this project with the latest version to fix this error."
40 | #endif
41 |
42 | #if ! DONT_SET_USING_JUCE_NAMESPACE
43 | // If your code uses a lot of JUCE classes, then this will obviously save you
44 | // a lot of typing, but can be disabled by setting DONT_SET_USING_JUCE_NAMESPACE.
45 | using namespace juce;
46 | #endif
47 |
48 | #if ! JUCE_DONT_DECLARE_PROJECTINFO
49 | namespace ProjectInfo
50 | {
51 | const char* const projectName = "DSP Testbench";
52 | const char* const companyName = "";
53 | const char* const versionString = "1.1.0";
54 | const int versionNumber = 0x10100;
55 | }
56 | #endif
57 |
--------------------------------------------------------------------------------
/JuceLibraryCode/ReadMe.txt:
--------------------------------------------------------------------------------
1 |
2 | Important Note!!
3 | ================
4 |
5 | The purpose of this folder is to contain files that are auto-generated by the Projucer,
6 | and ALL files in this folder will be mercilessly DELETED and completely re-written whenever
7 | the Projucer saves your project.
8 |
9 | Therefore, it's a bad idea to make any manual changes to the files in here, or to
10 | put any of your own files in here if you don't want to lose them. (Of course you may choose
11 | to add the folder's contents to your version-control system so that you can re-merge your own
12 | modifications after the Projucer has saved its changes).
13 |
--------------------------------------------------------------------------------
/JuceLibraryCode/include_juce_audio_basics.cpp:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | IMPORTANT! This file is auto-generated each time you save your
4 | project - if you alter its contents, your changes may be overwritten!
5 |
6 | */
7 |
8 | #include "AppConfig.h"
9 | #include
10 |
--------------------------------------------------------------------------------
/JuceLibraryCode/include_juce_audio_basics.mm:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | IMPORTANT! This file is auto-generated each time you save your
4 | project - if you alter its contents, your changes may be overwritten!
5 |
6 | */
7 |
8 | #include "AppConfig.h"
9 | #include
10 |
--------------------------------------------------------------------------------
/JuceLibraryCode/include_juce_audio_devices.cpp:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | IMPORTANT! This file is auto-generated each time you save your
4 | project - if you alter its contents, your changes may be overwritten!
5 |
6 | */
7 |
8 | #include "AppConfig.h"
9 | #include
10 |
--------------------------------------------------------------------------------
/JuceLibraryCode/include_juce_audio_devices.mm:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | IMPORTANT! This file is auto-generated each time you save your
4 | project - if you alter its contents, your changes may be overwritten!
5 |
6 | */
7 |
8 | #include "AppConfig.h"
9 | #include
10 |
--------------------------------------------------------------------------------
/JuceLibraryCode/include_juce_audio_formats.cpp:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | IMPORTANT! This file is auto-generated each time you save your
4 | project - if you alter its contents, your changes may be overwritten!
5 |
6 | */
7 |
8 | #include "AppConfig.h"
9 | #include
10 |
--------------------------------------------------------------------------------
/JuceLibraryCode/include_juce_audio_formats.mm:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | IMPORTANT! This file is auto-generated each time you save your
4 | project - if you alter its contents, your changes may be overwritten!
5 |
6 | */
7 |
8 | #include "AppConfig.h"
9 | #include
10 |
--------------------------------------------------------------------------------
/JuceLibraryCode/include_juce_audio_processors.cpp:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | IMPORTANT! This file is auto-generated each time you save your
4 | project - if you alter its contents, your changes may be overwritten!
5 |
6 | */
7 |
8 | #include "AppConfig.h"
9 | #include
10 |
--------------------------------------------------------------------------------
/JuceLibraryCode/include_juce_audio_processors.mm:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | IMPORTANT! This file is auto-generated each time you save your
4 | project - if you alter its contents, your changes may be overwritten!
5 |
6 | */
7 |
8 | #include "AppConfig.h"
9 | #include
10 |
--------------------------------------------------------------------------------
/JuceLibraryCode/include_juce_audio_processors_ara.cpp:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | IMPORTANT! This file is auto-generated each time you save your
4 | project - if you alter its contents, your changes may be overwritten!
5 |
6 | */
7 |
8 | #include "AppConfig.h"
9 | #include
10 |
--------------------------------------------------------------------------------
/JuceLibraryCode/include_juce_audio_processors_lv2_libs.cpp:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | IMPORTANT! This file is auto-generated each time you save your
4 | project - if you alter its contents, your changes may be overwritten!
5 |
6 | */
7 |
8 | #include "AppConfig.h"
9 | #include
10 |
--------------------------------------------------------------------------------
/JuceLibraryCode/include_juce_audio_utils.cpp:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | IMPORTANT! This file is auto-generated each time you save your
4 | project - if you alter its contents, your changes may be overwritten!
5 |
6 | */
7 |
8 | #include "AppConfig.h"
9 | #include
10 |
--------------------------------------------------------------------------------
/JuceLibraryCode/include_juce_audio_utils.mm:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | IMPORTANT! This file is auto-generated each time you save your
4 | project - if you alter its contents, your changes may be overwritten!
5 |
6 | */
7 |
8 | #include "AppConfig.h"
9 | #include
10 |
--------------------------------------------------------------------------------
/JuceLibraryCode/include_juce_core.cpp:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | IMPORTANT! This file is auto-generated each time you save your
4 | project - if you alter its contents, your changes may be overwritten!
5 |
6 | */
7 |
8 | #include "AppConfig.h"
9 | #include
10 |
--------------------------------------------------------------------------------
/JuceLibraryCode/include_juce_core.mm:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | IMPORTANT! This file is auto-generated each time you save your
4 | project - if you alter its contents, your changes may be overwritten!
5 |
6 | */
7 |
8 | #include "AppConfig.h"
9 | #include
10 |
--------------------------------------------------------------------------------
/JuceLibraryCode/include_juce_core_CompilationTime.cpp:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | IMPORTANT! This file is auto-generated each time you save your
4 | project - if you alter its contents, your changes may be overwritten!
5 |
6 | */
7 |
8 | #include "AppConfig.h"
9 | #include
10 |
--------------------------------------------------------------------------------
/JuceLibraryCode/include_juce_data_structures.cpp:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | IMPORTANT! This file is auto-generated each time you save your
4 | project - if you alter its contents, your changes may be overwritten!
5 |
6 | */
7 |
8 | #include "AppConfig.h"
9 | #include
10 |
--------------------------------------------------------------------------------
/JuceLibraryCode/include_juce_data_structures.mm:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | IMPORTANT! This file is auto-generated each time you save your
4 | project - if you alter its contents, your changes may be overwritten!
5 |
6 | */
7 |
8 | #include "AppConfig.h"
9 | #include
10 |
--------------------------------------------------------------------------------
/JuceLibraryCode/include_juce_dsp.cpp:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | IMPORTANT! This file is auto-generated each time you save your
4 | project - if you alter its contents, your changes may be overwritten!
5 |
6 | */
7 |
8 | #include "AppConfig.h"
9 | #include
10 |
--------------------------------------------------------------------------------
/JuceLibraryCode/include_juce_dsp.mm:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | IMPORTANT! This file is auto-generated each time you save your
4 | project - if you alter its contents, your changes may be overwritten!
5 |
6 | */
7 |
8 | #include "AppConfig.h"
9 | #include
10 |
--------------------------------------------------------------------------------
/JuceLibraryCode/include_juce_events.cpp:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | IMPORTANT! This file is auto-generated each time you save your
4 | project - if you alter its contents, your changes may be overwritten!
5 |
6 | */
7 |
8 | #include "AppConfig.h"
9 | #include
10 |
--------------------------------------------------------------------------------
/JuceLibraryCode/include_juce_events.mm:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | IMPORTANT! This file is auto-generated each time you save your
4 | project - if you alter its contents, your changes may be overwritten!
5 |
6 | */
7 |
8 | #include "AppConfig.h"
9 | #include
10 |
--------------------------------------------------------------------------------
/JuceLibraryCode/include_juce_graphics.cpp:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | IMPORTANT! This file is auto-generated each time you save your
4 | project - if you alter its contents, your changes may be overwritten!
5 |
6 | */
7 |
8 | #include "AppConfig.h"
9 | #include
10 |
--------------------------------------------------------------------------------
/JuceLibraryCode/include_juce_graphics.mm:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | IMPORTANT! This file is auto-generated each time you save your
4 | project - if you alter its contents, your changes may be overwritten!
5 |
6 | */
7 |
8 | #include "AppConfig.h"
9 | #include
10 |
--------------------------------------------------------------------------------
/JuceLibraryCode/include_juce_graphics_Harfbuzz.cpp:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | IMPORTANT! This file is auto-generated each time you save your
4 | project - if you alter its contents, your changes may be overwritten!
5 |
6 | */
7 |
8 | #include "AppConfig.h"
9 | #include
10 |
--------------------------------------------------------------------------------
/JuceLibraryCode/include_juce_graphics_Sheenbidi.c:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | IMPORTANT! This file is auto-generated each time you save your
4 | project - if you alter its contents, your changes may be overwritten!
5 |
6 | */
7 |
8 | #include "AppConfig.h"
9 | #include
10 |
--------------------------------------------------------------------------------
/JuceLibraryCode/include_juce_gui_basics.cpp:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | IMPORTANT! This file is auto-generated each time you save your
4 | project - if you alter its contents, your changes may be overwritten!
5 |
6 | */
7 |
8 | #include "AppConfig.h"
9 | #include
10 |
--------------------------------------------------------------------------------
/JuceLibraryCode/include_juce_gui_basics.mm:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | IMPORTANT! This file is auto-generated each time you save your
4 | project - if you alter its contents, your changes may be overwritten!
5 |
6 | */
7 |
8 | #include "AppConfig.h"
9 | #include
10 |
--------------------------------------------------------------------------------
/JuceLibraryCode/include_juce_gui_extra.cpp:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | IMPORTANT! This file is auto-generated each time you save your
4 | project - if you alter its contents, your changes may be overwritten!
5 |
6 | */
7 |
8 | #include "AppConfig.h"
9 | #include
10 |
--------------------------------------------------------------------------------
/JuceLibraryCode/include_juce_gui_extra.mm:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | IMPORTANT! This file is auto-generated each time you save your
4 | project - if you alter its contents, your changes may be overwritten!
5 |
6 | */
7 |
8 | #include "AppConfig.h"
9 | #include
10 |
--------------------------------------------------------------------------------
/JuceLibraryCode/include_juce_opengl.cpp:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | IMPORTANT! This file is auto-generated each time you save your
4 | project - if you alter its contents, your changes may be overwritten!
5 |
6 | */
7 |
8 | #include "AppConfig.h"
9 | #include
10 |
--------------------------------------------------------------------------------
/JuceLibraryCode/include_juce_opengl.mm:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | IMPORTANT! This file is auto-generated each time you save your
4 | project - if you alter its contents, your changes may be overwritten!
5 |
6 | */
7 |
8 | #include "AppConfig.h"
9 | #include
10 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2018 Andrew J
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # DSP Testbench
2 |
3 | DSP Testbench is designed to help developers using the [JUCE framework](https://juce.com) to analyse their DSP by providing a test harness for code inheriting from `juce::dsp::ProcessorBase`. The harness provides signal sources, routing, analysis and monitoring functions.
4 |
5 | 
6 |
7 | ## Features
8 |
9 | ### Title Bar Controls
10 |
11 | Besides the usual window sizing buttons, the title bar hosts the following controls:
12 |
13 | - CPU meter
14 | - Snapshot
15 | - Performance benchmarks
16 | - Audio device settings
17 | - About (you already know what this does :) )
18 |
19 | Most of the application settings are automatically saved and restored each time you restart the app.
20 |
21 | ### Signal Sources
22 |
23 | Two individual signal source modules generate synthesised signals, play back audio files, or pass through from an audio interface. The synthesis tab provides periodic waveforms with sweepable frequencies, as well as impulse & step functions and noise generators. Each source can be muted, inverted or gain trimmed, and the periodic waveforms can be synchronised between the two source modules.
24 |
25 | The triangle, square and saw oscillators are implemented with a PolyBLEP implementation to reduce aliasing, however it will still be visible in the analyser at higher frequencies.
26 |
27 | Note that white and pink noise show up as a circle on the phase scope because we generate different samples on each channel. The other oscillators generate the same samples on each channel.
28 |
29 | ### Processor Control
30 |
31 | Each of the two processor modules are used to host and control your DSP code. Either or both signal sources can be routed to each processor; and the output can be inverted, or muted.
32 |
33 | One use case is to verify that code optimisations do not alter the output. You can achieve this by hosting different versions of your DSP code in either module, routing the same audio to both, and inverting the output of one processor to ensure perfect cancellation.
34 |
35 | ### Analysis
36 |
37 | The analyser provides the following:
38 |
39 | - FFT scope with logarithmic frequency scale (0 to -80dB amplitude scale)
40 | - Oscilloscope
41 | - Phase scope
42 | - Level meter with VU (narrow) and peak (wide) meters for each channel
43 | - Clip indicators (click to popup clip stats window with reset button)
44 | - Pause button to freeze the display (audio is not paused)
45 | - Expand button
46 | - Advanced settings for scopes
47 |
48 | The oscilloscope can be zoomed using the mouse wheel (hold shift to zoom amplitude instead of time) and you can pan by clicking and dragging. Double click anywhere on the oscilloscope to reset scale
49 |
50 | ### Monitoring
51 |
52 | The monitoring section has a gain control and mute button to control the output level of the application. An optional output limiter is also provided to prevent digital overs (this is applied after the processors so does not affect their behaviour).
53 |
54 | ### Snapshot
55 |
56 | The snapshot functionality allows you to pass 4096 samples through the processor then pause the analysis and audio so you can forensically examine the resulting output. Normal operation can be resumed by toggling the snapshot button again. When a snapshot is triggered, the audio device is stopped and restarted and all modules are reset so that the same 4096 samples will be generated and processed every single time. The only exception to this is if the wave file player has its' right hand button disabled, in which case playback will be from the current position.
57 |
58 | ### Performance Benchmarks
59 |
60 | The benchmark functionality starts your processor(s) on another thread and pumps audio through, gathering statistics on how much time has been spent running your routines. A single block of audio is repeated from source A (using live audio input will not work).
61 |
62 | ## Developer Notes
63 |
64 | To make use of DSP Testbench, you need to include your own code, wrap it appropriately and build the project.
65 |
66 | - Navigate to the `Source\Processing` folder and take a look at `ProcessorExamples.h/.cpp`
67 | - This shows how to inherit from ProcessorHarness and shows examples of how to override the necessary pure virtual functions
68 | - Create a local branch of the repository before proceeding
69 | - Copy (or create) your own code into the project folder
70 | - Make sure you add these files to the Projucer project also
71 | - Either extend `ProcessorExamples.h/cpp` or create your own wrapper class and include it in `MainComponent.cpp`
72 | - Instantiate your processor harness in the `MainContentComponent` constructor
73 | - If optimising code, then use two separate wrappers and instantiate them separately
74 | - Build, run and test!
75 |
76 | ## Credits & Attributions
77 |
78 | ASIO Interface Technology by Steinberg Media Technologies GmbH
79 |
80 | This software makes use of certain code libraries, those portions of code are copyright as per below:
81 |
82 | - JUCE 8 - copyright © 2025 Raw Material Software
83 | - Application code - copyright © 2021 Oblique Audio
84 | - Fast maths approximations - copyright © 2011 Paul Mineiro
85 | - rand31pmc white noise generator - copyright © 2005 Robin Whittle
86 | - Pink noise filter - Paul Kellett
87 | - PolyBLEP/BLAMP - adapted from Tebjan Halm (vvvv.org)
88 | - MGA JS Limiter - copyright © 2008 Michael Gruhn
89 |
90 | ## Software Disclaimer
91 |
92 | This software is provided "as is" and you use it at your own risk.
93 |
94 | The developers make no warranties as to performance, merchantability, fitness for a particular purpose, or any other warranties whether expressed or implied. No oral or written communication from or information provided by the developers shall create a warranty.
95 |
96 | Under no circumstances shall the developers or contributors be liable for direct, indirect, special, incidental, or consequential damages resulting from the use, misuse, or inability to use this software, even if the developers have been advised of the possibility of such damages.
97 |
98 | These exclusions and limitations may not apply in all jurisdictions. You may have additional rights and some of these limitations may not apply to you.
99 |
100 |
--------------------------------------------------------------------------------
/Resources/about.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/Resources/audio_settings.svg:
--------------------------------------------------------------------------------
1 |
2 |
57 |
--------------------------------------------------------------------------------
/Resources/configure.svg:
--------------------------------------------------------------------------------
1 |
2 |
49 |
--------------------------------------------------------------------------------
/Resources/dashboard_gauge.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/Resources/expand.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/Resources/mute.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/Resources/pause.svg:
--------------------------------------------------------------------------------
1 |
2 |
31 |
--------------------------------------------------------------------------------
/Resources/phase_invert.svg:
--------------------------------------------------------------------------------
1 |
2 |
42 |
--------------------------------------------------------------------------------
/Resources/play.svg:
--------------------------------------------------------------------------------
1 |
2 |
31 |
--------------------------------------------------------------------------------
/Resources/screenshot.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/Source/GUI/AboutComponent.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | ==============================================================================
3 |
4 | AboutComponent.cpp
5 | Created: 16 Mar 2019 4:17:47pm
6 | Author: Andrew
7 |
8 | ==============================================================================
9 | */
10 |
11 | #include "AboutComponent.h"
12 |
13 | AboutComponent::AboutComponent()
14 | {
15 | addAndMakeVisible (txtEditor);
16 | txtEditor.setMultiLine (true);
17 | txtEditor.setReadOnly (true);
18 | txtEditor.setCaretVisible (false);
19 | txtEditor.setPopupMenuEnabled (false);
20 | txtEditor.setColour (TextEditor::ColourIds::outlineColourId, Colours::transparentBlack);
21 | txtEditor.setColour (TextEditor::ColourIds::backgroundColourId, Colours::black);
22 |
23 | Timer::callAfterDelay (10, [this] { addAboutText(); });
24 |
25 | setSize (800, 600);
26 | }
27 | void AboutComponent::paint(Graphics & g)
28 | {
29 | g.fillAll (DspTestBenchLnF::ApplicationColours::componentBackground());
30 | }
31 | void AboutComponent::resized()
32 | {
33 | txtEditor.setBounds(getLocalBounds().reduced(2,2));
34 | }
35 | void AboutComponent::addAboutText()
36 | {
37 | txtEditor.clear();
38 |
39 | insertBreak();
40 | insertTitle ("Application description", Colours::white, false);
41 | insertText ("DSP Testbench is designed to help developers using the JUCE framework to analyse their DSP by providing ");
42 | insertText ("a test harness for code inheriting from juce::dsp::ProcessorBase. The harness provides signal sources, ");
43 | insertText ("routing, analysis and monitoring functions. See README.md for developer notes.", true);
44 |
45 | insertSubtitle ("Title bar controls");
46 | insertText ("Besides the usual window sizing buttons, the title bar hosts the following controls:", true);
47 | insertBullet(); insertText ("CPU meter");
48 | insertBullet(); insertText ("Snapshot");
49 | insertBullet(); insertText ("Performance benchmarks");
50 | insertBullet(); insertText ("Audio device settings");
51 | insertBullet(); insertText ("About (you already know what this does :) )", true);
52 | insertBreak();
53 | insertText ("Most of the application settings are automatically saved and restored each time you restart the app.", true);
54 |
55 | insertSubtitle ("Signal sources");
56 | insertText ("Two individual signal source modules generate synthesised signals, play back audio files, or pass through from an audio interface. ");
57 | insertText ("The synthesis tab provides periodic waveforms with sweepable frequencies, as well as impulse & step functions and noise generators. ");
58 | insertText ("Each source can be muted, inverted or gain trimmed, and the periodic waveforms can be synchronised between the two source modules.", true);
59 | insertBreak();
60 | insertText ("The triangle, square and saw oscillators are implemented with a PolyBLEP implementation to reduce aliasing, however it will still be ");
61 | insertText ("visible in the analyser at higher frequencies.", true);
62 | insertBreak();
63 | insertText ("Note that white and pink noise show up as a circle on the phase scope because we generate different samples on each channel. ");
64 | insertText ("The other oscillators generate the same samples on each channel.", true);
65 |
66 | insertSubtitle ("Processor control");
67 | insertText ("Each of the two processor modules are used to host and control your DSP code. Either or both signal sources can be routed ");
68 | insertText ("to each processor; and the output can be inverted, or muted.", true);
69 | insertBreak();
70 | insertText ("One use case is to verify that code optimisations do not alter the output. You can achieve this by hosting different versions ");
71 | insertText ("of your DSP code in either module, routing the same audio to both, and inverting the output of one processor to ensure perfect cancellation.", true);
72 |
73 | insertSubtitle ("Analysis");
74 | insertText ("The analyser provides the following:", true);
75 | insertBullet(); insertText ("FFT scope with logarithmic frequency scale (0 to -80dB amplitude scale)");
76 | insertBullet(); insertText ("Oscilloscope");
77 | insertBullet(); insertText ("Phase scope");
78 | insertBullet(); insertText ("Level meter with VU (narrow) and peak (wide) meters for each channel");
79 | insertBullet(); insertText ("Clip indicators (click to popup clip stats window with reset button)");
80 | insertBullet(); insertText ("Pause button to freeze the display (audio is not paused)");
81 | insertBullet(); insertText ("Expand button");
82 | insertBullet(); insertText ("Advanced settings for scopes", true);
83 | insertBreak();
84 | insertText ("The oscilloscope can be zoomed using the mouse wheel (hold shift to zoom amplitude instead of time) and you can pan by ");
85 | insertText ("clicking and dragging. Double click anywhere on the oscilloscope to reset scale", true);
86 |
87 | insertSubtitle ("Monitoring");
88 | insertText ("The monitoring section has a gain control and mute button to control the output level of the application. An optional output limiter ");
89 | insertText ("is also provided to prevent digital overs (this is applied after the processors so does not affect their behaviour).", true);
90 |
91 | insertSubtitle ("Snapshot");
92 | insertText ("The snapshot functionality allows you to pass 4096 samples through the processor then pause the analysis and audio so you can forensically ");
93 | insertText ("examine the resulting output. Normal operation can be resumed by toggling the snapshot button again. When a snapshot is triggered, the audio ");
94 | insertText ("device is stopped and restarted and all modules are reset so that the same 4096 samples will be generated and processed every single time. ");
95 | insertText ("The only exception to this is if the wave file player has its' right hand button disabled, in which case playback will be from the current position.", true);
96 |
97 | insertSubtitle ("Performance benchmarks");
98 | insertText ("The benchmark functionality starts your processor(s) on another thread and pumps audio through, gathering statistics on how much time has ");
99 | insertText ("been spent running your routines. A single block of audio is repeated from source A (using live audio input will not work).", true);
100 |
101 | insertTitle ("Credits & Attributions");
102 | insertText ("ASIO Interface Technology by Steinberg Media Technologies GmbH", true);
103 | insertBreak();
104 | insertText ("This software makes use of certain code libraries, those portions of code are copyright as per below:", true);
105 | insertBullet(); insertText ("JUCE 8"); insertCopyright ("Raw Material Software", 2022);
106 | insertBullet(); insertText ("Application code"); insertCopyright ("Oblique Audio", 2022);
107 | insertBullet(); insertText ("Fast maths approximations"); insertCopyright ("Paul Mineiro", 2011);
108 | insertBullet(); insertText ("rand31pmc white noise generator"); insertCopyright ("Robin Whittle", 2005);
109 | insertBullet(); insertText ("Pink noise filter - Paul Kellett");
110 | insertBullet(); insertText ("PolyBLEP/BLAMP - adapted from Tebjan Halm (vvvv.org)");
111 | insertBullet(); insertText ("MGA JS Limiter"); insertCopyright ("Michael Gruhn", 2008);
112 | insertBreak();
113 |
114 | insertTitle ("Software Disclaimer");
115 | insertText ("This software is provided \"as is\" and you use it at your own risk.", true);
116 | insertBreak();
117 | insertText ("The developers make no warranties as to performance, merchantability, fitness for a particular purpose, or any other warranties whether expressed or implied. ");
118 | insertText ("No oral or written communication from or information provided by the developers shall create a warranty.", true);
119 | insertBreak();
120 | insertText ("Under no circumstances shall the developers or contributors be liable for direct, indirect, special, incidental, or consequential damages resulting from the use, ");
121 | insertText ("misuse, or inability to use this software, even if the developers have been advised of the possibility of such damages.", true);
122 | insertBreak();
123 | insertText ("These exclusions and limitations may not apply in all jurisdictions. You may have additional rights and some of these limitations may not apply to you.", true);
124 | insertBreak (0.5f);
125 |
126 | txtEditor.setCaretPosition (0);
127 | }
128 | void AboutComponent::insertTitle (const String& title, const Colour textColour, const bool insertLineBefore)
129 | {
130 | txtEditor.setColour (TextEditor::ColourIds::textColourId, textColour);
131 | if (insertLineBefore)
132 | insertBreak (1.2f);
133 | txtEditor.setFont (titleFont);
134 | txtEditor.insertTextAtCaret (title.toUpperCase() + "\n");
135 | insertBreak (0.3f);
136 | }
137 | void AboutComponent::insertSubtitle(const String & subtitle, const Colour textColour, const bool insertLineBefore)
138 | {
139 | txtEditor.setColour (TextEditor::ColourIds::textColourId, textColour);
140 | if (insertLineBefore)
141 | insertBreak (0.5f);
142 | txtEditor.setFont (subtitleFont);
143 | txtEditor.insertTextAtCaret (subtitle.toUpperCase() + "\n");
144 | insertBreak (0.15f);
145 | }
146 | void AboutComponent::insertText (const String& text, const bool breakLine, const Colour textColour)
147 | {
148 | txtEditor.setColour (TextEditor::ColourIds::textColourId, textColour);
149 | txtEditor.setFont (textFont);
150 | txtEditor.insertTextAtCaret (text);
151 | if (breakLine)
152 | txtEditor.insertTextAtCaret ("\n");
153 | }
154 | void AboutComponent::insertBreak (const float height)
155 | {
156 | txtEditor.setFont (Font (FontOptions (GUI_SIZE_F(height))));
157 | txtEditor.insertTextAtCaret ("\n");
158 | }
159 | void AboutComponent::insertBullet (const bool insertBreakBefore)
160 | {
161 | if (insertBreakBefore)
162 | insertBreak();
163 | txtEditor.setFont (textFont);
164 | txtEditor.insertTextAtCaret (CharPointer_UTF8("\xE2\x80\xA2 "));
165 | }
166 | void AboutComponent::insertCopyright(const String& copyrightOwner, const int year)
167 | {
168 | jassert (year > 1900);
169 | jassert (copyrightOwner.length() > 0);
170 | txtEditor.setFont (textFont);
171 | txtEditor.insertTextAtCaret (String(CharPointer_UTF8(" - copyright \xc2\xa9 ")) + String (year) + " " + copyrightOwner);
172 | }
--------------------------------------------------------------------------------
/Source/GUI/AboutComponent.h:
--------------------------------------------------------------------------------
1 | /*
2 | ==============================================================================
3 |
4 | AboutComponent.h
5 | Created: 16 Mar 2019 4:17:47pm
6 | Author: Andrew
7 |
8 | ==============================================================================
9 | */
10 |
11 | #pragma once
12 |
13 | #include "../JuceLibraryCode/JuceHeader.h"
14 | #include "LookAndFeel.h"
15 |
16 | class AboutComponent : public Component
17 | {
18 | public:
19 |
20 | AboutComponent();
21 | ~AboutComponent() override = default;
22 | void paint (Graphics& g) override;
23 | void resized() override;
24 |
25 | private:
26 |
27 | using cols = DspTestBenchLnF::ApplicationColours;
28 |
29 | void addAboutText();
30 | void insertTitle (const String& title, const Colour textColour = cols::titleFontColour(), const bool insertLineBefore = true);
31 | void insertSubtitle (const String& subtitle, const Colour textColour = cols::titleFontColour(), const bool insertLineBefore = true);
32 | void insertText (const String& text, const bool breakLine = false, const Colour textColour = cols::normalFontColour());
33 | void insertBreak (const float height = 0.2f);
34 | void insertBullet (const bool insertBreakBefore = true);
35 | void insertCopyright (const String& copyrightOwner, const int year);
36 |
37 | TextEditor txtEditor;
38 | const Font titleFont = Font (FontOptions (GUI_SIZE_F (0.85)));
39 | const Font subtitleFont = Font (FontOptions (GUI_SIZE_F (0.65)));
40 | const Font textFont = Font (FontOptions (GUI_SIZE_F (0.60)));
41 |
42 | JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AboutComponent)
43 | };
--------------------------------------------------------------------------------
/Source/GUI/AnalyserComponent.h:
--------------------------------------------------------------------------------
1 | /*
2 | ==============================================================================
3 |
4 | AnalyserComponent.h
5 | Created: 11 Jan 2018 4:37:59pm
6 | Author: Andrew Jerrim
7 |
8 | ==============================================================================
9 | */
10 |
11 | #pragma once
12 |
13 | #include "../JuceLibraryCode/JuceHeader.h"
14 | #include "FftScope.h"
15 | #include "Oscilloscope.h"
16 | #include "Goniometer.h"
17 | #include "MeteringComponents.h"
18 | #include "../Processing/FftProcessor.h"
19 | #include "../Processing/AudioScopeProcessor.h"
20 | #include "../Processing/MeteringProcessors.h"
21 |
22 | class AnalyserComponent final : public Component, public dsp::ProcessorBase, public Timer
23 | {
24 | public:
25 |
26 | AnalyserComponent();
27 | ~AnalyserComponent() override;
28 |
29 | void paint (Graphics& g) override;
30 | void resized() override;
31 | void timerCallback() override;
32 |
33 | void prepare (const dsp::ProcessSpec& spec) override;
34 | void process (const dsp::ProcessContextReplacing& context) override;
35 | void reset() override;
36 |
37 | bool isProcessing() const noexcept;
38 | void activateProcessing();
39 | void suspendProcessing();
40 |
41 | void showClipStats();
42 |
43 | private:
44 |
45 | int getOscilloscopeMaximumBlockSize() const;
46 |
47 | class AnalyserConfigComponent : public Component
48 | {
49 | public:
50 | explicit AnalyserConfigComponent (AnalyserComponent* analyserToConfigure);
51 | ~AnalyserConfigComponent() override
52 | = default;
53 |
54 | //void paint (Graphics& g) override;
55 | void resized () override;
56 |
57 | private:
58 | AnalyserComponent* analyserComponent;
59 | Label lblFftAggregation;
60 | ComboBox cmbFftAggregation;
61 | Label lblFftRelease;
62 | ComboBox cmbFftRelease;
63 | Label lblScopeAggregation;
64 | ComboBox cmbScopeAggregation;
65 | TextEditor txtHelp;
66 |
67 | JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AnalyserConfigComponent);
68 | };
69 |
70 | String keyName;
71 | std::unique_ptr config{};
72 |
73 | Label lblTitle;
74 | std::unique_ptr btnConfig{};
75 | std::unique_ptr btnPause{};
76 | std::unique_ptr btnExpand{};
77 | std::unique_ptr configComponent{};
78 |
79 | FftProcessor<12> fftProcessor;
80 | FftScope<12> fftScope;
81 |
82 | AudioScopeProcessor audioScopeProcessor;
83 | Oscilloscope oscilloscope;
84 | Goniometer goniometer;
85 |
86 | PeakMeterProcessor peakMeterProcessor{};
87 | VUMeterProcessor vuMeterProcessor{};
88 | MainMeterBackground mainMeterBackground{};
89 | OwnedArray peakMeterBars{};
90 | OwnedArray vuMeterBars{};
91 | OwnedArray clipIndicators{};
92 |
93 | ClipCounterProcessor clipCounterProcessor{};
94 | ClipStatsComponent clipStatsComponent{};
95 | Viewport clipStatsViewport{};
96 | std::unique_ptr clipStatsWindow{};
97 |
98 | int numChannels = 0;
99 |
100 | Atomic statusActive = true;
101 |
102 | JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AnalyserComponent)
103 | };
--------------------------------------------------------------------------------
/Source/GUI/BenchmarkComponent.h:
--------------------------------------------------------------------------------
1 | /*
2 | ==============================================================================
3 |
4 | BenchmarkComponent.h
5 | Created: 24 Apr 2019 9:26:12am
6 | Author: Andrew
7 |
8 | ==============================================================================
9 | */
10 |
11 | #pragma once
12 |
13 | #include "../JuceLibraryCode/JuceHeader.h"
14 | #include "../Processing/ProcessorHarness.h"
15 | #include "SourceComponent.h"
16 |
17 | class BenchmarkComponent : public Component, public Timer
18 | {
19 | public:
20 |
21 | /** Pass in pointers to both process harnesses and the source component for the audio to into them. */
22 | BenchmarkComponent (ProcessorHarness* processorHarnessA, ProcessorHarness* processorHarnessB, SourceComponent* sourceComponent);
23 | ~BenchmarkComponent() override;
24 | void paint (Graphics& g) override;
25 | void resized() override;
26 | void timerCallback() override;
27 | void setBufferAlignmentStatus (const String &status);
28 |
29 | private:
30 |
31 | class BenchmarkThread : public ThreadWithProgressWindow
32 | {
33 | public:
34 | BenchmarkThread (std::vector* harnesses, SourceComponent* sourceComponent, BenchmarkComponent* benchmarkComponent);
35 | ~BenchmarkThread() override = default;
36 |
37 | void run() override;
38 | void threadComplete (bool userPressedCancel) override;
39 |
40 | /** Set number of full test cycles to run (reset, prepare, processing). */
41 | void setTestCycles (const int cycles);
42 |
43 | /** Set number of times to iterate the processing within each cycle. */
44 | void setProcessingIterations (const int iterations);
45 |
46 | /**< Set ProcessSpec to test against. */
47 | void setProcessSpec (dsp::ProcessSpec& spec);
48 |
49 | private:
50 |
51 | /** Returns true if the specified pointer points to 16 byte aligned data. */
52 | static inline bool isSseAligned (const float* data);
53 |
54 | /** Returns a string describing the buffer alignment status. */
55 | String getAudioBlockAlignmentStatus() const;
56 |
57 | std::vector* processingHarnesses{};
58 | SourceComponent* srcComponent;
59 | BenchmarkComponent* parent;
60 | int testCycles = 0;
61 | int processingIterations = 0;
62 | dsp::ProcessSpec testSpec {};
63 | HeapBlock heapBlock{};
64 | std::unique_ptr> audioBlock{};
65 | };
66 |
67 | int getValueLabelIndex (const int processorIndex, const int routineIndex, const int valueIndex) const;
68 |
69 | OwnedArray