Designing Audio Effect Plugins in C++ For AAX, AU, and VST3 With DSP Theory

Second Edition

Will C. Pirkle

13 Routledge g^^ Taylor & Francis Croup

NEW YORK AND LONDON Contents

List of Figures xxiii List of Tables xliii Preface xlvi

Chapter 1: Introduction 1 1.1 Using This Book 1 1.2 Fundamentals of 2 1.2.1 Acquisition of Audio Samples 3 1.3 Reconstruction of the Analog Signal 4 1.4 Numerical Representation of Audio Data 5 1.5 Analytical DSP Test Signals 6 1.5.1 DC and Step (0 Hz) 7 1.5.2 Nyquist 8 1.5.3 >/2Nyquist 8 1.5.4 ^Nyquist 8 1.5.5 Impulse 8 1.6 Signal Processing Algorithms 8 1.6.1 Bookkeeping 10 1.6.2 The One-Sample 10 1.6.3 Multiplication With a Scalar Value 11 1.6.4 Addition and Subtraction 12 1.6.5 Some Algorithm Examples and Difference Equations 12 1.6.5.1 Gain, Attenuation and Phase Inversion 13 1.7 1st Order Feed-Forward and Algorithms 14 1.8 Bibliography 14 Chapter 2: Anatomy of an Audio Plugin 15 2.1 Plugin Packaging: Dynamic-Link Libraries (DLLs) 15 2.2 The Plugin Description: Simple Strings 17 2.2.1 The Plugin Description: Features and Options 18 2.3 Initialization: Defining the Plugin Parameter Interface 18 2.3.1 Initialization: Defining Channel I/O Support 20 2.3.2 Initialization: Sample Rate Dependency 21 2.4 Processing: Preparing for Audio Streaming 21 2.4.1 Processing: Audio Signal Processing (DSP) 21 2.5 Mixing Parameter Changes With Audio Processing 23

vii vlii Contents

2.5.1 Plugin Variables and Plugin Parameters 23 2.5.2 Parameter Smoothing 26 2.5.3 Pre and Post-Processing Updates 27 2.5.4 VST3 Sample Accurate Updates 27 2.5.5 Multi-Threaded Software 28 2.6 Monolithic Plugin Objects 30 2.7 Bibliography 31

Chapter 3: VST3 Programming Guide 32 3.1 Setting Up the VST3 SDK 32 3.1.1 VST3 Sample Projects 32 3.1.2 VST3 Documentation 33 3.2 VST3 Architecture and Anatomy 33 3.2.1 Single vs. Dual Component Architectures 34 3.2.2 VST3 Base Classes 35 3.2.3 MacOS Bundle ID 35 3.2.4 VST3 Programming Notes 35 3.2.5 VST3 and the GUID 36 3.2.6 VST3 Plugin Class Factory 37 3.3 Description: Plugin Description Strings 37 3.4 Description: Plugin Options/Features 38 3.4.1 Side Chain Input 38 3.4.2 Latency 38 3.4.3 Tail Time 38 3.4.4 Custom GUI 39 3.4.5 Factory Presets and State Save/Load 39 3.4.6 VST3 Support for 64-bit Audio 41 3.5 Initialization: Defining Plugin Parameters 41 3.5.1 Thread-Safe Parameter Access 43 3.5.2 Initialization: Defining Plugin Channel I/O Support 44 3.5.3 Initialization: Channel Counts and Sample Rate Information 45 3.6 The Buffer Process Cycle 45 3.6.1 Processing: Updating Plugin Parameters From GUI Controls 47 3.6.2 Processing: Resetting the Algorithm and Preparing for Streaming 49 3.6.3 Processing: Accessing the Audio Buffers 49 3.6.4 Processing: Writing Output Parameters 50 3.6.5 Processing: VST3 Soft Bypass 51 3.7 Destruction/Termination 51 3.8 Retrieving VST3 Host Information 52 3.9 Validating Your Plugin 52 3.10 Using ASPiK to Create VST3 Plugins 52 3.11 Bibliography 53

Chapter 4: AU Programming Guide 54 4.1 Setting Up the AU SDK 54 4.1.1 AU Sample Projects 54 4.1.2 AU Documentation 54 Contents ix

4.2 AU Architecture and Anatomy 55 4.2.1 AU Base Classes 56 4.2.2 MacOS Bundle ID 56 4.2.3 AU Programming Notes 56 4.3 Description: Plugin Description Strings 58 4.4 Description: Plugin Options/Features 59 4.4.1 Side Chain Input 59 4.4.2 Latency 60 4.4.3 Tail Time 60 4.4.4 Custom GUI 60 4.4.5 Factory Presets and State Save/Load 60 4.5 Initialization: Defining Plugin Parameters 61 4.5.1 Thread-Safe Parameter Access 64 4.5.2 Initialization: Defining Plugin Channel I/O Support 64 4.5.3 Initialization: Channel Counts and Sample Rate Information 65 4.6 The Buffer Process Cycle 66 4.6.1 Processing: Updating Plugin Parameters From GUI Controls 67 4.6.2 Processing: Resetting the Algorithm and Preparing for Streaming 68 4.6.3 Processing: Accessing the Audio Buffers 68 4.6.4 Processing: Writing Output Parameters 70 4.7 The AU/GUI Connection 70 4.7.1 Cocoa's Flat Namespace 72 4.7.2 The AU Event Listener System 72 4.7.2.1 The Event Lister Dispatch Callback Function 73 4.7.2.2 Creating the AU Event Listener 74 4.7.2.3 Destroying the Event Listener 75 4.8 Destruction/Termination 76 4.9 Retrieving AU Host Information 76 4.10 Validating Your Plugin 77 4.11 Using ASPiK to Create AU Plugins 77 4.12 Bibliography 77 Chapter 5: AAX Native Programming Guide 78 5.1 Setting Up the AAX SDK 79 5.1.1 AAX Sample Projects 79 5.1.2 AAX Documentation 79 5.2 AAX Architecture and Anatomy 80 5.2.1 AAX Model-Algorithm Synchronization 81 5.2.2 AAX Base Classes 82 5.2.3 MacOS Bundle ID 82 5.2.4 AAX Programming Notes 83 5.2.5 AAX Class Factory 83 5.2.6 AAX Effect Categories 83 5.2.7 AAX Algorithms: Channel-Processing Functions 84 5.2.8 AAX Algorithm Data 84 5.2.9 Algorithm Data Contents 85 Contents

5.3 Description: Plugin Description Strings 86 5.3.1 Description: Defining AAX Algorithms 88 5.4 Description: Plugin Options/Features 90 5.4.1 Side Chain Input 90 5.4.2 Latency 91 5.4.3 Tail Time 91 5.4.4 Custom GUI 91 5.4.5 Factory Presets and State Save/Load 92 5.4.6 AAX Notification System 92 5.4.7 AAX Custom Data 93 5.4.8 AAX EQ and Dynamics Curves 93 5.4.9 AAX Gain Reduction Meter 93 5.5 Initialization: Defining Plugin Parameters 94 5.5.1 Thread-Safe Parameter Access 97 5.5.2 Initialization: Defining Plugin Channel I/O Support 97 5.5.3 Initialization: Channel Counts and Sample Rate Information 97 5.6 The Buffer Process Cycle 98 5.6.1 Processing: Updating Plugin Parameters From GUI Controls 101 5.6.2 Processing: Resetting the Algorithm and Preparing for Streaming 101 5.6.3 Processing: Accessing the Audio Buffers 102 5.6.4 Processing: Writing Output Parameters 103 5.6.5 Processing: AAX Soft Bypass 104 5.7 Destruction/Termination 104 5.8 Retrieving AAX Host Information 104 5.9 Validating Your Plugin 105 5.10 Using ASPiK to Create AAX Plugins 106 5.11 Bibliography 106

Chapter 6: ASPiK Programming Guide 107 6.1 Plugin Kernel Portability and Native Plugin Shells 108 6.2 Organizing the SDKs: AAX, AU, and VST 111 6.2.1 Your C++Compiler Ill 6.2.2 Setting Up the AAX SDK Ill 6.2.3 Setting Up the AU SDK 112 6.2.4 Setting Up the VST SDK 112 6.2.5 Creating the Universal SDK Folder Hierarchy 112 6.2.6 Adding the VSTGU14 Library 112 6.2.7 CMake 113 6.3 Creating a Plugin Project With ASPiKreator: URFilters 114 6.3.1 ASPiK Project Folders 115 6.3.2 Running CMake 117 6.4 Adding Effect Objects to the PluginCore 117 6.4.1 The PluginCore Constructor 118 6.4.2 URFilters: GUI Parameter Lists 119 6.4.3 Parameter Smoothing 120 6.4.4 Handling the String-List Parameters 121 6.4.5 URFilters: Declaring Plugin Variables 123 Contents xi

6.4.6 Parameter Object Enumerations for Attributes 123 6.4.6.1 Continuous Floating Point Parameters and Discrete Integer Parameters 125 6.4.6.2 String-List Parameters 126 6.4.7 IIRFilters: Object Declarations and Reset 127 6.4.8 IIRFilters: GUI Parameter Updates 128 6.4.9 IIRFilters: Processing Audio Data 128 6.4.10 Buffer Pre-Processing 130 6.4.11 Buffer Post-Processing 130 6.4.12 Buffer vs. Frame Processing 131 6.4.13 processAudioFrame: Information About the Frame 132 6.4.14 processAudioFrame: Input and Output Samples 133 6.5 Defining Factory Presets 135 6.6 Basic Plugin GUI Design With ASPiK's PluginGUI 136 6.7 GUI Design With VSTGUI4 137 6.7.1 Modifier Keys 138 6.7.2 Zooming (Scaling the GUI) 138 6.7.3 Reserved Control Tags 138 6.7.4 VSTGUI4 Objects 139 6.7.5 Creating a GUI With VSTGUI 139 6.7.6 Important GUI Designer Terms 140 6.8 VSTGUI C++ Objects 141 6.8.1 Basic GUI Design 142 6.8.2 The GUI Designer Workspace 144 6.8.3 Changing Your GUI Canvas Size 146 6.8.4 Setting Up the Control Tags 146 6.8.5 Importing the Graphics Files 146 6.8.6 Assembling the GUI 147 6.8.7 Setting the Background 147 6.8.8 Adding the GUI Elements 147 6.8.9 Saving and Re-Building 148 6.8.10 Scaling the GUI 148 6.8.11 More ASPiK Features 149 6.9 Bibliography 149 Chapter 7: Using RackAFX to Create ASPiK Projects 150 7.1 Installing RackAFX 151 7.2 Getting Started With RackAFX 151 7.3 Setting Up Your Project Preferences and Audio Hardware 153 7.4 Installing VSTGUI4 153 7.5 Creating a Project and Adding GUI Controls 153 7.5.1 Numerical Continuous Controls 155 7.5.2 String-List Controls 156 7.5.3 Meters 158 7.6 Anatomy of Your RackAFX Project 159 7.7 Testing Audio Algorithms With RackAFX 161 7.8 RackAFX Impulse Convolver and FIR Design Tools 163 xii Contents

7.9 Designing Your Custom GUI 163 7.10 Exporting Your ASPiK. Project 165 7.11 Bibliography 166 Chapter 8: C++ Conventions and How to Use This Book 167 8.1 Three Types of C++Objects 167 8.1.1 Effect Objects Become Framework Object Members 168 8.1.2 All Effect Objects and Most DSP Objects Implement Common Interfaces 169 8.1.3 DSP and Effect Objects Use Custom Data Structures for Parameter Get/Set Operations 171 8.1.4 Effect Objects Accept Native Data From GUIs 173 8.1.5 Effect Objects Process Audio Samples 173 8.1.5.1 Series Objects 173 8.1.5.2 Parallel Objects 174 8.1.6 Effect Objects Optionally Process Frames 174 8.2 Book Projects 175 8.2.1 ASPiK Users 175 8.2.2 JUCE and Other Non-ASPiK Users 175 8.2.3 A Sample Plugin Project: GUI Control Definition 176

Chapter 9: How DSP Filters Work (Without Complex Math) 178 9.1 and Phase Response Plots 178 9.2 Frequency and Phase Adjustments From Filtering 179 9.3 1st Order Feed-Forward Filter 181 9.4 1st Order Feedback Filter 189 9.5 Final Observations 191 9.6 Homework 193 9.7 Bibliography 193

Chapter 10: Basic DSP Theory 194 10.1 The Complex Sinusoid 194 10.2 Complex Math Review 196 10.3 Time Delay as a Math Operator 198 10.4 The Sampled Sinusoid 199 10.5 1st Order Feed-Forward Filter Revisited 200 10.5.1 Negative 201 10.6 Evaluating the Transfer Function H(co) 203 10.6.1 DC(OHz) 205 10.6.2 Nyquist (TI) 205 10.6.3 Vi Nyquist (jt/2) 205 10.6.4 VA Nyquist (JI/4) 206 10.7 Evaluating ejm 207 10.8 The z Substitution 207 10.9 The z Transform 208 10.10 The z Transform of Signals 210 10.11 The z Transform of Difference Equations 211 10.12 The z Transform of an Impulse Response 212 10.13 The Zeros of the Transfer Function 213 Contents xiii

10.14 Estimating the Frequency Response: Zeros 214 10.15 Filter Gain Control 214 10.16 1st Order Feedback Filter Revisited 215 10.16.1 Step 1: Take the z Transform of the Difference Equation 216 10.16.2 Step 2: Fashion the Difference Equation into a Transfer Function 216 10.16.3 Step 3: Factor out a0as the Scalar Gain Coefficient 217 10.17 The Poles of the Transfer Function 217 10.17.1 Step4: Estimate the Frequency Response 218 10.17.2 Step 5: Perform Direct Evaluation of the Frequency Response 219 10.17.3 DC(OHz) 220 10.17.4 Nyquist(Tt) 220 10.17.5 Vi Nyquist (n/2) 220 10.17.6 V* Nyquist (re/4) 221 10.18 2nd Order Feed-Forward Filter 222 10.18.1 Step 1 and Step 2: Take the z Transform of the Difference Equation and Fashion it into a Transfer Function 222 10.18.2 Step 3: Factor Out a0 as the Scalar Gain Coefficient 222 10.18.3 Step 4: Estimate the Frequency Response 223 10.18.4 Step 5: Direct Evaluation 227 10.18.5 DC(OHz) 228 10.18.6 Nyquist (n) 228 10.18.7 Vi Nyquist (TI/2) 229 10.18.8 1/4 Nyquist (rr/4) 229 10.18.9 z Transform of Impulse Response 230 10.19 2nd Order Feedback Filter 231 10.19.1 Step 1, Step 2, and Step 3: Take the z Transform of the Difference Equation to Get the Transfer Function, Then Factor Out a0 as the Scalar Gain Coefficient 231 10.19.2 Step 4: Estimate the Frequency Response 232 10.19.3 Step 5: Direct Evaluation 236 10.19.4 DC(OHz) 237 10.19.5 Exercise 238 10.20 1st Order Pole/Zero Filter: The Shelving Filter 238 10.20.1 Step 1, Step 2, and Step 3: Take the z Transform of the Difference Equation to Get the Transfer Function, Then Factor Out a0 as the Scalar Gain Coefficient 239 10.20.2 Step 4: Estimate the Frequency Response 239 10.20.3 Step 5: Direct Evaluation 243 10.20.4 DC(OHz) 243 10.20.4.1 Exercise 244 10.21 The Biquadratic Filter 245 10.21.1 Step 1, Step 2, and Step 3: Take the z Transform of the Difference Equation to Get the Transfer Function, Then Factor Out a0 as the Scalar Gain Coefficient 245 10.21.2 Step 4: Plot the Poles and Zeros of the Transfer Function 246 10.21.3 The a^and bM Coefficient Naming Conventions 248 10.22 Other Biquadratic Structures 248 xiv Contents

10.23 C++ DSP Object: Biquad 250 10.23.1 Biquad: Enumerations and Data Structure 250 10.23.2 Biquad: Members 251 10.23.3 Biquad: Programming Notes 251 10.24 Homework 255 10.25 Bibliography 256

Chapter 11: Audio Filter Designs: HR Filters 257 11.1 Direct z-Plane Design 257 11.1.1 Simple Resonator 258 11.1.2 Smith-Angell Resonator 260 11.2 Analog Filter to Digital Filter Conversion 261 11.2.1 Example 266 11.3 Audio Biquad Filter Designs 268 11.3.1 The Audio Biquad Filter Structure 269 11.3.2 Classical Filters 270 11.3.2.1 1st Order LPF and HPF 270 11.3.2.2 2nd Order LPF and HPF 271 11.3.2.3 2nd Order BPF and BSF 272 11.3.2.4 2nd Order Butterworth LPF and HPF 273 11.3.2.5 2nd Order Butterworth BPF and BSF 274 11.3.2.6 2nd Order Linkwitz-Riley LPF and HPF 274 11.3.2.7 1st and 2nd Order APF 275 11.3.2.8 1st Order Shelving Filters 277 11.3.2.9 Low Shelving 277 11.3.2.10 High Shelf. 278 11.3.2.11 2nd Order Parametric EQ Filter: Non-Constant-Q 278 11.3.2.12 2nd Order Parametric EQ Filter: Constant-Q 279 11.4 Poles and Zeros at Infinity 280 11.4.1 1st Order All Pole Filter 282 11.4.2 2nd Order All Pole Filter: The MIDI Manufacturer's Association LPF 283 11.4.3 Vicanek's Analog Matched Magnitude 2nd Order LPF 285 11.4.4 Vicanek's Analog Matched Magnitude 2nd Order BPF 286 11.5 The Impulse Invariant Transform Method 288 11.5.1 Impulse Invariant 1st Order LPF 288 11.5.2 Impulse Invariant 2nd Order LPF 289 11.6 C++ Effect Object: AudioFilter 292 11.6.1 AudioFilter: Enumerations and Data Structure 292 11.6.2 AudioFilter: Members 292 11.6.3 AudioFilter: Programming Notes 293 11.7 Chapter Plugin: IIRFilters 296 11.7.1 IIRFilters: GUI Parameters 296 11.7.2 IIRFilters: Object Declarations and Reset 297 11.7.3 IIRFilters: GUI Parameter Update 297 11.7.4 IIRFilters: Process Audio 298 11.8 Homework 298 11.9 Bibliography 300 Contents

Chapter 12: Audio Filter Designs: Wave Digital and Virtual Analog 307 12.1 Wave Digital Filters 301 12.1.1 Scattering Parameters and WDFs 302 12.1.2 Simulating WDF Components 303 12.1.2.1 WDF Resistor 305 12.1.2.2 WDF Inductor 305 12.1.2.3 WDF Capacitor 305 12.1.3 Simulating WDF Component Interconnections 306 12.2 WDF Adaptors 308 12.2.1 Series Adaptors 309 12.2.2 Parallel Adaptors 310 12.2.3 More Component Combinations 311 12.2.4 Signal Flow Through a WDF Circuit 313 12.2.5 Ladder Filter WDF Library Conventions 314 12.2.6 Filter Source/Termination Impedance Matching 315 12.2.7 Bilinear Transform Frequency Warping 316 12.3 Designing Digital Ladder Filters With the WDF Library 317 12.3.1 Components and Component Combinations 317 12.3.2 Adaptors 317 12.3.3 WDF Ladder Filter Design: 3rd Order Butterworth LPF 318 12.3.4 WDF Ladder Filter Design: 3rd Order Bessel BSF 321 12.3.5 WDF Ladder Filter Design: 6th Order Constant-K BPF 324 12.3.6 WDF Ladder Filter Design: Ideal 2nd Order RLC Filters 325 12.4 Zavalishin's Virtual Analog Filters 330 12.4.1 1st Order VA Filters 330 12.4.2 2nd Order State Variable VA Filter 332 12.5 C++ DSP Object: ZVAFilter 336 12.5.1 ZVAFilter. Enumerations and Data Structure 336 12.5.2 ZVAFilter. Members 337 12.5.3 ZAFilter. Programming Notes 337 12.6 C++DSP Objects: WDF Ladder Filter Library 341 12.6.1 WDFIdealRLCxxx: Enumerations and Data Structure 342 12.6.2 WDFIdealRLCxxx: Members 342 12.6.3 WDFIdealRLCxxx: Programming Notes 342 12.7 Chapter Plugin: RLCFilters 344 12.7.1 RLCFilters: GUI Parameters 345 12.7.2 RLCFilters: Object Declarations and Reset 346 12.7.3 RLCFilters: GUI Parameter Update 346 12.7.4 RLCFilters: Process Audio 347 12.8 Homework 348 12.9 Bibliography 350 Chapter 13: Modulators: LFOs and Envelope Detectors 357 13.1 LFO Algorithms 351 13.1.1 The lAudioSignalGenerator Interface 353 13.1.2 C++ DSP Object: LFO 354 13.1.3 LFO: Enumerations and Data Structure 354 xvi Contents

13.1.4 LFO: Members 354 13.1.5 LFO: Programming Notes 355 13.2 Envelope Detection 357 13.2.1 C++ DSP Object: AudioDetector 359 13.2.2 AudioDetector. Enumerations and Data Structure 360 13.2.3 AudioDetector: Members 360 13.2.4 AudioDetector: Programming Notes 361 13.3 Modulating Plugin Parameters 364 13.3.1 Modulation Range, Polarity, and Depth 364 13.3.2 Modulation With the Envelope Detector 365 13.4 C++ Effect Object: EnvelopeFollower 367 13.4.1 EnvelopeFollower: Enumerations and Data Structure 367 13.4.2 EnvelopeFollower: Members 368 13.4.3 EnvelopeFollower: Programming Notes 368 13.5 Chapter Plugin 1: ModFilter 370 13.5.1 ModFilter: GUI Parameters 370 13.5.2 ModFilter: Object Declarations and Reset 371 13.5.3 ModFilter: GUI Parameter Update 372 13.5.4 ModFilter: Process Audio 372 13.6 The Effect 373 13.6.1 C++ Effect Object: PhaseShifter 375 13.6.2 PhaseShifter: Enumerations and Data Structure 376 13.6.3 PhaseShifter: Members 376 13.6.4 PhaseShifter: Programming Notes 377 13.7 Chapter Plugin 2: Phaser 380 13.7.1 Phaser: GUI Parameters 380 13.7.2 Phaser: Object Declarations and Reset 381 13.7.3 Phaser: GUI Parameter Update 381 13.7.4 Phaser: Process Audio 382 13.8 Homework 382 13.9 Bibliography 383

Chapter 14: Delay Effects and Circular Buffers 384 14.1 The Basic Digital Delay 386 14.2 Digital Delay With Wet/Dry Mix 389 14.3 An Efficient Circular Buffer Object 394 14.3.1 C++ DSP Object: CircularBuffer With Fractional Delay 397 14.3.2 CircularBuffer: Enumerations and Data Structure 398 14.3.3 CircularBuffer: Members 398 14.3.4 CircularBuffer: Programming Notes 399 14.4 Basic Delay Algorithms 401 14.4.1 Stereo Delay With Feedback 401 14.4.2 Stereo Ping-Pong Delay 401 14.5 C++ Effect Object: AudioDelay 403 14.5.1 AudioDelay: Enumerations and Data Structure 403 14.5.2 AudioDelay: Members 404 14.5.3 AudioDelay: Programming Notes 405 Contents xvii

14.6 Chapter Plugin: StereoDelay 408 14.6.1 StereoDelay: GUI Parameters 408 14.6.2 StereoDelay: Object Declarations and Reset 409 14.6.3 StereoDelay: GUI Parameter Update 409 14.6.4 StereoDelay: Process Audio 410 14.6.5 Synchronizing the Delay Time to BPM 410 14.6.5.1 ASPiK Users: BPM and Time Signature Information 410 14.7 More Delay Algorithms 411 14.7.1 Analog Modeling Delay 411 14.7.2 Multi-Tap Delay 412 14.7.3 LCR Delay 412 14.7.4 TC Electronics TC-2290 Dynamic Delay 412 14.8 Homework 414 14.9 Bibliography 415 Chapter 15: Modulated Delay Effects 416 15.1 The Flanger/Vibrato Effect 416 15.1.1 Stereo Flanger 418 15.2 The Effect 419 15.2.1 Stereo Chorus 421 15.3 C++ Effect Object: ModulatedDelay 422 15.3.1 ModulatedDelay: Enumerations and Data Structure 422 15.3.2 ModulatedDelay: Members 422 15.3.3 ModulatedDelay: Programming Notes 423 15.4 Chapter Plugin: ModDelay 426 15.4.1 ModDelay: GUI Parameters 426 15.4.2 ModDelay: Object Declarations and Reset 427 15.4.3 ModDelay: GUI Parameter Update 427 15.4.4 ModDelay: Process Audio 428 15.5 More Modulated Delay Algorithms 428 15.5.1 Korg Stereo Cross-Feedback Flanger/Chorus 428 15.5.2 Sony DPS-M7 Multi-Flanger 428 15.5.3 Bass Chorus 430 15.5.4 Dimension-Style Chorus (Roland Dimension D) 430 15.5.5 Sony DPS-M7 Deca Chorus 431 15.6 Homework 432 15.7 Bibliography 433 Chapter 16: Audio Filter Designs: FIR Filters 434 16.1 The Impulse Response Revisited: Convolution 434 16.2 FIR Filter Structures 437 16.3 Generating Impulse Responses 439 16.3.1 Impulse Responses of Acoustic Environments 439 16.3.2 Impulse Responses of Speakers and Cabinets 439 16.3.3 Impulse Responses by Frequency Sampling 439 16.3.4 Sampling Arbitrary Frequency Responses 439 16.3.4.1 Linear Phase FIR Using the Frequency Sampling Method 441 xviii Contents

16.3.5 Sampling Analog Filter Frequency Responses 441 16.3.6 Sampling Ideal Filter Frequency Responses 442 16.4 The Optimal/Parks-McClellan Method 444 16.5 Other FIR Design Methods 445 16.6 C++ DSP Function: FreqSample 446 16.7 C++ DSP Function: CalculateAnalogMagArray 446 16.7.1 calculateAnalogMagArray: Enumerations and Data Structure 447 16.7.2 calculateAnalogMagArray: Calculations 447 16.8 C++ DSP Object: LinearBuffer 448 16.8.1 LinearBuffer: Enumerations and Data Structure 448 16.8.2 LinearBuffer: Members 448 16.8.3 LinearBuffer: Programming Notes 449 16.9 C++ DSP Object: ImpulseConvolver 449 16.9.1 ImpulseConvolver: Enumerations and Data Structure 449 16.9.2 ImpulseConvolver: Members 449 16.9.3 ImpulseConvolver: Programming Notes 450 16.10 C++ Effect Object: AnalogFIRFilter 451 16.10.1 AnalogFIRFilter: Enumerations and Data Structure 452 16.10.2 AnalogFIRFilter: Members 452 16.10.3 AnalogFIRFilter: Programming Notes 453 16.11 Chapter Plugin: AnalogFIR 454 16.11.1 AnalogFIR: GUI Parameters 454 16.11.2 AnalogFIR: Object Declarations and Reset 455 16.11.3 AnalogFIR: GUI Parameter Update 456 16.11.4 AnalogFIR: Process Audio 456 16.12 Homework 457 16.13 Bibliography 457 Chapter 17: Reverb Effects 458 17.1 Anatomy of a Room Impulse Response 458 17.1.1 RT60 460 17.2 Echoes and Modes 460 17.3 The Comb Filter Reverberator 464 17.4 The Delaying All-Pass Reverberator 468 17.4.1 Alternate and Nested Delaying APF Structures 470 17.5 Schroeder's Reverberator 471 17.6 The LPF-Comb Reverberator 472 17.7 The Absorbent-APF Reverberator 474 17.8 The Modulated Delay APF 474 17.9 Moorer's Reverberator 475 17.10 Dattorro's Plate Reverb 475 17.11 The Spin Semiconductor® Reverb Tank 477 17.12 Generalized Feedback Delay Network Reverbs 479 17.12.1 Searching for FDN Coefficients 483 17.13 C++DSP Objects: Reverb Objects 483 17.13.1 C++ DSP Object: SimpleDelay 484 Contents xix

17.13.2 SimpleDelay: Custom Data Structure 484 17.13.3 SimpleDelay: Members 484 17.13.4 SimpleDelay: Programming Notes 485 17.13.5 C++ DSP Object: SimpleLPF 486 17.13.6 SimpleLPF: Custom Data Structure 486 17.13.7 SimpleLPF: Members 487 17.13.8 SimpleLPF: Programming Notes 487 17.13.9 C++ DSP Object: CombFilter 488 17.13.10 CombFilter: Custom Data Structure 488 17.13.11 CombFilter: Members 488 17.13.12 CombFilter: Programming Notes 488 17.13.13 C++ DSP Object: DelayAPF 489 17.13.14 DelayAPF: Custom Data Structure 490 17.13.15 DelayAPF: Members 490 17.13.16 DelayAPF Parameters: Programming Notes 491 17.13.17 C++ DSP Object: NestedDelayAPF 492 17.13.18 NestedDelayAPF: Custom Data Structure 492 17.13.19 NestedDelayAPF: Members 493 17.13.20 NestedDelayAPF: Programming Notes 493 17.13.21 C++DSP Object: TwoBandShelvingFilter 494 17.13.22 TwoBandShelvingFilter: Custom Data Structure 494 17.13.23 TwoBandShelvingFilter: Members 494 17.13.24 TwoBandShelvingFilter: Programming Notes 495 17.14 C++ Effect Object: ReverbTank 496 17.14.1 ReverbTank: Enumerations and Data Structure 498 17.14.2 ReverbTank: Members 499 17.14.3 ReverbTank: Programming Notes 499 17.15 Chapter Plugin: Reverb 504 17.15.1 Reverb:G\}\ Parameters 504 17.15.2 Reverb: Object Declarations and Reset 506 17.15.3 Reverb: GUI Parameter Update 506 17.15.4 Reverb: Process Audio 507 17.16 Homework 508 17.17 Bibliography 508

Chapter 18: Dynamics Processing 510 18.1 Compressor Output Calculation 513 18.1.1 Hard-Knee Compressor and Limiter 513 18.1.2 Soft-Knee Compressor and Limiter 514 18.2 Downward Expander Output Calculation 514 18.2.1 Hard-Knee Expander and Gate 514 18.2.2 Soft-Knee Expander 515 18.3 Final Gain Calculation 516 18.4 Stereo-Linked Dynamics Processor 516 18.5 Spectral Dynamics Processing 516 18.6 Parallel Dynamics Processing 518 xx Contents

18.7 Look-Ahead Processing 519 18.8 External Keying 519 18.8.1 ASPiK Users: Side Chain Code 520 18.9 Gain Reduction Metering 521 18.10 Alternate Side Chain Configurations 521 18.11 C++ DSP Object: LRFilterBank 523 18.11.1 LRFilterBank: Enumerations and Data Structure 523 18.11.2 LRFilterBank: Members 523 18.11.3 LRFilterBank: Programming Notes 523 18.12 C++ Effect Object: DynamicsProcessor 525 18.12.1 DynamicsProcessor: Enumerations and Data Structure 525 18.12.2 DynamicsProcessor: Members 526 18.12.3 DynamicsProcessor: Programming Notes 526 18.13 Chapter Plugin: Dynamics 529 18.13.1 Dynamics: GUI Parameters 529 18.13.2 Dynamics: Object Declarations and Reset 530 18.13.3 Dynamics: GUI Parameter Update 530 18.13.4 Dynamics: Process Audio and External Keying 531 18.13.5 Stereo Linking the DynamicsProcessor Objects 532 18.13.6 ASPiK Users: Enabling the Special Pro Tools Gain Reduction Meter 533 18.14 Homework 533 18.15 Bibliography 534

Chapter 19: Nonlinear Processing: Distortion, Tube Simulation, and HF Exciters 535 19.1 Frequency Domain Effects of Nonlinear Processing 536 19.2 Vacuum Tubes 538 19.3 Solid State Distortion 541 19.4 Bit Crushers 542 19.5 High Frequency Exciters 544 19.6 Virtual Bass 545 19.7 Ring Modulation 545 19.8 Nonlinear Processing Functions 547 19.8.1 Asymmetrical Waveshaping 549 19.9 C++ DSP Object: BitCrusher 550 19.9.1 BitCrusher: Enumerations and Data Structure 550 19.9.2 BitCrusher: Members 551 19.9.3 BitCrusher: Programming Notes 551 19.10 C++ DSP Object: DFOscillator 552 19.10.1 DFOscillator: Enumerations and Data Structure 552 19.10.2 DFOscillator: Members 552 19.10.3 DFOscillator: Programming Notes 553 19.11 C++DSP Functions: Waveshapers 554 19.12 C++DSP Object: TriodeClassA 554 19.12.1 TriodeClassA: Enumerations and Data Structure 554 19.12.2 TriodeClassA: Members 555 19.12.3 TriodeClassA: Programming Notes 556 19.13 C++ Effect Object: ClassATubePre 557 Contents xxi

19.13.1 ClassATubePre: Enumerations and Data Structure 557 19.13.2 ClassATubePre: Members 558 19.13.3 ClassATubePre: Programming Notes 558 19.14 Chapter Plugin: TubePreamp.... 560 19.14.1 TubePreamp: GUI Parameters 560 19.14.2 TubePreamp: Object Declarations and Reset 561 19.14.3 TubePreamp: GUI Parameter Update 562 19.14.4 TubePreamp: Process Audio 562 19.15 Bonus Plugin Projects 563 19.16 Homework 563 19.17 Bibliography 563 Chapter 20: FFT Processing: The Phase 564 20.1 The Fourier Series 564 20.2 Understanding How the Fourier Kernel Works 568 20.2.1 Windowing DFT Input Data 572 20.3 The Complete DFT 573 20.4 The FFT 574 20.4.1 Overlap/Add Processing 575 20.4.2 Window Gain Correction 578 20.4.3 FFT and IFFT Magnitude and Phase 578 20.4.4 Using Phase Information 579 20.4.5 Phase Deviation 580 20.4.6 Phase Vocoder Coding 581 20.5 Some Phase Vocoder Effects 583 20.5.1 Robot and Simple Noise Reduction 583 20.5.2 Time Stretching/Shrinking 584 20.5.3 Pitch Shifting 585 20.5.4 Phase Locking 587 20.6 Fast Convolution 590 20.7 Gardner's Fast Convolution 594 20.8 Chapter Objects and Plugins 595 20.9 C++ DSP Object: FastFFT 596 20.9.1 FastFFT: Enumerations and Data Structure 596 20.9.2 FastFFT: Members 596 20.9.3 FastFFT: Programming Notes 596 20.10 C++ DSP Object: PhaseVocoder 598 20.10.1 PhaseVocoder: Enumerations and Data Structure 598 20.10.2 PhaseVocoder: Members 598 20.10.3 PhaseVocoder: Programming Notes 598 20.10.3.1 PhaseVocoder Example: Robotization 601 20.10.3.2 PhaseVocoder Example: NoiseReduction 602 20.11 C++ DSP Object: FastConvolver 602 20.11.1 FastConvolver: Members 602 20.11.2 FastConvolver: Programming Notes 603 20.12 C++ Effect Object: PSMVocoder 605 20.12.1 PSMVocoder: Enumerations and Data Structure 606 xxii Contents

20.12.2 PSMVocoder. Members 607 20.12.3 PSMVocoder. Programming Notes 607 20.13 Chapter Plugin: PitchShifler 610 20.13.1 PitchShifler. GUI Parameters 611 20.13.2 PitchShifler. Object Declarations and Reset 611 20.13.3 PitchShifler GUI Parameter Update 612 20.13.4 PitchShifler Process Audio 612 20.14 Third Party C++DSP Object: TwoStageFFTConvolver 612 20.15 Homework 613 20.16 Bibliography 613 Chapter 21: Displaying Custom Waveforms and FFTs 614 21.1 Custom Views for Plotting Data 614 21.1.1 ASPiK: The GUI Lifecycle and Messaging 615 21.1.2 Multi-threading: The Lock-Free Ring Buffer 617 21.1.3 A Waveform Histogram Viewer 619 21.1.4 An Audio Spectrum Analyzer View 620 Chapter 22: Sample Rate Conversion 624 22A Interpolation: Overview 624 22.1.1 Interpolation: Operations 626 22.1.2 Interpolation: Polyphase Decomposition 627 22.2 Decimation: Overview 629 22.2.1 Decimation: Operations 630 22.2.2 Decimation: Polyphase Decomposition 631 22.3 Polyphase Decomposition Math 632 22.3.1 Type-1 Decomposition 633 22.3.2 Type-2 Decomposition 634 22.3.2.1 What Is the Meaning of "Polyphase?" 635 22.4 C++ DSP Objects: Interpolator andDecimator 636 22.4.1 C++ DSP Object: Interpolator 637 22.4.2 Interpolator. Enumerations and Data Structure 638 22.4.3 Interpolator. Members 638 22.4.4 Interpolator. Programming Notes 639 22.4.5 C++ DSP Object: Decimator 639 22.4.6 Decimator. Enumerations and Data Structure 640 22.4.7 Decimator. Members 640 22.4.8 Decimator: Programming Notes 640 22.5 Chapter Plugin: TubePreamp Revisited 641 22.6 Homework 643 22.7 Bibliography 643 Index 644