Designing Audio Effect Plug-Ins in C++ With Signal Processing Theory

Will Pirkle

Focal Press Taylor & Francis Croup

NEW YORK AND LONDON Introduction xv

Chapter 1: Digital Principles 1.1 Acquisition of Samples 1.2 Reconstruction of the Signal 1.3 Signal Processing Systems 1.4 Synchronization and Interrupts 1.5 Signal Processing Flow 1.6 Numerical Representation of Audio Data 1.7 Using Floating-Point Data 1.8 Basic DSP Test Signals 1 1.8.1 DC and Step 1.8.2 Nyquist 1.8.3 Vi Nyquist 1.8.4 lA Nyquist 1.8.5 Impulse 1.9 Signal Processing Algorithms 1.10 Bookkeeping 1.11 The One-Sample 1.12 Multiplication 1.13 Addition and Subtraction 1.14 Algorithm Examples and the Difference Equation 1.15 Gain, Attenuation, and Phase Inversion 1.16 Practical Mixing Algorithm Bibliography

Chapter 2: Anatomy ofa Plug-In 2.1 Static and Dynamic Linking 2.2 Virtual Address Space and DLL Access 2.3 C and C++ Style DLLs 2.4 Maintaining the User Interface 2.5 The Applications Programming Interface 2.6 Typical Required API Functions 2.7 The RackAFX Philosophy and API 2.7.1 stdcall Bibliography

VII viii Contents

Chapter 3: Writing Plug-Ins with RackAFX 35 3.1 Building the DLL 35 3.2 Creation 36 3.3 The GUI 36 3.4 Processing Audio 37 3.5 Destruction 38 3.6 Your First Plug-Ins 38 3.6.1 Project: Yourplugin 39 3.6.2 Yourplugin GUI 39 3.6.3 Yourplugin.h File 39 3.6.4 Yourplugin.cpp File 40 3.6.5 Building and Testing 40 3.6.6 Creating and Saving Presets 40 3.6.7 GUI Designer 40 3.7 Design a Volume Control Plug-In 40 3.8 Set Up RackAFX for Use 41 3.9 Setup Preferences 43 3.9.1 Project: Volume 44 3.9.2 Volume GUI 45 3.9.3 Configure a Slider Control 46 3.9.4 Volume.h File 48 3.9.5 Volume.cpp File 50 3.10 Design a Volume-in-dB Plug-In 54 3.10.1 Project: VolumedB 56 3.10.2 VolumedB GUI 56 3.10.3 VolumedB.h File 56 3.10.4 VolumedB.cpp File 57 3.11 Design a High- Tone Control Plug-In 58 3.11.1 Project: SimpleHPF 60 3.11.2 SimpleHPF GUI 60 3.11.3 SimpleHPF.h File 60 3.11.4 SimpleHPF.cpp File 62 3.12 Design a High-Frequency Tone Control with Volume Plug-In 66 3.12.1 Project: SimpleHPF 66 3.12.2 SimpleHPF GUI 66 3.12.3 SimpleHPF.h File 66 3.12.4 SimpleHPF.cpp File 67 3.13 The User Plug-In Menu in RackAFX 69

Chapter 4: How DSP Filters Work 71 4.1 First-Order Feed-Forward Filter 74 4.2 Design a General First-Order Feed-Forward Filter 84 4.3 First-Order Feed-Back Filter 88

4.4 Design a General First-Order Feed-Back Filter 89 Contents ix

4.4.1 Project FeedBackFilter 89 4.4.2 FeedBackFilter GUI 89 4.4.3 FeedBackFilter.h File 89 4.4.4 FeedBaclcFilter.cpp File 90 4.5 Observations 94 4.5.1 General 94 4.5.2 Feed-Forward Filters 95 4.5.3 Feed-Back Filters 95 Bibliography 95

Chapter 5: Basic DSP Theory 97 5.1 The Complex Sinusoid 97 5.2 Complex Math Review 100 5.3 Time Delay as a Math Operator 102 5.4 First-Order Feed-Forward Filter Revisited 103 5.4.1 Negative 104 5.4.2 Frequencies Above and Below ±Nyquist 106 5.5 Evaluating the Transfer Function H(o>) 106 5.5.1 DC(OHz) 107 5.5.2 Nyquist 0) 108 5.5.3 >/2 Nyquist (tt/2) 109 5.5.4 V* Nyquist (ir/4) 109 5.6 Evaluating 112 5.7 The z Substitution 114

5.8 The z Transform 114

5.9 The z Transform of Signals 116 5.10 The z Transform of Difference Equations 117 5.11 The z Transform of an Impulse Response 118 5.12 The Zeros of the Transfer Function 119 5.13 Estimating the Frequency Response: Zeros 121 5.14 Filter Gain Control 122 5.15 First-Order Feed-Back Filter Revisited 123 5.16 The Poles of the Transfer Function 124 5.16.1 DC(OHz) 128 5.16.2 Nyquist (it) 128 5.16.3 Vi Nyquist (tt/2) 129 5.16.4 Va Nyquist (ir/4) 130 5.17 Second-Order Feed-Forward Filter 132 5.17.1 DC(OHz) 139 5.17.2 Nyquist (it) 139 5.17.3 V% Nyquist (tt/2) 140 5.17.4 V* Nyquist (tt/4) 140 5.18 Second-Order Feed-B ack Filter 142 5.18.1 DC(OHz) 148 5.18.2 Challenge 149 x Contents

5.19 First-Order Pole-Zero Filter: The Shelving Filter 149 5.19.1 DC(OHz) 155 5.19.2 Challenge 155 5.20 The Bi-Quadratic Filter 157 Bibliography 162 Chapter 6: Audio Filter Designs: IIR Filters 163 6.1 Direct z-Plane Design 163 6.2 Single Pole Filters 164 6.2.1 First-Order LPF and HPF 164 6.3 Resonators 165 6.3.1 Simple Resonator 165 6.3.2 Smith-Angell Improved Resonator 168 6.4 Analog Filter to Digital Filter Conversion 170 6.4.1 Challenge 178 6.5 Effect of Poles or Zeros at Infinity 178 6.6 Generic Bi-Quad Designs 181 6.6.1 First-Order LPF and HPF 182 6.6.2 Second-Order LPF and HPF 183 6.6.3 Second-Order BPF and BSF 184 6.6.4 Second-Order Butterworth LPF and HPF 184 6.6.5 Second-Order Butterworth BPF and BSF 185 6.6.6 Second-Order Linkwitz-Riley LPF and HPF 186 6.6.7 First- and Second-Order APF 188 6.7 Audio Specific Filters 188 6.7.1 Modified Bi-Quad 189 6.7.2 First-Order Shelving Filters 189 6.7.3 Second-Order Parametric/Peaking Filter: Non-Constant-Q 191 6.7.4 Second-Order Parametric/Peaking Filter: Constant-Q 192 6.7.5 Cascaded Graphic EQ: Non-Constant-Q 194 6.7.6 Cascaded Graphic EQ: Constant-Q 195 6.8 Design a Resonant LPF Plug-In 196 6.8.1 Project: ResonantLPF 197 6.8.2 ResonantLPF GUI 197 6.8.3 ResonantLPF.h File 198 6.8.4 ResonantLPF.cpp File 199 6.9 The Massberg Analog-Matched Low-Pass Filter 201 6.9.1 First-Order Massberg LPF 201 6.9.2 Second-Order Massberg LPF 203 Bibliography 204 References 205

Chapter 7: Delay Effects and Circular Buffers 207 7.1 The Basic Digital Delay 209 7.2 Digital Delay with Wet/Dry Mix 214 Contents xi

7.2.1 Frequency and Impulse Responses 214 7.2.2 The Effect of 218 7.3 Design a DDL Module Plug-In 224 7.3.1 Project: DDLModule 225 7.3.2 DDLModule GUI 225 7.3.3 DDLModule.h File 226 7.3.4 DDLModule.cpp File 226 7.3.5 Declare and Initialize the Delay Line Components 228 7.3.6 DDLModule.h File 230 7.3.7 DDLModule.cpp File 230 7.4 Modifying the Module to Be Used by a Parent Plug-In 233 7.4.1 DDLModule.h File 233 7.4.2 DDLModule.cpp File 234 7.5 Modifying the Module to Implement Fractional Delay 235 7.5.1 DDLModule.cpp File 238 7.6 Design a Stereo Digital Delay Plug-In 239 7.6.1 Project: StereoDelay 239 7.6.2 StereoDelay GUI 241 7.6.3 StereoDelay.h File 241 7.6.4 StereoDelay.cpp File 242 7.7 Design a Stereo Crossed-Feedback Delay Plug-In 244 7.8 Enumerated Slider Variables 245 7.8.1 Constructor 246 7.8.2 PrepareForPlayO 246 7.8.3 UserInterfaceChange() 246 7.8.4 ProcessAudioFrameQ 247 7.9 More Delay Algorithms 248 7.9.1 Advanced DDL Module 248 7.9.2 Delay with LPF in Feedback Loop 248 7.9.3 Multi-Tap Delay 249 7.9.4 Ping-Pong Delay 250 7.9.5 LCR Delay 250 Bibliography 251

Chapter 8: Audio Filter Designs: FIR Filters 253 8.1 The IR Revisited: Convolution 253 8.2 Using RackAFX's Impulse Convolver 258 8.2.1 Loading IR Files 258 8.2.2 Creating IR Files 259 8.2.3 The IR File Format 261 8.3 Using RackAFX's FIR Designer 262 8.4 The Frequency Sampling Method 263 8.4.1 Linear-Phase FIR Using the Frequency Sampling Method 263 8.5 Complementary Filter Design for Linear Phase FIR Filters 266 8.6 Using RackAFX's Frequency Sampling Method Tool 267 xii Contents

269 8.7 Designing a Complementary Filter 270 8.8 The Optimal (Parks-McClellan) Method 271 8.9 Using RackAFX's Optimal Method Tool 273 8.10 Design a Convolution Plug-In 275 8.10.1 Project: Convolver 275 8.10.2 Convolver.h File 276 8.10.3 Convolver.cpp File 281 8.11 Numerical Method FIR Filters 282 8.11.1 Moving Average Interpolator 284 8.11.2 Lagrange Interpolator 284 8.11.3 Median Filter 287 Bibliography 289 Chapter 9: Oscillators 289 9.1 Direct Form Oscillator 290 9.1.1 Initial Conditions 292 9.2 Design a Direct Form Oscillator Plug-In 292 9.2.1 Project: DirectOscillator 292 9.2.2 DirectOscillator GUI 294 9.2.3 DirectOscillator.h File 295 9.2.4 DirectOscillator.cpp File 297 9.2.5 Improving the Oscillator Design 299 9.3 The Gordon-Smith Oscillator 301 9.4 Wave Table Oscillators 303 9.5 Design a Wave Table Oscillator Plug-In 303 9.5.1 Project: WTOscillator 303 9.5.2 WTOscillator GUI 304 9.5.3 WTOscillator.h File 305 9.5.4 WTOscillator.cpp File 308 9.6 Adding More Wave Tables 308 9.6.1 WTOscillator.h File 309 9.6.2 WTOscillator.cpp File 310 9.6.3 WTOscillator GUI 310 9.6.4 WTOscillator.h File 311 9.6.5 WTOscillator.cpp File 312 9.7 Band-Limited Additive Wave Tables 313 9.7.1 WTOscillator GUI 313 9.7.2 WTOscillator.h File 314 9.7.3 WTOscillator.cpp File 317 9.7.4 Saw-Tooth 317 9.7.5 Square Wave 320 9.8 Additional Oscillator Features (LFO) 320 9.8.1 WTOscillator.h File 321 9.8.2 WTOscillator.cpp File 321 9.8.3 WTOscillator.h File 322 9.8.4 WTOscillator.cpp File Contents xiii

9.9 Bipolar/Unipolar Functionality 324 9.9.1 WTOscillator GUI 324 9.9.2 WTOscillator.cpp File 325 Bibliography 326

Chapter 10: Modulated Delay Effects 327 10.1 The Flanger/Vibrato Effect 328 10.2 The Effect 331 10.3 Design a Flanger/Vibrato/Chorus Plug-In 334 10.3.1 Project: ModDelayModule 335 10.3.2 ModDelayModule GUI 336 10.3.3 ModDelayModule.h File 336 10.3.4 ModDelayModule.cpp File 337 10.3.5 PrepareForPlayO 340 10.3.6 Challenge 342 10.4 Design a Stereo Quadrature Flanger Plug-In 342 10.4.1 Project: StereoQuadFlanger 342 10.4.2 StereoQuadFlanger GUI 342 10.4.3 StereoQuadFlanger.h File 342 10.4.4 StereoQuadFlanger.cpp File 343 10.4.5 Challenges 345 10.5 Design a Multi-Unit LCR Chorus Plug-In 345 10.5.1 Project: StereoLCRChorus 346 10.5.2 StereoLCRChorus GUI 346 10.5.3 StereoLCRChorus.h File 346 10.5.4 StereoLCRChorus.cpp File 347 10.6 More Modulated Delay Algorithms 350 10.6.1 Stereo Cross-Flanger/Chorus (Korg Triton®) 350 10.6.2 Multi-Flanger (Sony DPS-M7®) 350 10.6.3 Bass Chorus 350 10.6.4 Dimension-Style (Roland Dimension D®) 351 10.6.5 Deca-Chorus (Sony DPS-M7®) 354 Bibliography 355 Chapter 11: Reverb Algorithms 357 11.1 Anatomy of a Room Impulse Response 358 11.1.1 RT60: The Reverb Time 359 11.2 Echoes and Modes 360 11.3 The Comb Filter Reverberator 364 11.4 The Delaying All-Pass Filter Reverberator 368 11.5 More Delaying All-Pass Filter Reverberators 370 11.6 Schroeder's Reverberator 372 11.7 The Low-Pass Filter-Comb Reverberator 373 11.8 Moorer's Reverberator 375 11.9 Stereo Reverberation 376 11.10 Gardner's Nested APF Reverberators 377 xiv Contents

11.11 Modulated APF and Comb/APF Reverb 381 11.12 Dattorro's Plate Reverb 382 11.13 Generalized Feedback Delay Network Reverbs 385 11.14 Other FDN Reverbs 389 11.15 An Example Room Reverb 391 11.16 RackAFX Stock Objects 394 11.16.1 COnePoleLPF 394 11.16.2 CDelay 395 11.16.3 CCombFilter 396 11.16.4 CLPFCombFilter 396 11.16.5 CDelayAPF 398 11.17 Design the Room Reverb 398 11.17.1 Project: Reverb 398 11.17.2 Reverb GUI 398 11.17.3 Reverb.h 402 11.17.4 Reverb.cpp 403 11.18 Challenge 408 Bibliography 409 References 409

Chapter 12: Modulated Filter Effects 411 12.1 Design a Mod Filter Plug-In: Part I Modulated fc 412 12.1.1 Project: ModFilter 413 12.1.2 ModFilter GUI 413 12.1.3 ModFilter.h File 413 12.1.4 ModFilter.cpp File 416 12.2 Design a Mod Filter Plug-In: Part II, Modulated fc, Q 419 12.2.1 ModFilter GUI 419 12.2.2 ModFilter.h File 419 12.2.3 ModFilter.cpp File 420 12.3 Design a Mod Filter Plug-In: Part III, Quad-Phase LFOs 423 12.3.1 ModFilter GUI 423 12.3.2 ModFilter.cpp File 424 12.4 Design an Envelope Follower Plug-In 425 12.5 Envelope Detection 428 12.5.1 Project EnvelopeFollower 430 12.5.2 EnvelopeFollower GUI 430 12.5.3 EnvelopeFollower.h File 431 12.5.4 EnvelopeFollower.cpp File 432 12.6 Design a Plug-In 436 12.6.1 Project Phaser 440 12.6.2 Phaser GUI 440 12.6.3 Phaser.hFile 440 12.6.4 Phaser.cpp File 441 Contents xv

12.7 Design a Stereo Phaser with Quad-Phase LFOs 446 12.7.1 Phaser GUI 446 12.7.2 Phaser.hFile 446 12.7.3 Phaser.cpp File 447 Bibliography 451 References 451

Chapter 13: Dynamics Processing 453 13.1 Design a Compressor/Limiter Plug-In 457 13.1.1 Project: DynamicsProcessor 458 13.1.2 DynamicsProcessor: GUI 458 13.1.3 DynamicsProcessor.h File 459 13.1.4 DynamicsProcessor.cpp File 460 13.1.5 DynamicsProcessor.cpp File 465 13.2 Design a Downward Expander/Gate Plug-In 466 13.2.1 DynamicsProcessor.h File 466 13.2.2 DynamicsProcessor.cpp File 466 13.3 Design a Look-Ahead Compressor Plug-In 468 13.3.1 DynamicsProcessor: GUI 469 13.3.2 DynamicsProcessor.h File 470 13.3.3 DynamicsProcessor.cpp File 470 13.4 Stereo-Linking the Dynamics Processor 472 13.4.1 DynamicsProcessor: GUI 472 13.4.2 DynamicsProcessor.cpp File 473 13.5 Design a Spectral Compressor/Expander Plug-In 475 13.5.1 Project: SpectralDynamics 476 13.5.2 SpectralDynamics: GUI 476 13.5.3 Additional Slider Controls 477 13.5.4 Spectral Dynamics Buttons 477 13.5.5 Spectral Dynamics Metering 477 13.5.6 SpectralDynamics.h File 478 13.5.7 SpectralDynamics.cpp File 479 13.6 Alternate Side-Chain Configurations 486 Bibliography 487 References 487

Chapter 14: Miscellaneous Plug-Ins 489 14.1 Design a Tremolo/Panning Plug-In 489 14.1.1 Project: TremoloPanner 490 14.1.2 TremoloPanner: GUI 490 14.2 Design a Ring Modulator Plug-In 494 14.2.1 Project: RingModulator 494 14.2.2 RingModulator: GUI 494 14.2.3 RingModulator.h File 495 14.2.4 RingModulator.cpp File 495 xvi Contents

14.3 Design a Wave Shaper Plug-In 497 14.3.1 Project: WaveShaper 498 14.3.2 WaveShaper: GUI 498 Bibliography 500

Appendix A: The VST® and AU® Plug-In APIs 507 A. 1 Compiling as a VST Plug-In in Windows 501 A.2 Wrapping Your RackAFX Plug-In 503 A.3 Comparison of Objects/Methods/GUIs 505 A.4 VST Plug-In without Wrapping 506 A.4.1 Default GUI 507 A.4.2 Signal Processing 509 A.5 VST Plug-In with RackAFX Wrapping 512 A.5.1 Default GUI 512 A.6 AU Overview 514 A.6.1 Default GUI 515 A.6.2 Signal Processing 516

Appendix B: More RackAFX Controls and GUI Designer. 579 B. l The Alpha Wheel and LCD Control 519 B.2 The Vector Joystick Control 521 B.3 Using the sendUpdateGUI() Method 525 B.4 Using GUI Designer 525

Index 537