This program analyzes incoming PCM data on the fly and passes the results to files. The C++ source code is available and should be portable to other platforms at reasonable effort. The open source library FFTW version 3.x is utilized for fast operation. Analyze is optimized to use sound devices for the A/D and D/A conversion.
Analyze is
just the core application without any platform dependent stuff.
The recording and the playback of the PCM stream as well as some buffering, to handle real time operation, must be provided with other platform specific tools like arecord/aplay (Linux) or playrec (OS/2). AFAIK nothing simple like that is available for Windows - sorry guys, so I do not recommend that OS for this purpose.
It is absolutely essential to use the same sound device for input and output. Analyze makes heavy use of the very high time correlation of input and output samples when the A/D and D/A converters are controlled by the same crystal oscillator for the sampling frequency. If different devices are used results of higher frequencies will derate after less than one second.
The graphic output is also not part of Analyze. I recommend Gnuplot but any other application that can deal with ASCII files will do the job as well.
See the example scripts for suggestions for the software setup including parameter files for Analyze.
In general it is a good advice to use the maximum native sample rate supported by your sound device. Only for audio only you might prefer 48 kHz even if you have an HD audio device. This will save some computing power and reduce the risk of sample drops. You definitely must avoid sample rate conversions.
Independent of your hardware I recommend 16 bits per sample. Using more usually adds no value. But it might make things worse because some sound devices do not perform well when choosing the maximum bit depth at the maximum sample rate.
Although the entire process will work with PulseAudio in principle I recommend not to use it. The chance to get unexpected resampling artifacts or stray sounds from other applications is significantly higher with PulseAudio. You can simply bypass PulseAudio by choosing the appropriate sound device for arecord and aplay. Young might need to terminate the PulseAudio daemon by pulseaudio -k before to get the device unlocked.
While the software setup is always basically the same the hardware varies with the desired measurements.
Channel map:
input channel |
two port measurement |
impedance measurement |
---|---|---|
L(t) | response signal |
voltage U(t) |
R(t) | reference signal |
current I(t) |
For high precision impedance measurements you need 4 wire connections and high impedance differential amplifiers. And to drive higher current you need an additional amplifier. The latter can be almost any audio amplifier, but the differential probes need some electronics. Two INA105 with an TL074 as impedance converter at its inputs will do the job.
Depending on the impedance to measure the reference resistor might be chosen from the range 100 mΩ to 50 kΩ roughly.
I furthermore recommend a 3 point calibration with a known impedance. This will
also compensate for the properties of the reference resistor with respect to its frequency response, e.g. because of parasitic
inductance.
If you do so you will be able to measure really low and high impedance from about 1 mΩ up to 10 MΩ, including the reactance of
capacitors and inductors.
There is a very simple variant that requires only one external reference resistor. Of course, you get only restricted
accuracy, but the most limiting factor is the maximum output current of the sound device. While old sound cards
often had a small built-in amplifier new ones sometimes do not even have enough power to drive a 32 Ω headphone.
You may overcome this limit by using an audio amplifier. But be careful, not all amplifiers have one terminal of the speaker
output connected to ground. And even if so it might introduce some stray current from its power supply.
Reasonable values for Rref are only between 33 Ω and 3,3 kΩ roughly.
In this configuration the voltage over the reference resistor cannot be sampled directly. Only the sum with the voltage over the test impedance is available. You need to tell Analyze by the diff option to use differential sampling mode. This causes the current (denominator) to be calculated by
I = (Right - Left) / Rref
I recommend to use 3 point calibration even in this simple configuration. Although you cannot use a 4 wire connection it will significantly improve the accuracy.
If you two-port network can directly deal with the line level of the sound device, e.g. an audio equalizer, it can be directly connected like shown in the image. The only special thing needed is an Y-cable to get the reference feedback.
To the left is the typical setup for speaker measurements. The properties of the audio amplifier (and sound device) have no relevant influence on the result. The microphone and its corresponding amplifier is the critical part. There are calibration services available for these combinations at reasonable charge.
You cannot use USB microphones calibrated by the manufacturer. They use a different crystal oscillator for the sampling rate than the sound card used for playback of the reference. This results in slightly different speed of playback and recording destroying the phase coherence used by Analyze to get high precision results. At least this is untested.
You should chose a sweep mode to reduce systematic errors due to harmonic distortion, intermodulation or non minimum phase responses.
Of course, there are more things to respect to get a reasonable speaker measurement, first of all some kind of anechoic
location. But this is by far beyond the scope of this document.
If your intention is to characterize the room and the speakers together for doing digital room correction, things are easier.
If you trust your amplifier to be linear or you want to compensate for its properties you can use a more simple setup. A sufficiently linear amplifier must satisfy the following properties:
In the sample folder there are a bunch of scripts to set up scenarios as mentioned above. They are all intended to be used with Ubuntu Linux, but you may use them as blueprint for other platforms too. See examples for some results created by these sample files.
The sample files assume that your sound card can deal with 192 kHz sampling rate (HD audio) which is quite common for modern PCs. If not you should adjust the sampling rate to 48 kHz and set the maximum frequency in fft.cfg to 20 kHz.
All file names mentioned here are in the same directory. The analyze executable have to be build before the scrips can be used. The Analyze executable is expected in the parent folder. If you have chosen a different build directory you should put a symbolic link there.
The *.cfg files are configuration files for Analyze. They are only slightly platform dependent. The files have an inheritance hierarchy by including the parent configuration file.
setup.cfg - root configuration used by all other configurations
It sets sampling rate, sample format and other global options. Furthermore is sets up the sample input/output to the fixed names rec.pipe and play.pipe respectively. As the name suggests this should be pipes (also called fifos) that receive or play raw samples from or to the sound device. The script setup_alsa_server.sh is invoked at program start. It creates the pipes and spawns the arecord and aplay processes to feed or consume the pipe data respectively.
It also writes the effective configuration to current.cfg which is used to extract some parameters for plots (fmin, fmax, fftlen and rref) into the file gpenv.gp intended to be included by Gnuplot.
Last but not least the file for the (last) FFT analysis results is set to data.dat.
fft.cfg - configuration file for FFT based real time impedance measurements
It selects an FFT length of 16,384, infinite loop mode and slightly pink noise as reference. To reduce measurement noise and analysis overhead it averages always 16 chunks of the FFT length before the results are passed to Gnuplot which should listen at stdout of analyze for plot commands. See measure.sh for an appropriate setup. This first command passed to Gnuplot is always l'gpenv.gp' to inject current configuration values into Gnuplot.
The sound output is set to symmetric mode because my amplifier has a symmetric input. You need not to change that unless you rely on the same phase to be present at the left and right sound channel.
fft-.2.cfg, fft-2.cfg, fft-20.cfg, fft-200.cfg, fft-2k.cfg, fft20k.cfg - files for selected reference resistors
These files just refine a few parameters for a bunch of different reference resistors used for impedance measurements. They also select the appropriate calibration file which must be named zero-RRR.dat. The calibration files must be created before the measurement can start. Use the calibrate?.sh scripts for this purpose.
You probably need to adjust this files for your reference resistors.
calibrate.cfg - calibration for impedance measurements
This instructs Analyze to perform a matrix calibration and write the result to the file zero.dat. You need to rename the resulting file matching the used reference resistor once the calibration has completed successfully.
room.cfg - record the loudspeaker response in the room
Currently not well tested.
roomscan.cfg - fast scan of the loudspeaker response in the current room
This activates two channel mode to record the response of both stereo channels at the same time. The scan is done with an FFT length of 65,536 in the range 20 Hz ... 20 kHz. Only frequencies separated approximately by halftone are used for analysis. You will not be able to extract reasonable values for the group delay with this coarse pattern. Furthermore some the frequencies of the 2nd and 3rd harmonic are unused to get a rough idea of distortion.
A sampling rate of 48 kHz is recommended for this type of measurement. Higher frequencies just add overhead and reduce accuracy.
Every 4 cycles of FFT length the result file data.dat is updated. The stdout of analyze is intended to be piped to Gnuplot. See measure.sh for an appropriate setup. This first command passed to Gnuplot is always l'gpenv.gp' to inject current configuration values into Gnuplot. Each time an FFT completed l'viewH.gp' is sent to Gnuplot to view the transfer function.
All measurement data since start is aggregated to get less noisy results. The longer you run the more precise you get. But due to systematic errors like non minimum phase system or intermodulation you will not get high accuracy. Simply stop when the result becomes stable.
The *.sh scripts are intended for Bash.
This script is intended for all measurements except for calibration. Use ./measure @filename.cfg with the appropriate configuration file name to start a measurement.
You can also pass additional command line parameters to Analyze. In fact @filename.cfg is also just an include directive for Analyze.
Just start the script and follow the instructions. The result is shown with Gnuplot after completion. Whenever possible
you should prefer the 3 point calibration.
After the calibration completed you probably want to copy the result file zero.dat to a more descriptive file
name matching your current setup. These files are also included by the impedance measurement configuration files.
After calibration a second verification step is recommended. It performs the same calibration but with the previously perfromed calibration result in zero.dat applied. The result is now written to zeroD.dat. At this point you should see a significantly improved result.
This script creates a record.pipe and play.pipe fifo and tries to start arecord and aplay in different terminals to feed and consume the pipe data respectively. The script is automatically invoked by Analyze if you use the sample configuration files above.
The setup also passes the content of the file mixer.in to amixer. You should use this to set defined mixer levels.
You likely need to adjust this file matching your sound hardware.
The macro files are named *.gp and used by the above scripts to visualize data. Feel free to adjust the according your needs.
This file is invoked by all sample scripts. Put general Gnuplot settings here.
This is invoked by the fft-*.cfg files to show the results of the data.dat file.
Show the amplitude of the diagonal and non-diagonal calibration matrix elements, the phase of the diagonal matrix elements and the absolute frequency dependent amplitude of voltage at both input channels.
This is the same as zero.gp but with slightly different scale for 3 point calibration.
Same as zero.gp, but for the file zeroD.dat.
This will show the speaker level and the group delay of a two channel measurement.