The post Audio Programmer Podcast 04 with Guest Rob Bantin (Ubisoft Games) appeared first on The Audio Programmer.

]]>The post Audio Programmer Podcast 04 with Guest Rob Bantin (Ubisoft Games) appeared first on The Audio Programmer.

]]>The post Coding Challenge: Valid Parentheses appeared first on The Audio Programmer.

]]>Does the order of data appearance and processing matter?

C++ is a deep language with a lot to learn. Experimentation, projects and general development practice will catapult you forward. However, sometimes it is important to step back and review some basic computer science and coding challenges. Doing so has helped me think differently about solving problems and appreciate certain aspects of C++ that are easy to forget. This is a part of the reason why I have been practicing extensively on LeetCode.

You can find this problem here.

Given a string containing just the characters ‘(‘, ‘)’, ‘{‘, ‘}’, ‘[‘ and ‘]’, determine if the input string is valid.

An input string is valid if:

- Open brackets must be closed by the same type of brackets.
- Open brackets must be closed in the correct order.

Note that an empty string is also considered valid.

```
Input: "()"
Output: true
```

```
Input: "()[]{}"
Output: true
```

```
Input: "(]"
Output: false
```

```
Input: "([)]"
Output: false
```

```
Input: "{[]}"
Output: true
```

```
class Solution {
public:
bool isValid(string s) {
}
};
```

It is good in coding interviews to ask some *clarifying questions*. Think of it as a chance to bounce ideas off each other as a conversation. Some clarifying questions may concern specific cases. For instance, is this an input we can expect?

```
Input: ")("
Output: false
```

Let us assume so while coding this question up.

Now let’s take a moment to think about this from first principles.

We are given a *std::string* and we need to look at each *char* in the string. Furthermore, the order of processing matters *and* we do not need to access random characters. Therefore, a *std::stack* seems like and ideal data structure. Essentially the process will look like this:

- loop through the string
- for a opening bracket char… add it to the stack
- for a closing bracket char… is the char the
*complementary*bracket? If so, pop the item from the stack as we have a complete pair. - during the loop… we need to check that the stack is not empty if we are examining a closing character.
- after the loop… the stack must be empty because all brackets need a complement.

I think we can start coding this as we have a general outline.

```
class Solution {
private:
bool isComplement(char stackValue, char candidateValue)
{
// check for the correct match...
if(stackValue=='(' && candidateValue==')')
{
return true;
}
else if(stackValue=='{'&& candidateValue=='}')
{
return true;
}
else if(stackValue=='[' && candidateValue==']')
{
return true;
}
else
{
// ...not the correct match
return false;
}
}
public:
bool isValid(string s) {
// this is a stack that we will use to validate our string
std::stack<char> validationStack;
// loop through each char element in the input string...
for(auto element : s)
{
// we can only have one of 6 possible characters...
// ...3 possible opening characters
if((element=='(') || (element=='{') || (element=='['))
{
// push this character to the stack
validationStack.push(element);
}
// ...3 possible closing characters
if((element==')') || (element=='}') || (element==']'))
{
// do we even have anything on the stack?
if(validationStack.empty() == true)
{
// not valid strings -->> "}" "())"
return false;
}
// is this character the correct complement?
bool status = isComplement(validationStack.top(), element);
if(status == true)
{
// ...we found a correct match
validationStack.pop();
}
else
{
// ...this character does not match the stack character
return false;
}
}
}
// final check...
// our stack must be empty in order to be valid
if(validationStack.empty() != true)
{
// not valid strings -->> "{" "(()"
return false;
}
// things are okay
return true;
}
};
```

Let’s take a moment to analyze the *space* and *time* complexity of this algorithm.

The time complexity of this algorithm is *O*(*n*) as we only loop through the string once and *push* and *pop* from the *std::stack* as we go. Each *push* and *pop* operation is a constant time operation. If we were using a *std::vector* this would not necessarily be the case.

The space complexity of this algorithm is *O*(*n*). In the worst case we end up storing the entire input string. Imagine if our input was either of the following:

```
Input: "({({({("
Input: "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
```

I hope this short tutorial has helped outline a guiding thought process on using *std::stack* for use in algorithm design. Stacks and Queues are useful tools when making applications that are easier to forget about. When order matters, always think about stacks and queues as part of your solution. Until next time:

Be good to each other and take it easy…

-Will ☜(ﾟヮﾟ☜)

The post Coding Challenge: Valid Parentheses appeared first on The Audio Programmer.

]]>The post Digital Filter Design: The Analog Prototypes for IIR Filters appeared first on The Audio Programmer.

]]>Before we understand virtual analog filters we should take the time to understand the common filter prototypes. Filter prototypes, or *classes*, were invented as a means of quickly creating a template filter with certain design trade-offs. There are four filter prototypes that you *need* to understand:

- Butterworth Filter
- Chebyshev Filter Type I
- Chebyshev Filter Type II
- Elliptic Filter

There are more filter classes besides those listed above. Not all filter prototypes used for continuous systems can be correctly translated to the digital domain. However, these four classes are in the filter design class in the JUCE framework and this is why I am explaining them.

When designing IIR filters in a software suite such as MATLAB, you will often see a diagram of this sort:

Essentially, we are asking, how can we make a line that will not touch the shaded areas and meet our design specifications. As you can see, we have a lot to play with. We can change a filter’s deviation in the pass-band, deviation in the stop-band, stop-band attenuation, transition bandwidth and cutoff frequency. The variables used in this diagram are as follows:

This gives us two primary parameters that we use in the design stage. We will probably return to these terms and definitions in a future article where I demonstrate an example filter design process. [1]

In this article we will not be going over the mathematics involved in designing the different filter classes. That would likely make this article too long. For the sake of brevity, we are going to focus on the different filter prototypes and compare them. Furthermore, we will only be focusing on creating prototype low-pass filters in this article.

A low-pass Butterworth filter is an all-pole filter with a a squared magnitude response (we will return to this definition in the future) [1]. The number of poles is defined as the filter order. The defining characteristic of a Butterworth filter is that it is *monotonic* in both the pass-band and stop-band. Monotonic means that it does not exhibit any rippling in those regions. The engineering trade-off is that the transition band is wide. As a result, you must use a much higher order Butterworth to get a sharper filter cutoff. The following graph shows a Butterworth filter of order = [1, 2, 4, 5]. As you can imagine, the wall of diminishing returns hits you pretty hard. The black line marks filter cutoff.

Chebyshev Type I filters allow one to design a filter where deviation in the pass band is allowable. As a result, the pass band exhibits ripples while the stop band is monotonic. The upside is that you can achieve a narrower transition band. In other words, you are trading a lower discriminatory factor for a better selectivity factor. [1]

It is typical in audio devices to aim to achieve a pass band ripple of ± 3 dB or less. In this filter I have specified that the minimum allowable attenuation would be 6 dB in the pass band.

Chebyshev Type II filters allow one to design a filter where deviation in the stop band is allowable. As a result, the pass band is monotonic while the stop band exhibits ripples. The upside is that you can achieve a narrower transition band just like the Type I but your cutoff will move for the sake of reaching the stop band frequency sooner. Notice below how the stop band ripples are different depending on even and odd filter orders. [1]

It is typical in audio devices to aim to achieve a stop-band attenuation of -60 dB or more. In this filter I have specified that the minimum allowable attenuation would be -54 dB for the stop band.

Elliptic filters provide a nice balance between the Chebyshev variants. In an Elliptic filter, there is ripple in both the pass band and stop band but the transition band width can be made even narrower. [1] All code for this article can be found on my GitHub.

In this filter, I have specified that the filter could exhibit a 6 dB deviation in the pass band and stop bands. As a result, we have an incredibly sharp cutoff for a given filter order.

Of course, as you know from all of my articles, the time domain and frequency domain are inextricably linked. Every modification we make in the frequency domain aspects of a filter has direct implications to the impulse response. So it would be wise of us to look at each of these prototypes and compare their impulse responses for a given filter order. The following graph shows the resulting impulse response that each prototype yields at the same cutoff frequency for the same order *N*=4. All code for this article can be found on my GitHub.

As you can see, the filters with the smallest transition bands and largest deviations in the pass-band exhibit the longest decay time. The reasons for this are too long for this article. However, I want you to think of these IIR filter prototypes as an analogous method to the window design method for FIR filters. The steeper the filter we require, the longer the trailing impulse response. The question is:

Is this longer decay audible?

The answer is: Not likely. You can feasibly make resonators on this principle of designing for a high selectivity factor. But the main concern for the long impulse response comes into play when analyzing the effects of a filter on a signal used to control a system. The bottom line is:

Does the shape of the signal matter?

We will return to this concept when we examine *linear phase filters* and why they are used. Please note that the magnitude-phase response of filters is something that we have not discussed yet.

In this article, I have given a brief overview of the classic analog filter prototypes. It should be clear how they can be used to create an IIR filter for a given set of specifications. In this article, we have compared the four different methods found in the JUCE filter design class. In a future article, I want to explain more about IIR filters and their design. Perhaps, it will be useful to explain, at length, the design process of an example filter. There is so much to cover. Until then:

Be good to each other and take it easy…

-Will ☜(ﾟヮﾟ☜)

[1] Schaums Outline of Digital Signal Processing, 2nd Edition (Schaum’s Outlines)

[2] Understanding Digital Signal Processing

The post Digital Filter Design: The Analog Prototypes for IIR Filters appeared first on The Audio Programmer.

]]>The post Podcast Episode 03 – Maxwell Hayes (Software Intern, Epic Games) appeared first on The Audio Programmer.

]]>The post Podcast Episode 03 – Maxwell Hayes (Software Intern, Epic Games) appeared first on The Audio Programmer.

]]>The post Coding Challenge: Moving Average from Data Stream appeared first on The Audio Programmer.

]]>C++ is a deep language with a lot to learn. Experimentation, projects and general development practice will catapult you forward. However, sometimes it is important to step back and review some basic computer science and coding challenges. Doing so has helped me think differently about solving problems and appreciate certain aspects of C++ that are easy to forget. This is a part of the reason why I have been practicing extensively on LeetCode.

You can find this problem here. This is part of the *Introduction to Data Structure Queue & Stack* Card on LeetCode. There are some great explanations on these data structures that I highly suggest taking a look at. I have also written an article on this.

Given a stream of integers and a window size, calculate the moving average of all integers in the sliding window.

```
MovingAverage m = new MovingAverage(3);
m.next(1) = 1
m.next(10) = (1 + 10) / 2
m.next(3) = (1 + 10 + 3) / 3
m.next(5) = (10 + 3 + 5) / 3
```

```
class MovingAverage {
public:
/** Initialize your data structure here. */
MovingAverage(int size) {
}
double next(int val) {
}
};
/**
* Your MovingAverage object will be instantiated and called as such:
* MovingAverage obj = new MovingAverage(size);
* double param_1 = obj.next(val);
*/
```

This is a moving average calculation and you can find out more about it here. Moving averages are used all the time in signal analysis or any role where you have time series data. Digital Signal Processing and Finance are two fields where you can expect this type of question. In DSP you will often hear this called a *moving average filter*, which is essentially a crude low-pass filter.

It is common to address this problem using a queue such as a FIFO. In this case, I would suggest using the *std::queue* data structure from the STL. While I actually wrote about this data structure in a previous article, I do not suggest you copy paste those classes for a variety of reasons. **Do not over complicate this task** by building your own generic FIFO class.

Just a word here, there are different types of moving average. There are cumulative moving averages which take into account all of the data submitted. There are weighted moving averages which use a constant set number of values as data and there may be be a weight applied (like a windowing function). All in all, this question is actually neither of those. The number of used values is not constant. However, the basic process of en-queuing a value to use is the main point of this exercise.

The following code block should make for a clear solution. Note that the std::queue class does not allow us to pre-allocate size or check for a size limit. We must create this check ourselves.

```
class MovingAverage {
public:
/** Initialize your data structure here. */
double runningTotal;
unsigned int windowSize;
std::queue<int> buffer;
MovingAverage(unsigned int inputSize) {
/*initialize values*/
runningTotal = 0.0;
windowSize = inputSize;
}
double next(int inputValue) {
/*check if buffer is full*/
if (buffer.size() == windowSize)
{
/*subtract front value from running total*/
runningTotal -= buffer.front();
/*delete value from front of std::queue*/
buffer.pop();
}
/*add new value*/
buffer.push(inputValue);
/*update running total*/
runningTotal += inputValue;
/*calculate average*/
return static_cast<double>(runningTotal / buffer.size());
}
};
```

Of course, it is possible to handle the runningTotal differently. It is possible to recalculate it every time a value is added. However, this would be inefficient.

I could be wrong concerning space time complexity of this code. It seems to me that this solution uses (in the worst case) a constant amount of space O(1). In the worst case there are only as many values as the windowSize. The time complexity is O(*n*) in the worst case. This is because the common C++ documentation says:

Constant (amortized time, reallocation may happen).

If a reallocation happens, the reallocation is itself up to linear in the entire size.

*push()* and *pop()* both have this complexity. If we assume that reallocation happens every time, then O(*n*) will happen in two places.

In this article, I showed you a basic implementation of a std::queue used as a means to filter data. Remember to think through the many C++ data structures that you have available to you before you approach a problem. Also think about how you can relate these problems to our field of Audio Programming. This moving average problem seems like an intuitive introduction as we tend to work with time series data. Until next time:

Be good to each other and take it easy…

-Will ☜(ﾟヮﾟ☜)

The post Coding Challenge: Moving Average from Data Stream appeared first on The Audio Programmer.

]]>The post About LIFO and FIFO Data Structures (The Basics) appeared first on The Audio Programmer.

]]>Two common data structures in computer science are LIFO (last-in-first-out) and FIFO (first-in-first-out). In audio the FIFO data structure is especially important and will occur as a topic of further discussion in later articles.

Finding good explanations of these data structures is easy but I want to point you to further resources:

In a LIFO data structure, the *newest* element added to the queue will be processed *first*. Sometimes this will be called a stack and is usually pictured as below. The new element is always added at the end of the stack. There are two basic operations that a LIFO needs to allow:

*push*– append an element to the end of the container*pop*– remove the most recent element from the container

The LIFO data structure can be thought of as analogous to a deck of cards that you add to the top of and draw from the top of.

The following code should outline a basic LIFO as we have discussed so far.

```
class BasicLIFO
{
private:
/*use a vector to store the data...*/
vector<float> containerLIFO;
bool isEmpty()
{
/*checks if the container is empty or not...
we need this function as our container is private.*/
return containerLIFO.empty();
}
public:
void push(float x)
{
/*append value to vector...*/
containerLIFO.push_back(x);
}
bool pop()
{
/* check whether the queue is empty or not... */
if (isEmpty())
{
return false;
}
/* delete an element from the queue...*/
containerLIFO.pop_back();
/*return true if the operation is successful...*/
return true;
}
};
```

There are more advanced LIFO structures that are generic, multi-channeled, can handle multiple users, multiple readers or can still have methods that handle internal sorting and searching.

LIFOs are useful when a program needs to access the most recent information entered. Stacks are important in algorithms involving *backtracking*. While this is not fundamental to DSP it is common to use this in other parts of a program such as File Management or parameter parsing. I highly recommend you come to grips with std::stack for solving interview related LIFO questions.

In a FIFO data structures the first element added to the container will be processed first. There are two basic operations that a FIFO needs to allow:

*enqueue*– append an element to the end of the container*dequeue*– remove the first element from the container

This is represented graphically below. The container is a number of contiguous boxes. A box can be added to only one end and a box can be taken from only the opposite end. Think of it like a conveyor belt.

The following code should outline a basic FIFO as we have discussed so far.

```
class BasicFIFO
{
private:
/*use a vector to store the data...
pretend this is an audio buffer....*/
vector<float> containerFIFO;
/*a read index to indicate the start position...*/
int readIndex;
bool isEmpty()
{
/*checks whether the container is empty or not...*/
return readIndex >= containerFIFO.size();
}
public:
BasicFIFO()
{
/*initialize readIndex position...*/
readIndex = 0;
}
bool enqueueValue(float x)
{
/*insert an element into the container...
return true if the operation is successful...*/
containerFIFO.push_back(x);
return true;
}
bool dequeueValue()
{
/*increment readIndex...
return true if the operation is successful...*/
if (isEmpty())
{
return false;
}
readIndex++;
return true;
}
};
```

This class and the behavior designated by the functions ensures that our data structure has this First In First Out behavior that the name implies. However, we can do *much* better as this class is highly inefficient.

r designated by the functions ensures that our data structure has this First In First Out behavior that the name implies. However, we can do *much* better as this class is highly inefficient.

The above implementation *works* but it *wastes* space. As the start Index moves, more and more space is wasted even if the elements before the start index may be empty. This is likely to be unacceptable. What happens if we have a space limitation? How can this be addressed?

To address these problems, we create a Circular FIFO *aka* Ring Buffer *aka* Circular Queue. A Ring Buffer uses a fixed-size array with two pointers. One pointer acts as a read head while one acts as a write head. The goal is to reuse the empty storage. This is one of the most important data-structures in audio programming.

I am sorry but I really did not want to make a .gif or animation of this. I have linked a YouTube animation that I think demonstrates this well.

Now here is another video from Timur Doumler about a special implementation of the ring-buffer in audio. We will come back to this video in the future but at this current time, I want you to just pay attention to his overall explanation of the ring buffer. You should be starting at 54:27 :

The following code should outline a basic Circular FIFO as we have discussed so far. Please note the utility function of *isEmpty()* and *isFull()* which are important conditions to observe. While there is a *std::queue* data structure in the standard C++ library, I want to use *std::vector* as we will revisit this basic idea later.

```
class RingBuffer
{
private:
vector<float> containerRingBuffer;
int readIndex;
int writeIndex;
int size;
bool isEmpty()
{
/* check if the buffer is empty or not. */
return readIndex == -1;
}
bool isFull()
{
/* check if the buffer is full or not. */
return ((writeIndex + 1) % size) == readIndex;
}
public:
RingBuffer(int inputSizeValue)
{
size = inputSizeValue;
containerRingBuffer.resize(size);
readIndex = -1;
writeIndex = -1;
}
bool enqueueValue(float inputValue)
{
/* insert an element into the circular queue.
return true if the operation is successful. */
if (isFull())
{
return false;
}
if (isEmpty())
{
readIndex = 0;
}
writeIndex = (writeIndex + 1) % size;
containerRingBuffer[writeIndex] = inputValue;
return true;
}
bool dequeueValue()
{
/* delete an element from the circular queue.
return true if the operation is successful. */
if (isEmpty())
{
return false;
}
if (readIndex == writeIndex)
{
readIndex = -1;
writeIndex = -1;
return true;
}
readIndex = (readIndex + 1) % size;
return true;
}
};
```

I would not recommend that you normally build these data structures on your own. The C++ STL comes with all of the basic data structures you will require to solve problems and implement prototype algorithms. For this reason, I hope you take the time to understand *std::queue* and *std::priority_queue*. While it is unlikely that you will use these to build audio software, it is likely that you can prototype out a calculation using these standard data structures.

This article was meant to serve as a small introduction and guide to LIFO and FIFO data-structures. There is a good chance, as an audio programmer, that you will be asked to solve questions using these data structures. I aim to go through some practice coding interview questions which employ these data-structures as it helps to recognize when to use certain data-structures. After that, I want to introduce you to some C++ specific implementations concerning these data-structures and audio. Until then:

Be good to each other and take it easy…

-Will ☜(ﾟヮﾟ☜)

The post About LIFO and FIFO Data Structures (The Basics) appeared first on The Audio Programmer.

]]>The post Podcast Episode 02 – Bruce Dawson (Software Engineer, Output) appeared first on The Audio Programmer.

]]>The post Podcast Episode 02 – Bruce Dawson (Software Engineer, Output) appeared first on The Audio Programmer.

]]>The post Understanding the Z-Transform Part IV: Analyzing an IIR Filter appeared first on The Audio Programmer.

]]>I also showed that you can take the magnitude response in decibels at any value of *z*. Furthermore, we can get the system’s *magnitude-frequency* response (DTFT) if *z* is on the unit circle.

Lastly, the mesh representation allowed us to visually see the pole and zero locations for a system. For an FIR filter, the poles were located at the center while the zeros could be anywhere.

Clearly the last article was important…

In this article, I want to show you how we can examine IIR systems and filters. I will show you how we can examine a filter for stability and how the coefficients of the system are related to the pole and zero coordinates. In this article we will have to back track a bit to refine our understanding of IIR systems.

It has been a while since I actually described the workings of an IIR filter system. In a previous article, I demonstrated the basic difference between an FIR and IIR filter. I said that the FIR system is constructed out of a number of taps that form a discrete convolution. I also said that the IIR filter can use feedback and feed-forward routing to create a filter. I also stated that an IIR filter can be stated as a *difference equation*.

While the system I proposed was correctly demonstrated and written, it was not a *general* view of IIR filters. Now I think is a good time to demonstrated how IIR systems are put together in a *general* formulation.

Below you will find a graph of a general IIR system. Please note that this graph is more complicated than the simple system used in a previous article (which had one feed-back coefficient). However, even that system is still valid according to this general system below. We should take a moment to look at the principle operation of this general IIR diagram [1] [2].

We have a system with input *x*[*n*] that produces an output *y*[*n*]. The output is a function of the difference of a feed-forward system (left-hand side) and a feed back system (right-hand side). The left-hand side has its gain coefficients denoted with *b*. The right-hand side has its gain coefficients denoted with *a*. Please note that we can have any number of *a* and *b* taps. These sides do not need to be symmetric.

You might not immediately notice this, but that left-hand side looks exactly like the FIR filter (below) even though the orientation is different. Remember that the highlighted section is known as a tap.

Going back to the IIR filter in the larger previous picture…

The right-hand side looks very similar to the left-hand side with some differences:

- Notice how there is no
*a0*coefficient that is complementary to*b0*. This is because*a0*==1 in this formulation. In other words, the sample is not modified at this point. - The right-hand side takes the input from the left-hand side
*and*the result of itself. This is the feedback nature of an IIR filter system. This feedback path is what leads to the infinite nature of the impulse response.

Now think about the last point. If we had no feedback paths, as if our filter did not require any, then our filter would be an FIR filter.

The basic thing to remember is that FIR and IIR systems may seem different. However, you can also remember this general IIR filter diagram by thinking of two FIR systems feeding samples in opposite directions.

The general IIR filter can be transcribed as follows.

This can also be sometimes written with the *a0* term as:

Notice that *a0* simply acts as an overall gain control for the system.

The output *y* is a function of *x* and delayed *y* signals. The coefficients *a* are the feedback terms. The coefficients *b* are the feed-forward terms. There are *F* number of feed-forward coefficients and *B* number of feedback coefficients. Note the sign change for the *a* terms.

This long summation can be written in a more condensed manner (difference equation) [1].

Which is equivalent to this version which includes the *a0* term.

As shown by the signal flow diagram for the general IIR, we have a left-hand side and a right-hand side. This means that the feed forward summation and the feedback summation can be considered as separate terms which allows us to write the following equivalence [2].

Now this way of writing the equation is not helpful to us when writing code. But it is helpful when breaking down this IIR system. We can think of this as being two separate convolutions. One acting on the *y* terms with *B* number of *a* coefficients. One acting on the *x* terms with *F* number of *b* coefficients.

This is useful as it will allow us to analyze these as two separate systems. The right-hand side of this equivalence statement corresponds with the feed forward term and we are convolving the coefficients with the input signal *x*. The right-hand side of this equivalence statement corresponds with the feedback terms and we are convolving the coefficients with the output signal *y*. Of course, *y* is the result of the right-hand side.

The previous equivalence statement means that we can perform a Z-Transform on each side of the equation simultaneously [2]. You will often see this as follows:

If we re-arrange terms we can get the *Total System Transfer Function* which is often denoted *H*(*z*). This is akin to saying the Z-Transform of the entire system. Effectively the Transfer Function is a ratio of the output terms to the input terms. (Apologies for the odd formatting bug…)

Notice that if we have no *a* coefficients then your system equation is the Unilateral Z-Transform over 1. This means that if you do not have any feedback then your system is an FIR system.

Just like in the previous article, it is now doubly tedious to do this by hand. So, let’s test some systems using my Python code. If you want any Python code that relates to this, then feel free to grab it from my GitHub.

So lets use what we have discussed to analyze a common filter. Using the following code, we can create an Elliptic Low-pass Filter with a pass band deviation of 6 dB and a stop band attenuation of 54 dB with 6 dB variance.

`bEllip, aEllip = scipy.signal.iirfilter(3, 0.5, rp=6, rs=54, btype='lowpass', ftype='ellip')`

Our filter coefficients are as follows:

```
b Coefficients :
[0.07166155 0.18822804 0.18822804 0.07166155]
a Coefficients :
[ 1. -0.88402525 0.96119644 -0.55739203]
```

The scipy.signal module gives us stable filters. For this article, we do not need to concern ourselves with the calculations. I would still like to show you the characteristics of the filter that we have created. Here is the result of the DTFT (the magnitude of *H*(*z*) along the unit circle).

Let’s actually take a look on that circle mesh.

You have probably noticed that our poles are within the unit circle but away from the center of the mesh. The zeros appear at the edge of the unit circle but they can reside anywhere on the z-plane. This system is *stable* as shown by the impulse response below.

Of course, we should ask ourselves: *What if the poles move outside of the unit circle*?

To investigate this, I want to now make an arbitrary IIR filter. Here are the filter coefficients I will use:

```
b Coefficients :
[0.6, -0.5, 0.1, -0.2, 0.3]
a Coefficients :
[0.2, -0.1, -0.0005, 0.2, -0.0002]
```

Here is the system frequency response.

The poles and zeros are located at:

```
poles :
[0.67835673+0.j 0.10283426-0.90061364j 0.10283426+0.90061364j]
zeros :
[-0.8133127+0.58182682j -0.8133127-0.58182682j -1. +0.j ]
```

And here is the system as a mesh

It looks as if there is trouble here. We have two poles outside of the unit circle and the zeros are located within the radius of the poles farthest from the unit circle. Extending the mesh out to a radius of 2 would reveal the location of these hyper-extended poles. As a result our system does not converge and the impulse response is *unstable*.

A filter system can be stable for certain values of *z* and not for others. A rule to remember is that a system can be evaluated for values of *z* that are farther out than the furthest pole from the center of the unit circle. Remember that FIR filters always have their poles in the center, therefore all values of *z* (that are not at the center) can be evaluated. IIR filter can have poles that are placed elsewhere. This means that the values of *z* beyond that pole can be evaluated. However, if any poles are at or beyond the unit circle then the system is unstable as the DTFT cannot actually be determined. Practically speaking, this is why you need a computer to analyze the Z-Domain.

I would like to key you in on to a supplementary video from a DSP lecturer in Ireland named David Doran. He has an excellent video explaining analysis of IIR systems in the Z-Domain as well.

In this article I have covered the essentials of using the Z-Transform to characterize an IIR system. We have now solidified our understanding of IIR filters and how they can be described in a general manner both graphically and mathematically. And we have finalized how we can use the Z-Transform to describe the feed-forward and feedback phenomena of a system in order to get the System Transfer Function. Lastly we have looked at preliminary components of stability using the position of the poles in relation to the zeros and also the impulse response.

In future articles, I want to show how we can examine electronic circuits in order to model analog systems. I then want to show how we can take those analog systems and model them in the digital domain. Exciting stuff ahead! Until next time:

Be good to each other and take it easy…

-Will ☜(ﾟヮﾟ☜)

[1] The z-transform and Analysis of LTI Systems

[2] Schaums Outline of Digital Signal Processing, 2nd Edition (Schaum’s Outlines)

[3] Understanding Digital Signal Processing

The post Understanding the Z-Transform Part IV: Analyzing an IIR Filter appeared first on The Audio Programmer.

]]>The post The Audio Programmer Podcast Episode 01 w/ guest Eyal Amir (Software Engineer, Waves) appeared first on The Audio Programmer.

]]>The post The Audio Programmer Podcast Episode 01 w/ guest Eyal Amir (Software Engineer, Waves) appeared first on The Audio Programmer.

]]>The post About Lambda Expressions (The Basics) appeared first on The Audio Programmer.

]]>In this article I want to give you a brief introduction to lambda expressions, a modern C++ language feature. Resources are listed below at the end of the article. I highly suggest you look at those if you need help understanding lambda expressions. As always, remember to experiment with new coding habits on your own! All code used here can be found on my GitHub. I also suggest the great tutorial series by our forum member, MatKat, here. His lesson on lambda expressions is also well written.

A lambda expression is similar to a function. Lambda expression allow one to encapsulate a number of lines of code, manipulate some data and return some data. Like a function you can:

- pass values by reference or value
- name a lambda expression and call it later
- return stuff of any type

Unlike a function a lambda expression does not *necessarily* need to be named. A question you might be asking is…

Lambda expressions behave similarly to a function but they have some different behavior. Consider this…

What if we want to pass a function to a function?

This is not possible directly. However, we can pass a *pointer* to a function.

Another thing to consider…

What if we want to have some internal state within our function?

We could use the *static* keyword for the relevant variables somewhere in the function. An alternative is to make a class that contains the variables and the single function that we want to use (a *functor*).

Lambda expressions are an alternative to do both of these things with less code and simplified data management. To understand how to *derive* these two aspects, I highly suggest watching Arthur O’Dwyer’s CppCon Presentation on Lambdas from First Principles linked below. Let’s continue on with the basics.

A lambda expression contains a few essential parts:

- A
*Capture List*which is denoted with ‘[ ]’. This is followed by… *Function Argument(s)*which is denoted with ‘( )’. This is followed by…*Function Body*which is denoted with ‘{ }’- When a lambda expression is
*used*there will be invocation parenthesis just like a normal function. This is denoted by ‘( )’

Let’s see these aspects at work. The following code sample shows the same lambda expression repeated twice. One has minimal comments and the other is fully commented. They do the same thing.:

```
int main()
{
/*this is a basic lambda expression...*/
[]() {
std::cout << "this is a basic lambda expression...\n";
}();
/*this is the same basic lambda expression...*/
[/*it captures nothing...*/](/*it takes no arguments...*/) {
/*this is the lambda expression function body...*/
std::cout << "this is a basic lambda expression...\n";
}(/*I want to invoke the lambda expression...*/);
}
```

The result of running this program is:

```
this is a basic lambda expression...
this is a basic lambda expression...
```

Let’s actually take a moment to pass a value to the lambda expression. This can be done by:

- Specifying the argument
- Passing values for the arguments when we invoke the lambda expression

```
int main()
{
/*another lambda expression...*/
[](int inputValue) {
std::cout << "my inputValue = " << inputValue <<"\n";
}(100);
}
```

The result of running this program is:

`my inputValue = 100`

Of course, it is not always useful to make a lambda expression that must be invoked immediately. Perhaps it is best to name the lambda expression and use it elsewhere down the line.

Let’s do something related to our last code block. We will use the *auto* keyword to deduce a return type for this lambda expression. This function will return the input divided by a float value of 2.12 . We will invoke this lambda expression twice.

```
int main()
{
/*another lambda expression...*/
auto myLambdaExpression = [](int inputValue) {
std::cout << "my inputValue = " << inputValue << "\n";
return inputValue / 2.12F;
};
/*assume some other code happened here...*/
std::cout << "my outputValue = " << myLambdaExpression(100) << "\n";
std::cout << "my outputValue = " << myLambdaExpression(12) << "\n";
}
```

The result of running this program is:

```
my inputValue = 100
my outputValue = 47.1698
my inputValue = 12
my outputValue = 5.66038
```

The capture list (also called capture block) allows another way to pass variables to the lambda expression as either a value or a reference (just like a function). The function arguments section does this too however, there is a difference. The capture block is used for variables that are within scope. The next code block demonstrates passing values by reference to the lambda expression:

```
int main()
{
/*assume we have some internal variables to our main...*/
std::string nameLongTown = "Llanfairpwllgwyngyllgogerychwyrndrobwllllantysiliogogogoch";
int indexString = 0;
/*another lambda expression...*/
auto myLambdaExpressionByReference = [&nameLongTown, &indexString](int inputValue) {
std::cout << "the current town is " << nameLongTown << " !\n";
std::cout << "the " << indexString << " letter is " << nameLongTown.at(indexString) << " !\n";
indexString += 2;
std::cout << "the " << indexString << " letter is " << nameLongTown.at(indexString) << " !\n";
std::cout << "remove letter " << inputValue << " !\n";
nameLongTown[inputValue] = '_';
std::cout << "the current town is now " << nameLongTown << " !\n\n";
};
myLambdaExpressionByReference(2);
myLambdaExpressionByReference(15);
}
```

The result of running this program is:

```
the current town is Llanfairpwllgwyngyllgogerychwyrndrobwllllantysiliogogogoch !
the 0 letter is L !
the 2 letter is a !
remove letter 2 !
the current town is now Ll_nfairpwllgwyngyllgogerychwyrndrobwllllantysiliogogogoch !
the current town is Ll_nfairpwllgwyngyllgogerychwyrndrobwllllantysiliogogogoch !
the 2 letter is _ !
the 4 letter is f !
remove letter 15 !
the current town is now Ll_nfairpwllgwy_gyllgogerychwyrndrobwllllantysiliogogogoch !
```

It is also possible to capture *all* variables within a scope in a few ways.

- [=] capture all variables by value
- [&] capture all variables by reference
- there are other options as well but I suggest checking out the C++ standard and experimenting on your own.

The following code block demonstrates how to do this.

```
int main()
{
int a = 0;
int b = 110.03;
/*another lambda expression...*/
auto myLambdaExpressionAll = [=](auto inputValue) {
std::cout << a << " + " << b << " + " << inputValue << " = " << a+b+inputValue << "\n";
};
/*another lambda expression...*/
auto myLambdaExpressionAllAgain = [=](auto inputValue) {
std::cout << a << " + " << inputValue << " = " << a + inputValue << "\n";
};
myLambdaExpressionAll(33.33);
myLambdaExpressionAllAgain(0.1);
}
```

The nice thing is that the lambda expression will only copy over the values that are actually used in the expression (as far as I understand…). The result of running this program is:

```
0 + 110 + 33.33 = 143.33
0 + 0.1 = 0.1
```

Of course, the most important thing about lambda expressions is that we can pass the name of the lambda expression as a function parameter. This is shown in a small example below:

```
int main()
{
auto MyVector = std::vector<int>{ 1,13,4,5,3,6,3,1,3,9,4 };
/*another lambda expression*/
auto isGreaterThan4 = [](int valueCandidate) {
return valueCandidate > 4;
};
/*another lambda expression*/
auto is4 = [](int valueCandidate) {
return valueCandidate == 4;
};
auto above4Count = std::count_if(MyVector.begin(), MyVector.end(), isGreaterThan4);
auto is4Count = std::count_if(MyVector.begin(), MyVector.end(), is4);
std::cout << "above4Count " << above4Count << "\n";
std::cout << "is4Count " << is4Count << "\n";
}
```

The result of running this program is:

```
above4Count 4
is4Count 2
```

The point of this article was to familiarize you with lambda expressions. They are not the most common feature in modern C++ but they are useful to understand. It is important that you are not thrown off by the syntax even if it may seem less readable at times. When reading the code provided by others, take it slow and just remember the 4 essentials parts of a lambda expression.

Lambda expressions are useful as an additional tool in standard modern C++. You might find that they will not always be an optimal choice compared to function objects, structs and function pointers. However, they will exhibit utility often in the back end for DSP calculations.

Be good to each other and take it easy…

-Will ☜(ﾟヮﾟ☜)

[1] CppCon 2015: Arthur O’Dwyer “Lambdas from First Principles: A Whirlwind Tour of C++

[2] Microsoft Documents: Lambda Expression Syntax

The post About Lambda Expressions (The Basics) appeared first on The Audio Programmer.

]]>