NokiMo
luxcache
luxcache

patreon


AUDIO ARCHITECTURE MASTERCLASS - Part 2: Max & gen~ for Signal Processing, Distortion & Filters with fendoap

AUDIO ARCHITECTURE MASTERCLASS

Part 2: Max & gen~ for Signal Processing, Distortion & Filters
with fendoap

In this Lux Cache article/tutorial series, we delve into the intricate world of ‘audio architecture’', exploring the complex interplay between digital audio creation and music technology. By examining the multifaceted systems and frameworks that shape the digital music landscape, this series illuminates the myriad ways in which music is composed, performed, and perceived in the digital age. In this chapter, Japanese music technologist & developer fendaop explores the practical application of Max and gen~ in signal processing, with a particular focus on distortion and filters. This comprehensive guide delves into the intricacies of digital audio creation and music technology,, the generation of harmonics in relation to waveform symmetry and their effects on sound quality, and using gen~ to demonstrate the creation and manipulation of biquad filters. The article balances theoretical insights with practical examples, including block diagrams and frequency response curves, catering to both novices and seasoned professionals.

This tutorial is available as a Patreon text post and a preferred .pdf document format. We ask you kindly to not share Lux Cache content outside of the Patreon, our contributors rely on your donations.

~

CONTENTS

1: SAFETY MEASURES 1

2: DISTORTION AND ASYMMETRY 3

3.1: INTRODUCTION TO GEN~ AND BLOCK DIAGRAMS 6

3.2: BIQUAD FILTERS AND THEIR CONSTRUCTION 8

3.3: CALCULATION OF BIQUAD FILTER COEFFICIENTS 12

3.4: DRAWING THE FREQUENCY RESPONSE OF BIQUAD FILTERS 19

4: CONCLUSION 24


1: SAFETY MEASURES

First, before starting any work, it's important to explain the necessity of inserting a high-pass filter and a clip before the output for the protection of speakers and equipment. As shown in Figure 1, placing "cross~ 5" and "clip~ -1 1" before the output can serve as a basic safety measure. In Max, there is a risk of accidentally producing a large signal due to incorrect connections or parameter settings. Therefore, working with a low volume and avoiding headphones are good safety practices to follow.

Figure 1: safety.maxpat

First, let’s discuss "clip~ -1 1." In Max, it is necessary to keep the output signal within the range of -1 to 1. Since objects like “ezdac~” and “dac~” in Max do not have built-in limiters, outputting signals beyond the -1 to 1 range can potentially damage speakers and equipment. Therefore, we insert a clip~ object before the output to limit it. Figure 2 shows how a sine wave with an amplitude of -1.5 to 1.5 is altered by clip~. Clip~ not only serves as a safety measure but also distorts the waveform, generating harmonics. As the amplitude of the input sine wave or waveform is increased, the shape gradually approaches that of a square wave. Distortion, particularly in relation to asymmetric waveforms, will be discussed later.

Next, let’s explain "cross~ 5." Cross~ is an object that provides both high-pass and low-pass filter outputs. Here, we are using cross~ as a high-pass filter at 5 Hz. Signals can sometimes include a DC component, which is a constant bias in the signal to either the positive or negative side. This bias can cause abrupt clicking noises when turning the output on or off and can stress the equipment. Therefore, a very low-frequency high-pass filter is used to remove the DC component. The DC component can be thought of as an extremely low-frequency sound. As the frequency is reduced, the waveform eventually stops oscillating and becomes a DC component. Hence, a high-pass filter can be used to remove it. By using a high-pass filter at a frequency that does not affect the audible range, we can cut the DC component. In Figure 2, the sine wave is modified by adding a DC component with "sig~ 0.5," and then the DC component is removed using the high-pass filter.

Figure 2; safety.maxpat

2: DISTORTION AND ASYMMETRY

Having discussed clip~, let's now talk about distortion. While clip~ is a safety measure, inputting a large signal into it results in distortion and the generation of harmonics. These harmonics, when the waveform is symmetrical, produce odd harmonics. If the waveform is asymmetrical, both odd and even harmonics are generated. For example, in Figure 3, we compare the harmonic spectrum of a symmetric "clip~ -1 1" and an asymmetric "clip~ -0.9 0.9" when a sine wave with an amplitude of -2 to 2 is input. In the symmetric clip, only odd harmonics are added, whereas in the asymmetric clip, even harmonics are also present.

Figure 3: asym_distortion.maxpat

Why is this the case? Let's consider specifically the case of the 2nd harmonic (even) and the 3rd harmonic (odd). For instance, Figures 4 and 5 show what happens when the 2nd and 3rd harmonics are superimposed on the fundamental frequency, respectively. Consider whether an asymmetric waveform would remain the same if roughly inverted.

Figure 4

Figure 5

Take the 2nd harmonic as an example. Looking at the section within the green frame in Figure 6, while the shape of the fundamental frequency inverts between top and bottom, the shape of the 2nd harmonic remains the same. When these waveforms are added, combinations like "same + same" and "opposite + same" are formed, resulting in asymmetry.

Figure 6

Now consider the 3rd harmonic. Within the green frame, if the fundamental frequency inverts, the shape of the 3rd harmonic within the frame also inverts. Adding these waveforms results in "same + same" and "-(same + same)," which makes the shape symmetrical when inverted.

Figure 7

The same phenomenon occurs with even harmonics as with the 2nd harmonic, and similarly with odd harmonics as with the 3rd harmonic. If even harmonics generate asymmetry in the waveform, conversely, generating an asymmetric waveform will also produce even harmonics. Therefore, by making the waveform asymmetric, even harmonics can be generated.

3.1: INTRODUCTION TO GEN~ AND BLOCK DIAGRAMS

Max includes a feature known as gen~. When describing signal processing or synthesis in Max, one method is to combine MSP objects as illustrated in Figure 7. Figure 7 shows a very simple example of reverb created using an all-pass filter. While regular synthesis can be achieved with MSP objects, gen~ is useful for more detailed processing, executing signal processing formulas, or reducing computational load. For instance, gen~ enables creating filters by allowing delays on a per-sample basis.

Figure 7: simple_rev.maxpat

Let's try creating a biquad filter with gen~. Before doing that, let’s briefly explain block diagrams. Block diagrams visually represent the mechanics of signals, commonly used in signal processing. They contain various parts, similar to representations in Max. For example, as shown in Figure 8, the input is written as x[n] and the output as y[n]. To the right of the figure, the representation in gen~ is shown. Please refer to files like Block_diagram.maxpat for guidance.

Figure 8

When multiplying an input by a constant and outputting, it is represented in Figure 9. When adding inputs together, it is noted as in Figure 10.

Figure 9

Figure 10

When introducing a delay to the input - representing a delay - it is denoted as in Figure 11. The part labeled 'Z' is called a delay element, representing the delay. The coefficient of z indicates how many samples the signal is delayed. Here, it's written as -1, which means delaying the signal by one sample. For instance, with a sampling rate of 48000 Hz, one sample represents (1/48000) seconds.

Figure 11

3.2: BIQUAD FILTERS AND THEIR CONSTRUCTION

There is a type of filter known as the Biquad filter. It operates with five parameters, which can be altered to create various types of filters. In Max, you can use an object called Biquad~. Biquad~ can be easily used in combination with the filter graph object, which calculates the coefficients.

Figure 12

Figure 13

Figure 14

A block diagram representation of a Biquad filter is shown in Figure 14. There are two sets of delays, each with two delays, making a total of four. Additionally, there is one gain for each delay and one for the dry signal, totalling five gains. The Biquad filter allows for the creation of various types of filters by adjusting these five gain parameters.

First, let's construct the structure of a Biquad filter using gen~. The creation using gen~ is depicted in Figure 15. Here, there are six inputs, from in1 to in6. Figure 16 shows the external view of the gen~. in1 is for the signal input. in2 to in6 is for the five gain parameters. When these five parameters are inputted, the filter becomes operational.

Figure 15

Figure 16: biquad_filter_structure.maxpat

For example, as illustrated in Figure 17, when using filtergraph~ to connect to the gen~ that we just created, in the same manner as with biquad~, it becomes evident that it functions similarly to the biquad~ object.

Figure 17

3.3: CALCULATION OF BIQUAD FILTER COEFFICIENTS

Having constructed the filter structure, the next step is to calculate its coefficients. A well-known formula for calculating Biquad filter coefficients is the RBJ cookbook, a compilation of equations for biquad filters. We will use this as a basis for our coefficient calculations. As a preliminary step in the calculation of the filter coefficients, we will redefine the previously mentioned coefficients with more detailed variables. Figure 18 shows these redefined where everything is divided by the variable a0. By calculating these six intermediate variables: b0, b1, b2, a0, a1, and a2, we can determine the five coefficients.

Figure 18

To calculate the coefficients, we will prepare variables as follows:

Figure 19

We also set intermediate variables as shown in Figure 20. Intermediate variables are used to simplify the formula by grouping repeated elements into a single variable. They don’t have any specific meaning; they simply make the expression of the formula simpler.

Figure 20

Using the variables from Figures 19 and 20, the formulae for calculating the coefficients of the biquad filter are demonstrated. The formulae for calculating the coefficients of three different filters are presented in Figures 21 to 23. Based on these, the coefficients can be calculated, enabling the creation of specific filters with the Biquad filter.

Figure 21


Figure 22

Figure 23

The calculation for a Low-pass Filter is first created using gen~. Inside gen~, there is a feature called codebox, which allows for text-based description, and this is utilized. Three parameters are inputted here through in1 to in3: in1 for Frequency, in2 for Gain, and in3 for Q. While Gain is not used in the Low-pass Filter, it is included as a parameter for potential use in other filters. The five coefficients of the Biquad filter are calculated using these three inputted parameters and the previously mentioned formulae.

Figure 24

Once the calculation of coefficients is completed, as shown in Figure 25, the gen~ object for the biquad filter that was created earlier can be connected and used. After successfully creating a Low-pass Filter, other types of filters can be created in the same manner. Let's now make it possible to switch between multiple filters. For example, create a system that can switch between three filters: Low-pass (LP), High-pass (HP), and Band-pass (BP).

Figure 25

Inside the codebox of gen~, conditional statements using 'if' can be utilized. 'If' statements are programming syntax used for making conditional decisions. Additionally, a parameter called 'mode' is added with in4. By making conditional decisions based on the value of 'mode', switching between the aforementioned calculations can be implemented, allowing for the changing of filters. Figure 26 shows the setup that can switch between three filters: LP, HP, and BP. When mode is 0, it's in Low-pass; when mode is 1, it's High-pass; and when mode is 2, it's Band-pass.

Figure 26

Once assembled as shown in Figure 27, it becomes possible to switch and utilize the filter modes. Please refer to examples such as Biquad_filter_3mode.maxpat for guidance.

Figure 27

3.4: DRAWING THE FREQUENCY RESPONSE OF BIQUAD FILTERS

A block diagram or a formula that represents the state of signals and the entire system is called a transfer function. Here, a brief introduction to the transfer function related to Biquad filters is provided. Figure 28 shows the Biquad filter represented as a transfer function. This transfer function can be used to represent characteristics like the filter's response curve. As illustrated in Figure 29, by substituting cosω+jsinω into the Z portion of the transfer function and calculating the absolute value, the amplitude response of the filter can be determined.

Figure 28

Figure 29

For the absolute value of a fraction, the absolute values of the numerator and the denominator can be calculated separately. Figure 30 contemplates the absolute value of the numerator, while Figure 31 considers that of the denominator. Figure 32 then calculates the overall absolute value from these individual absolute values. The amplitude response formula derived in this way is based on the transfer function. In this formula, ω represents the normalized angular frequency, which is the frequency scaled between 0 and 2π. Considering the Nyquist frequency, it corresponds to scaling the frequency between 0 and π. By substituting values from 0 to π into this amplitude response formula at several points and plotting the calculated values, the frequency response can be drawn.

Figure 30

Figure 31

Figure32

The specific implementation in gen~ is shown in Figure 33. Here, the amplitude response is plotted into a buffer~. The buffer~ is defined outside of gen~, where the results of the amplitude response calculations are recorded. Once loaded into the buffer, the data can be read from outside, for example, using JSUI for drawing, or through plot~ for visualization. The part labelled 'flag' is a method used to reduce computational load. Inside gen~, calculations could occur, for example, 48,000 times per second. Since such high-speed processing is unnecessary for drawing, using a flag and a counter to decrease the frequency of calculations can reduce CPU load. For instance, in this case, calculations for drawing are performed only once every 2,000 times.

Figure 33

The drawing is done by inputting the five coefficients, calculating, and then recording the results into an external buffer~, which can be displayed through plot~. Please refer to biquad_filter_curve.maxpat for an example.

Figure 34

4: CONCLUSION

Max and gen~ are well-suited as tools for learning signal processing and synthesis through practice. Gen~ is particularly effective for grasping the concept of more general signal processing. By using gen~, one can also get an idea of how to implement these concepts in more general programming languages and other environments. For example, Figure 35 shows a musical patch created solely using gen~.

Figure35    gen_music.maxpat

~

fendoap is a music technologist, developer and experimental artist based in Japan. You can listen to their music on their Bandcamp page and explore their Max For Live devices on their Gumroad store.

You can follow them on Instagram: @y.o.fendoap

2023 © Whiston Digital / Lux Media  |  luxcache.com 


Related Creators