Updated Appendix E: Tuning the EQ Profile (markdown)
parent
74d4e0edaf
commit
6a7ac2073f
|
@ -1,175 +1,3 @@
|
||||||
# Tuning the EQ Profile
|
The fastest, easiest way of changing the EQ profile is to use [George Norton's Headphones Toolbox](https://github.com/george-norton/headphones-toolbox). It's a powerful GUI tool that allows you to shape the EQ any way that you want to. And, it's completely free! Check it out.
|
||||||
|
|
||||||
After the marathon that was [[Appendix C: Firmware programming]], you're now fully prepared to change the EQ profile of your Ploopy Headphones. But, how's that done?
|
If you feel like doing things manually, check the past revisions of this appendix for information on how to do that.
|
||||||
|
|
||||||
This guide will walk you through how to tune the Ploopy Headphones to shape the sound to anything you want.
|
|
||||||
|
|
||||||
Do you want bass cannons that will make grandma think you're summoning satanic beasts? _Easy_.
|
|
||||||
|
|
||||||
Do you want tweeters that will drive the neighbourhood dogs insane? _No sweat_.
|
|
||||||
|
|
||||||
Do you want a flat, boring line? _A bit of trouble, maybe, but possible_.
|
|
||||||
|
|
||||||
Let's crack on with it.
|
|
||||||
|
|
||||||
## user.c
|
|
||||||
|
|
||||||
Look for `user.c` in the Ploopy Headphones firmware source code. This is where the DSP filters live. This is your EQ profile.
|
|
||||||
|
|
||||||
In order to define the EQ profile of your set of Ploopy Headphones, you will have to make significant changes to this file. Thankfully, it's not that complex.
|
|
||||||
|
|
||||||
Let's walk through one of the filters, what it means, and how to change it.
|
|
||||||
|
|
||||||
### Filter numbers
|
|
||||||
|
|
||||||
```
|
|
||||||
bqf_memreset(&bqf_filters_mem_left[0]);
|
|
||||||
bqf_memreset(&bqf_filters_mem_right[0]);
|
|
||||||
bqf_peaking_config(SAMPLING_FREQ, 49.0, -20.0, 1.3, &bqf_filters_left[0]);
|
|
||||||
bqf_peaking_config(SAMPLING_FREQ, 49.0, -20.0, 1.3, &bqf_filters_right[0]);
|
|
||||||
```
|
|
||||||
|
|
||||||
These four lines represent ONE filter. The way that we can tell that is because of the signifier `[0]`. That means that every line above is configuring the first filter. (Because of a quirk of computer science, we start counting at 0, not 1, so the first object in a group of objects is referred to as 0, not 1.)
|
|
||||||
|
|
||||||
If we wanted to configure a second filter, we'd do the same thing as above, we'd create a new group of those four lines, but use `[1]`. If we wanted a third filter, we'd use `[2]`. Get it?
|
|
||||||
|
|
||||||
### Left and right
|
|
||||||
|
|
||||||
You've probably already noticed that there are references to "left" and "right"; for instance, `bqf_filters_mem_left[0]` and `bqf_filters_mem_right[0]`. That's because each filter operates on the left and right channels independently.
|
|
||||||
|
|
||||||
If we want to configure the same filter for both the left and right channel, we have to type out the line two times, once for the left channel and once for the right channel.
|
|
||||||
|
|
||||||
### bqf_filters_mem
|
|
||||||
|
|
||||||
`bqf_filters_mem` objects represent a bit of temporary memory used up by a filter during normal operation. When we're defining the filter for the first time, we need to reset the filter. That ensures that it works correctly.
|
|
||||||
|
|
||||||
The line `bqf_memreset(&bqf_filters_mem_left[0])` resets the memory for the left channel of the first filter. If you wanted to reset the memory of the right channel of the fourth filter, you'd use the line `bqf_memreset(&bqf_filters_mem_right[3])`.
|
|
||||||
|
|
||||||
There is a lot going on with the memory, but it's not necessary to know in order to define a new filter. Just know that a reset is necessary when defining the filters.
|
|
||||||
|
|
||||||
### bqf_filters
|
|
||||||
|
|
||||||
Here is where we define the actual filter itself.
|
|
||||||
|
|
||||||
Based on what we've seen so far, you should be able to understand that `bqf_peaking_config(SAMPLING_FREQ, 49.0, -20.0, 1.3, &bqf_filters_left[0])` defines the filter for the left channel of the first filter. Now, let's break down how the rest works.
|
|
||||||
|
|
||||||
As you can probably guess, `bqf_peaking_config` defines this filter as a peaking filter. Peaking filters have a few variables that go into them: sampling frequency, center frequency, decibel gain, and Q factor. In fact, that's exactly what the numbers in that line represent:
|
|
||||||
|
|
||||||
```
|
|
||||||
bqf_peaking_config(SAMPLING_FREQ, 49.0, -20.0, 1.3, &bqf_filters_left[0])
|
|
||||||
| | | |
|
|
||||||
sampling frequency | | |
|
|
||||||
| | |
|
|
||||||
center frequency | |
|
|
||||||
| |
|
|
||||||
decibel gain |
|
|
||||||
|
|
|
||||||
Q factor
|
|
||||||
```
|
|
||||||
|
|
||||||
When defining filters, we use these variables, which is what defines how the filters function.
|
|
||||||
|
|
||||||
So, that's really it for `user.c`. The next big question is: what are all of the different filters, and how do they work? In order to answer that question, find `bqf.c` and open it.
|
|
||||||
|
|
||||||
## bqf.c
|
|
||||||
|
|
||||||
`bqf.c` is where all of the filter types are defined. In this file, we can find all of the definitions for the various filter types.
|
|
||||||
|
|
||||||
This file is complex. Very complex. However, you don't have to make any changes to it! You don't even have to fully understand what's going on here. Lucky, lucky!
|
|
||||||
|
|
||||||
Let's take a look at an example. Since we were looking at peaking filters, let's find `bqf_peaking_config` in this file:
|
|
||||||
|
|
||||||
```
|
|
||||||
/**
|
|
||||||
* Configure a peaking filter. Parameters are as follows:
|
|
||||||
*
|
|
||||||
* fs: The sampling frequency. This is usually defined for you by
|
|
||||||
* SAMPLING_FREQ in run.h. It's the sampling frequency of the DAC on the
|
|
||||||
* board.
|
|
||||||
*
|
|
||||||
* f0: The centre frequency. this is where the signal starts getting
|
|
||||||
* attenuated.
|
|
||||||
*
|
|
||||||
* dBgain: The gain at the centre frequency, in dB. Positive for boost,
|
|
||||||
* negative for cut.
|
|
||||||
*
|
|
||||||
* Q: The quality factor. It defines the bandwidth from the centre frequency.
|
|
||||||
* For the purposes of this filter, the bandwidth is defined using the points
|
|
||||||
* on the curve at which the gain in dB is half of the peak gain. Some
|
|
||||||
* example values for Q:
|
|
||||||
* - sqrt(2) is 1 octave wide
|
|
||||||
*/
|
|
||||||
void bqf_peaking_config(double fs, double f0, double dBgain, double Q,
|
|
||||||
bqf_coeff_t *coefficients) {
|
|
||||||
|
|
||||||
...
|
|
||||||
```
|
|
||||||
|
|
||||||
Ahh, now we get a few clues. Take another look at how we defined the peaking filter in `user.c`:
|
|
||||||
|
|
||||||
```
|
|
||||||
bqf_peaking_config(SAMPLING_FREQ, 49.0, -20.0, 1.3)
|
|
||||||
| | | |
|
|
||||||
sampling frequency | | |
|
|
||||||
center frequency | |
|
|
||||||
decibel gain |
|
|
||||||
Q factor
|
|
||||||
```
|
|
||||||
|
|
||||||
If you look at the definition for `bqf_peaking_config` in `bqf.c`, you'll see that the first variable is `fs`, which is defined as the sampling frequency in the little blurb above the function's definition. Similarly, `f0`, `dBgain` and `Q` are all defined, too. That's how we know in what order we should put the relevant variables to define our filters.
|
|
||||||
|
|
||||||
In fact, `bqf.c` contains definitions as well as hints for many different kinds of filters. Take a look through the file and see what you can find.
|
|
||||||
|
|
||||||
## Sampling frequency
|
|
||||||
|
|
||||||
Note that the sampling frequency is something that you should never need to change. You can either set it to `48000` manually, or you can set it to `SAMPLING_FREQ`, which is actually just an alias for `48000`. Either way is good.
|
|
||||||
|
|
||||||
## user.h
|
|
||||||
|
|
||||||
The last file we need to look at is `user.h`. This file has one line that is relevant to us: `#define FILTER_STAGES X`. You need to change this after you've defined your EQ profile. For example, if you have two filters, you need to change it to `#define FILTER_STAGES 2`.
|
|
||||||
|
|
||||||
## Full example
|
|
||||||
|
|
||||||
Let's say that you want to create an EQ profile with three filters:
|
|
||||||
|
|
||||||
- A high-pass filter with a center frequency of 65Hz and a Q-factor of 0.8
|
|
||||||
- A low-shelf filter with a center frequency of 7,400Hz, a decibel gain of 4.2dB, and a Q-factor of 4.3
|
|
||||||
- An all-pass filter with a center frequency of 12,000Hz and a Q-factor of 2.1
|
|
||||||
|
|
||||||
It might be worth it for you to try this yourself as an exercise, and see if you come up with what's in the example below.
|
|
||||||
|
|
||||||
First, we need to change `user.c` to be the following:
|
|
||||||
|
|
||||||
```
|
|
||||||
void define_filters() {
|
|
||||||
// First filter.
|
|
||||||
bqf_memreset(&bqf_filters_mem_left[0]);
|
|
||||||
bqf_memreset(&bqf_filters_mem_right[0]);
|
|
||||||
bqf_highpass_config(SAMPLING_FREQ, 65.0, 0.8, &bqf_filters_left[0]);
|
|
||||||
bqf_highpass_config(SAMPLING_FREQ, 65.0, 0.8, &bqf_filters_right[0]);
|
|
||||||
|
|
||||||
// Second filter.
|
|
||||||
bqf_memreset(&bqf_filters_mem_left[1]);
|
|
||||||
bqf_memreset(&bqf_filters_mem_right[1]);
|
|
||||||
bqf_lowshelf_config(SAMPLING_FREQ, 7400.0, 4.2, 4.3, &bqf_filters_left[1]);
|
|
||||||
bqf_lowshelf_config(SAMPLING_FREQ, 7400.0, 4.2, 4.3, &bqf_filters_right[1]);
|
|
||||||
|
|
||||||
// Third filter.
|
|
||||||
bqf_memreset(&bqf_filters_mem_left[2]);
|
|
||||||
bqf_memreset(&bqf_filters_mem_right[2]);
|
|
||||||
bqf_allpass_config(SAMPLING_FREQ, 12000.0, 2.1, &bqf_filters_left[2]);
|
|
||||||
bqf_allpass_config(SAMPLING_FREQ, 12000.0, 2.1, &bqf_filters_right[2]);
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Next, we need to change `user.h`: `#define FILTER_STAGES 3`.
|
|
||||||
|
|
||||||
And...that's it! Once you build your firmware and put it onto the amplifier board, your new EQ profile will start working immediately (even if it sounds awful, like this one).
|
|
||||||
|
|
||||||
## Maximum number of filters
|
|
||||||
|
|
||||||
One last note: currently, the amplifier board can support a maximum of six filters. If you try to define more, the sound will become quite choppy.
|
|
||||||
|
|
||||||
## And...you're done!
|
|
||||||
|
|
||||||
Happy EQing!
|
|
Loading…
Reference in New Issue