HOWTO: Quick Frequency Response Measurements Using JAPA and Faust

Post fully complete "how to" guides and tutorials here. This is a great place to get feedback on stuff you might put in the wiki.

Moderators: MattKingUSA, khz

CrocoDuck
Established Member
Posts: 1133
Joined: Sat May 05, 2012 6:12 pm
Been thanked: 17 times

HOWTO: Quick Frequency Response Measurements Using JAPA and Faust

Post by CrocoDuck »

Let's say we have something in our audio path and we want to know how it modifies our audio signal. It might be an unknown stompbox or even our room.

If this something does not produce nonlinear distortion (like clipping, compression or similar) then we can use this simple method.

JAPA is a nice little tool by Fons Adriaensen. From his web page:
Fons Adriaensen wrote: Japa (JACK and ALSA Perceptual Analyser), is a 'perceptual' or 'psychoacoustic' audio spectrum analyser.
In contrast to JAAA, this is more an acoustical or musical tool than a purely technical one. Possible uses include spectrum monitoring while mixing or mastering, evaluation of ambient noise, and (using pink noise), equalisation of PA systems.
This HOWTO assumes that JAPA is already installed on the system and that it works with JACK correctly.

Don't be scared by the quantity of text: it is actually all simple. The fact is that I like to explain things in details (or at least I try to...).

1: The basics

Every linear system has an impulse response. Let's call the unknown impulse response of the system under test h(t), where t is time, in seconds. So, if we give an input b(t) to the system, we get an output a(t) = b(t) * h(t), where * denotes convolution.

We can describe a system also in the frequency domain. Through Fourier transform we can get these quantities:

h(t) -> H(f) system frequency response
b(t) -> B(f) input spectrum
a(t) -> A(f) output spectrum

where f is frequency, in Hertz. H(f) will be the frequency response. For example, for filters it is the law that, for each value of frequency, tells us the level and phase of the output. In frequency domain things are easier, with the output spectrum being easily calculated through ordinary multiplication:

A(f) = B(f) . H(f) (. denotes multiplication)

Hence, we can find H(f) easily (let's not dig into the maths about why this is not always appropriate):

H(f) = A(f) / B(f)

This is a very crude way to do it, but it most often works, and we can use JAPA for that.

2: A test ride

Let's test things out first. Let's fire up JACK and JAPA. Then, let's open up Calf filter (our test bed) and let's set this up:

Image

We can see that JAPA has two built-in signal generators, one white noise generator and one pink noise generator. Go back to this:

H(f) = A(f) / B(f)

we need a broadband input signal so that we can solve the equation above for as many values of f as possible. So we use noise, which is a signal made of many different frequencies. But it doesn't need to be flat (white) noise. In fact, above we connected the pink noise generator. Then, the input signal goes directly into JAPA in_2 to act as the reference, while the test bed output goes into JAPA in_1. The fact that we use a reference input removes the need to use white noise and makes the measurement smoother. On the side panel we assign the input to A and B (see why I called the signals above that way?) and then, in the traces section, we set up JAPA to show us A/B. We can adjust the scale using the controls below the input assignment section, and we are done! What we see in JAPA has a very good agreement with the expected shape as shown by Calf filter. If we play with Calf filter parameters we will see the plot in JAPA changing accordingly.

Why this works? (intuitive explanation with less maths)

In the frequency domain division acts like a "comparison operator". All of we are doing is to compare the spectrum at the input of the system-under-test (Calf filter in this case) to the spectrum at its output, to find out what changed. Given that what changed is due to the system response, that's what we find.

3: Soundcard Response

With the same method we can measure our soundcard response too!

But first, what we do to measure the soundcard? We just loop it back as shown here.

Image


To avoid excessive levels due to feedback, please start with all controls with volume down to 0!
Then, slowly raise output level and input gain until you have a safe level. In my case I connected system playback_1 back to system capture_1 with an audio cable.

To be clear, what we measure in this way are actually 2 things. In fact the signal flows as follow:

JAPA noise output -> Soundcard DA converter -> Soundcard Output Stage -> -> Soundcard Input Stage -> Soundcard AD Converter -> JAPA in_1

This method allows us to measure whatever we put between JAPA noise output and JAPA in_1 (provided that we stream also a reference to in_2). So we are actually assessing the combined response of Soundcard input and output.

We might be then tempted to think that we can just do as above, but instead of Calf filter we put our soundcard between JAPA noise output and JAPA in_1. However, if we do just that by sending the noise to system playback_1 and by routing system capture_1 to JAPA input 1, then we will only have a wiggly line:

Image

Why is that happening? Well, the let's look at the equation once again:

H(f) = A(f) / B(f)

A(f) is the spectrum of the system-under-test output, while b(t) is the spectrum of the signal we input to the system-under-test, i.e. our reference. While we supply b(t) to JAPA in_2 digitally, in_2 goes into the DA/AD converters of the soundcard, so it goes through additional latency!

Now, when we try to solve the equation above, A(f) must be the output which comes as a consequence of supplying B(f) as an input. This means that there is causality between them: B(f) => A(f), so we are comparing the input against the output it produces.

If latency is introduced this does not happen: by the time our reference signal gets into JAPA in_2 its output still has to arrive at JAPA in_1, as latency is delaying it! The signals at JAPA in_1 and in_2 are hence not correlated at all, so we are measuring nothing! How we can solve this?

Compensation Delay Line

Easy, by introducing an equal delay for the reference signal, so that we restore the lost causality!

First, let's measure our soundcard latency. Another software tool based on work by Fons can be used for that. It is called jack_iodelay. Just launch it from the command line and connect it like this:

Image

As you can see I have a fairly large latency, as I am running with these settings:

Code: Select all

/usr/bin/jackd -P70 -t5000 -dalsa -r96000 -p4096 -n3 -D -Chw:USB -Phw:USB
It does not matter how big is the latency, and for measurements it is best to set up for highest stability (higher latency) so that xruns do not pollute our tests.

So, now we see our soundcard latency, but if we loop back jack_iodelay to itself what we observe?

Image

That is, there is a latency associated with just streaming digital data, big as our JACK Frames/Period value (in samples). It is due to buffering and you can read about it here.

So, what value of latency our reference signal should have to preserve input/output causality? Well, given that a latency of Frames/Period samples will be introduced just by JACK alone, the correct value is the following:

soundcard latency - Frames/Period value

in our case: 17780.760 - 4096 = 13684.760 samples

How can we do it? For me, the easiest approach was to write a simple delay line with Faust. If you installed Faust from git, just drop this in a text file called fdelayLine.dsp (not really sure how much sense makes to put a license on 6 lines of code...):

Code: Select all

// Simple Delay Line

declare name "fdelayLine";
declare author "CrocoDuck o'Ducks";
declare copyright "CrocoDuck o'Ducks";
declare version "1.00";
declare license "LGPL";

de = library("delays.lib");

delayLine = de.fdelay(192000.0, samples)
with{
    samples = nentry("Samples", 0, 0, 192000.0, 0.001);
};

process = delayLine, delayLine;
Then, in a terminal, compile it to a standalone JACK GTK application by issuing this command:

Code: Select all

faust2jack fdelayLine.dsp 
This will create the executable fdelayLine you can launch from the command line:

Code: Select all

./fdelayLine
Alternatively, you can download the precompiled program here (not sure whether it will work) or use another delay program. Then, we just use it as follows:

Image

We see a way better result already! However, the raise in high frequency is not very realistic. I found that rounding the latency value to the nearest integer (13685 in this case) helps (maybe those intersample values are not too accurate):

Image

Now, that's a nice realistic soundcard frequency response! It might be worth to set the speed control to slow, as the low frequency will be probably pretty wiggly.

So, in short:
  • Find your soundcard latency, in samples.
  • Subtract from it your JACK buffer size.
  • Round the result to the nearest integer.
  • Connect JAPA noise output to playback_1, loop your soundcard playback_1 output to capture_1 input and route capture_1 to JAPA in_1.
  • Route JAPA noise output to the delay line with the value of latency we calculated above, and then the output of the delay line to JAPA in_2.
4: Measuring Microphones Relative Responses

Let's imagine we have 2 microphones and we want to compare their frequency responses. How can we do it? Look at the picture below.

Image

The picture represent a loudspeaker on the left, to which we have connected one of the JAPA noise outputs, and two microphones under test (the black dots), going to our JAPA inputs. JAPA is configured as always. Now, what happens to the noise output signal?

As it gets radiated from the speaker, it spectrum gets multiplied by the speaker frequency response Hs. By calling the spectrum of the noise N:

N . Hs

Then, the radiated noise propagates through air to the respective microphones. The propagation through air is described by the frequency responses Hsm1 and Hsm2. So, at each of the microphones, the spectrum of the noise looks like this:

N . Hs . Hsm1 (mic 1)
N . Hs . Hsm2 (mic 2)

Finally, each of the microphones has its own response Hm1 and Hm2, so the spectra at JAPA inputs are:

N . Hs . Hsm1 . Hm1 (JAPA in_1)
N . Hs . Hsm2 . Hm2 (JAPA in_2)

Now, JAPA will divide the spectrum at in_1 by the spectrum at in_2, giving as a result:

(Hsm1 . Hm1) / (Hsm2 . Hm2)

Since N and Hs cancel each other. Now, imagine that the two microphones are very very close (but not touching!). Then, Hsm1 and Hsm2 will be very similar, almost equal:

Hsm1 ~ Hsm2

Meaning that we are left with:

Hm1 / Hm2

Again, division means comparison, so the curve we will observe on JAPA shows the difference between mic 1 with respect mic 2 (the reference). For example, if the curve at 500 Hz is +10 dB we know that mic 1 response at 500 Hz is +10 dB with respect whatever value mic 2 response has at 500 Hz.

Now, as a final step, imagine that mic 2, the reference, has a very very flat response. For example, this microphone has a very good flat response. This will mean that Hm2 is a straight line, so Hm1 / Hm2 shows, a part for an overall gain factor, the exact response of Hm1.

Be careful though! Remember about this approximation: Hsm1 ~ Hsm2. This is true only if the mics are very close. The closer the mics the higher the frequency up until we can consider Hsm1 and Hsm2 identical. This is because the space in between the mics is short. Every sound field is made by many components at different wavelengths, which is related to frequency. The higher the frequency, the shorter the wavelength. If the wavelength of the sound is much longer than the space between the mics, than the wave at that frequency is not varying a lot between the two mics. On the contrast, high frequency sound which has wavelength shorter than the gap between the mics will vary a lot between the mics, producing a difference.

In other words: Hsm1 and Hsm2 would be identical if we could put mic 1 and mic 2 in the very same point in space. But we can't, we can only put them very close. Since low frequency sound varies very little in space, as it has a long wavelength, then mic1 and mic2 appear as they were in the same location for low frequency sound.

As a result, this method will show you a real comparison of the microphones up to a certain upper frequency, after which the result is not accurate. How will we understand where the approximation breaks? Well, the volume of air between the mics will, excited by the noise, bounce between them. This will produce a high frequency resonance. If you see a resonant peak at the end of the spectrum (usually after 10 kHz) don't worry: that's not real and it is due to the approximation breaking down.

This is a very easy and good method to test microphones frequency responses, and one of the very few that can be done easily in any kind of room.

5: Room Responses and Compensation EQs

We can then try to design compensation EQs for a system. For example, we might want to compensate for the response of our room. Then, we could place a microphone where our head is gonna be while listening and, for each channel, we could realize the following chain (here represented for only one channel):

Image

Which is very similar to that of the sound card measurement. Simply speaking, our output noise will go the one output channel, then to the speaker. Then, we put our mic in position and we route it into a soundcard input. Instead to connect this soundcard input directly to JAPA in_1, we put an EQ in between. In this example, Calf EQ.

As for the reference, we route our test signal to JAPA in_2, but through a compensation delay line. How we calculate the compensation delay in this case? We can use jack_iodelay to assess the latency of this chain:

Latency 1: soundcard -> speaker -> mic -> soundcard -> Calf EQ

and this chain:

Latency 2: Calf EQ latency.

Things might get a bit loud when measuring Latency 1, but it should work. Now, the compensation delay will be:

round(Latency 1 - Latency 2), where round() means that we round to the nearest integer.

What are we actually doing? If the EQ is flat, then we are essentially measuring the room response. However, as we tweak the EQ, we will change the curve on JAPA plot. When the EQ is flat (or flattish, rather) it means that we found the EQ that compensates for the room response, as the combined response of room and EQ is flat.

Here a pic of how my room response looks when Calf EQ is bypassed:

Image

And here when I activate the best EQ I could find:

Image

We can see that the measured response is much flatter! It wasn't too hard to find a decent EQ, and when I activate it the sound does sound more neutral to me. My speaker system is really lacking on the bass, so the EQ really helps in getting those bass out properly. However, as my speakers are small and cheap, they cannot really output that much low frequency sound without distorting a bit. So, to compare EQ ON and OFF fairly I had to lower down the volume. If you do a comparison yourself, make sure the loudness of EQ ON and EQ OFF is the same, or you will be unable to judge fairly if the compensation is good.

Oh, and remember to do this process for each channel. The EQ solution for every channel might actually vary. In my case, as the listening position is central in the room and the stereo speakers are symmetric, the difference was minimal.

How good of a compensation will it be? Well, we are limited by these:
  • The EQ we use: it will determine how easily we can match the room response.
  • The fact that we measure with a microphone. The mic response is different from that of our head so, even if we get a straight line in JAPA, the compensation will not be optimal when we put our head where the mic is. This will affect mostly the high frequency.
Last edited by CrocoDuck on Sun Jan 21, 2018 6:05 pm, edited 7 times in total.
User avatar
funkmuscle
Established Member
Posts: 2800
Joined: Mon Jun 02, 2008 2:30 pm
Has thanked: 129 times
Been thanked: 31 times

Re: HOWTO: Quick Frequency Response Measurements Using JAPA

Post by funkmuscle »

dude I'll have to sit with a beer or 6 and go over this. sounds quite interesting.
CrocoDuck
Established Member
Posts: 1133
Joined: Sat May 05, 2012 6:12 pm
Been thanked: 17 times

Re: HOWTO: Quick Frequency Response Measurements Using JAPA

Post by CrocoDuck »

funkmuscle wrote:dude I'll have to sit with a beer or 6 and go over this. sounds quite interesting.
Coo! By the way, I think there is another reason why the soundcard measurement is hard: decorrelation due to latency. I have in mind how to compensate for it. I will try it soon and update the above.
User avatar
funkmuscle
Established Member
Posts: 2800
Joined: Mon Jun 02, 2008 2:30 pm
Has thanked: 129 times
Been thanked: 31 times

Re: HOWTO: Quick Frequency Response Measurements Using JAPA

Post by funkmuscle »

CrocoDuck wrote:
funkmuscle wrote:dude I'll have to sit with a beer or 6 and go over this. sounds quite interesting.
Coo! By the way, I think there is another reason why the soundcard measurement is hard: decorrelation due to latency. I have in mind how to compensate for it. I will try it soon and update the above.
Nice! :D
User avatar
lucianodato
Established Member
Posts: 156
Joined: Sat May 15, 2010 9:00 pm
Has thanked: 3 times
Been thanked: 16 times

Re: HOWTO: Quick Frequency Response Measurements Using JAPA

Post by lucianodato »

I remember using vst plugin analyzer in the past. Got too look into it. Thanks for sharing! :)
Arguy (IRC)
nayam
Posts: 1
Joined: Fri Aug 30, 2019 6:21 am
Contact:

Re: HOWTO: Quick Frequency Response Measurements Using JAPA and Faust

Post by nayam »

Interesting thread!! I'd like to use vst plugin analyzer. Thanks for sharing.
User avatar
sadko4u
Established Member
Posts: 986
Joined: Mon Sep 28, 2015 9:03 pm
Has thanked: 2 times
Been thanked: 359 times

Re: HOWTO: Quick Frequency Response Measurements Using JAPA and Faust

Post by sadko4u »

Moreover, you can use a LSP Profiler plugin now made by CrocoDuck to capture real impulse responses of the room!
LSP (Linux Studio Plugins) Developer and Maintainer.
User avatar
lilith
Established Member
Posts: 1698
Joined: Fri May 27, 2016 11:41 pm
Location: bLACK fOREST
Has thanked: 117 times
Been thanked: 57 times
Contact:

Re: HOWTO: Quick Frequency Response Measurements Using JAPA and Faust

Post by lilith »

I tried to do this here, but don't know if i'm measuring bullshit. I have a EQ settings for room correction from REW and I want to check if they make the response flatter.

Here's the connections from Catia:

Image

The pink noise generator goes into JAPA in 2 and the mic goes through EQ into JAPA in 1.
With the MIC turned down I get this in JAPA:

Image

Blue is the Pink Noise coming from JAPA, Red is the signal from the MIC. Here I have the question why the amplitude of the pink noise is increasing again for higher frequencies (ok, likely cause it's the psychoacoustic loudness). Is this because I didn't do any soundcard correction? This is the graph with the mic capturing the pink noise from the loudspeaker:

Image

You see peaks at ~70 and ~130 Hz. This is where my room modes are located.

This is when I look at the ratio:

Image

That's the frequency response from REW:

Image

It looks similar, but some peaks like the one at ~500 Hz in the JAPA Graph is missing in REW. Also the region below 70 Hz is much more pronounced in the REW plot.

And this is what I get when applying my EQ settings from REW:

Image

I should get a flat line more or less, but it's far from being flat. Pretty sure there's something wrong.

Does the latency correction play any role when doing such measurements with random noise??
User avatar
lilith
Established Member
Posts: 1698
Joined: Fri May 27, 2016 11:41 pm
Location: bLACK fOREST
Has thanked: 117 times
Been thanked: 57 times
Contact:

Re: HOWTO: Quick Frequency Response Measurements Using JAPA and Faust

Post by lilith »

sadko4u wrote:Moreover, you can use a LSP Profiler plugin now made by CrocoDuck to capture real impulse responses of the room!
Is it also possible to use it for correction?
User avatar
sadko4u
Established Member
Posts: 986
Joined: Mon Sep 28, 2015 9:03 pm
Has thanked: 2 times
Been thanked: 359 times

Re: HOWTO: Quick Frequency Response Measurements Using JAPA and Faust

Post by sadko4u »

lilith wrote:
sadko4u wrote:Moreover, you can use a LSP Profiler plugin now made by CrocoDuck to capture real impulse responses of the room!
Is it also possible to use it for correction?
You mean, you need an impulse response that will compensate room settings?
Currently no, we can just take a response of a linear system at this time.
LSP (Linux Studio Plugins) Developer and Maintainer.
User avatar
lilith
Established Member
Posts: 1698
Joined: Fri May 27, 2016 11:41 pm
Location: bLACK fOREST
Has thanked: 117 times
Been thanked: 57 times
Contact:

Re: HOWTO: Quick Frequency Response Measurements Using JAPA and Faust

Post by lilith »

sadko4u wrote:
lilith wrote:
sadko4u wrote:Moreover, you can use a LSP Profiler plugin now made by CrocoDuck to capture real impulse responses of the room!
Is it also possible to use it for correction?
You mean, you need an impulse response that will compensate room settings?
Currently no, we can just take a response of a linear system at this time.
The IR file I will get from REW, just have to find a way to invert it. Maybe that's even possible with REW, have to check this.
CrocoDuck
Established Member
Posts: 1133
Joined: Sat May 05, 2012 6:12 pm
Been thanked: 17 times

Re: HOWTO: Quick Frequency Response Measurements Using JAPA and Faust

Post by CrocoDuck »

Hi there! Sorry for the late replies, being really busy these days.
lilith wrote:Does the latency correction play any role when doing such measurements with random noise??
Yes, absolutely. Without latency correction the reference signal arrives at JAPA before the measurement signal does. So, the quotient is not between a test signal and its "consequence" through the system being measured. This loss in causality kills the measurement.
lilith wrote:Is it also possible to use it for correction?
As sadko4u told earlier, not yet. I have a couple of ideas on how to do it, though. They stemmed by how I tried to implement a nonlinear profiler (still work in progress).

At the moment I cannot quite take part in development, but I plan to look into it when in the future I will be able to dedicate time to the LSP project again.
lilith wrote:The IR file I will get from REW, just have to find a way to invert it. Maybe that's even possible with REW, have to check this.
As far as I know, you can use REW to design your own biquad based compensation EQ which you can export for EqualizerAPO. Note that the same EQ parameters can be used with LSP parametric equalizers.

More info:
https://sourceforge.net/p/equalizerapo/ ... mentation/
https://lsp-plug.in/?page=manuals&secti ... x32_stereo
User avatar
lilith
Established Member
Posts: 1698
Joined: Fri May 27, 2016 11:41 pm
Location: bLACK fOREST
Has thanked: 117 times
Been thanked: 57 times
Contact:

Re: HOWTO: Quick Frequency Response Measurements Using JAPA and Faust

Post by lilith »

Thanks, then I got it. I will look into REW if I can export an inverted IR file. I used the EQ mode in REW to get some correction parameters in the 50-200 Hz range and manually entered them in EQ10 equalizer. APO is not available for Linux. I guess I will use the LSP then for that. Is this the Resonance filter I have to use? It's the only one that looks like the REW settings.

A more simple approach to test and correct the frequency response (though not in real time):

1. Record pink noise into a DAW through your speakers at listening position with a condenser MIC like the Superlux ECM 999
2. Record the pink noise directly into the DAW

Normalize both tracks and look at the signal through a spectrum analyzer:
This is shown here:

Image

Blue is the Pink Noise directly recorded into the DAW (I guess it's a straight line here as in the frequency analyzer the pink noise envelope is chosen (?) ), red is through the speakers and green is through the speaker but with an EQ in between with settings from REW.

You clearly see the two bumps in the red curve, which is due to some room modes at 70, 86 and 131 Hz. Now you can also add an EQ in your DAW and correct the red curve until it's flat like the blue curve. I only whould reduce the level and avoid increasing the level as this can lead to unwanted distortion of the speakers. That's a simple and straight forward way to get to know your room and to see where the problematic frequencies are.

At least the REW settings seem to correct more or less the low freq range and the sound is also much better after applying the correction. Not perfect but miles better than mixing in an untreated room. I put 8 45x45x100 cm bass traps in my room and it's still not sufficient. The decay time got much better, but the freq response is still almost unchanged!
User avatar
lilith
Established Member
Posts: 1698
Joined: Fri May 27, 2016 11:41 pm
Location: bLACK fOREST
Has thanked: 117 times
Been thanked: 57 times
Contact:

Re: HOWTO: Quick Frequency Response Measurements Using JAPA and Faust

Post by lilith »

Is it ok to choose the Generic EQ in REW?

Image

And which slope factor to use in the LSP EQ then and what type of EQ (resonance?)?

Settings:

Image
User avatar
sadko4u
Established Member
Posts: 986
Joined: Mon Sep 28, 2015 9:03 pm
Has thanked: 2 times
Been thanked: 359 times

Re: HOWTO: Quick Frequency Response Measurements Using JAPA and Faust

Post by sadko4u »

lilith wrote: And which slope factor to use in the LSP EQ then and what type of EQ (resonance?)?
You need to use special APO DR filters in LSP equalizer to match the REW settings.
Also, Since LSP equalizer provides APO-compatible filters, I'm currently working on this feature request sent to me as a feedback some time ago:

https://github.com/sadko4u/lsp-plugins/ ... #L196-L231
LSP (Linux Studio Plugins) Developer and Maintainer.
Post Reply