Python Open Room Correction (PORC)

I've created the Python Open Room Correction (PORC) project to generate room correction filters for OpenDRC, or any other convolution engine for that matter. The filter is based on the work of work of Dr. Balazs Bank.

PORC is intended to be a free command line tool. If you desire a fancy GUI feel free to fork this project (or pay for an expensive commercial software package).

PORC allows one to specify a target curve and generate the corresponding loudspeaker-room correction filters. The filters may easily be imported into OpenDRC. I've been listening on my system for the last few weeks and the result is excellent. It even sounds fantastic well outside the targeted sweet zone. Attached is a screen shot of my left channel speaker results.

Room EQ Wizard (REQ) is an excellent (and free) tool for measuring the loudspeaker-room impulse response of your system.

I realize I can do a much better job with documentation; this project is intended to be a work in progress. See the link above for the code.

/Mason
 

Attachments

  • eqplot.png
    eqplot.png
    171.8 KB · Views: 2,274
Nice ! Congrats for the hard work !

I've checked your website for an example of output file (i.e. FIR coefficients). Could you point to such a file? I'd like to look at the file format and see how much effort is required to use it with my own convolution device.

Cheers

Nick

(Looking at the equalizing curve, there's a boost by over 20 dB in the lower end. One has to be careful not to blow the speaker.)
 
Excellent idea, I'd been thinking of a similar project with python, I'll play with your code later in the week and save myself any duplication and just send pull request your way if I have anything to add :)

I'll also test it on osx 10.7 too.

With ipython I find less need for gui stuff (I find it distracting anyway)

hint ipython notebooks are pretty cool:
Code:
ipython notebook --pylab inline

I hadn't seen the papers from Dr Bank either so looks like I've got some reading to do!
 
Last edited:
How do the equalized and unequalized phase response compare?

The filter is minimum-phase, if that's what you're referring to.

In any regard it sounds fantastic. This loudspeaker-room correction filter, in combination with OpenDRC convolution, completely transforms my system. The result is "silky smooth." In retrospect my system definitely sounds "bright" and a little "harsh" without the filter. There's no going back.

One could test the filter with the free Foobar2000 convolution plugin on Windows. On Linux, one could try jcgui with Jack.

All one needs to do is purchase a calibrated measurement microphone and a descent audio interface. Room EQ Wizard is an excellent free software tool that will allow you to measure the impulse response of your speaker-room system. When measuring, make sure the audio playback device and the microphone are running on the same clock (i.e. audio interface).

I designed the script to be as simple as possible. I've had success in the past with DRC-FIR, but the learning curve is fairly high and setup/configuration can be a pain. The scientific computing packages for Python are quite nice.
 
Nice ! Congrats for the hard work !

Thanks. The real credit goes to Dr. Bank for developing the parallel filter. I took his MATLAB code and ported it to Python in order to make it more accessible to folks.

I've checked your website for an example of output file (i.e. FIR coefficients). Could you point to such a file?

If you look in the 'data' directory on Github, you can find the measured impulse response of my system. You can run this data through the filter to produce an example. The filter output is a mono wav file. You can use 'sox' to change it to your desired format.

(Looking at the equalizing curve, there's a boost by over 20 dB in the lower end. One has to be careful not to blow the speaker.)

The curves are actually normalized, but I shifted them to all fit on the same graph.
 
Last edited:
With ipython I find less need for gui stuff (I find it distracting anyway)

iPython is great! I believe the Scientific Python tools are viable alternatives to MATLAB and all the other commercial packages that cost an arm and a leg for non-student editions.

For this type of application working on the command line is very fast. The script does produce a nice graph of the output (see initial screenshot). The initial learning curve might be a little high to setup Python and all the required dependencies, but getting ones hands into the guts of things is in the spirit of open source and DIY anyway...!
 
Phase

It's worth looking at phase as well as magnitude, though getting good phase data is harder.

I plugged the impulse responses into Room EQ Wizard, and the output is 180 phase shifted from the input. This is typical behavior of an all pass filter.

RED = Convolution Output
GREEN = Input
 

Attachments

  • output.png
    output.png
    72 KB · Views: 1,930
  • input.png
    input.png
    74.2 KB · Views: 1,872
If you look in the 'data' directory on Github, you can find the measured impulse response of my system. You can run this data through the filter to produce an example. The filter output is a mono wav file. You can use 'sox' to change it to your desired format.

I don't have the required packages installed to run your code now, but it's definitely worth checking.
So the FIR coefficients are embedded in the wav file as fixed-point coefficients, is that correct?
In the example that you provide, how many coefficients are required for the processing? (and what's the sample rate?)

I also had a look at the link to the introduction where the original author models a system with a parallel structure of second order sections.

Again, I haven't been in the details of your code, but are you transforming an IIR processing into a FIR one in order to be able to use a convolution engine and because you don't have the appropriate parallel IIR structure at hand? Or is it because it's more efficient?

Also, how do you you perform the transformation from IIR to FIR? Is it an impulse response truncation?

Sorry if my questions are missing the point, I'm just discovering the algorithm.
 
So the FIR coefficients are embedded in the wav file as fixed-point coefficients, is that correct?
Yes. You can import the wav file into any standard convolution engine. On Windows, I like the Foobar2000 convolution plugin. On Linux, I like the jcgui (jconvolver front end) for Jack. For my main stereo system, I'm using MiniDSP's OpenDRC box.

In the example that you provide, how many coefficients are required for the processing? (and what's the sample rate?)
There is no limit on the sample rate. For my system, I'm using 48kHz to measure the impulse response of my system.

I added the '-n' flag to PORC to specify the number of output filter taps. The default set to 65536 (which is the same as DRC-FIR), but you can change it to anything. The limiting factor would be your input signal. At 48kHz my measured impulse response is above 130k samples.

The OpenDRC box has a limit of 6144 taps, thus I use -n 6144.

I...are you transforming an IIR processing into a FIR one in order to be able to use a convolution engine and because you don't have the appropriate parallel IIR structure at hand? Or is it because it's more efficient?

Also, how do you you perform the transformation from IIR to FIR? Is it an impulse response truncation?
Rather than muddy the waters in regard to algorithm, I believe you would be best served by reading Dr. Bank's papers. I'm still coming up to speed on the DSP theory myself. This one is a good place to start, although Dr. Bank has a number of good references on his webpage:

http://www.mit.bme.hu/~bank/publist/spl08.pdf
 
Last edited:
Hello, trying to use this interesting porc.py, I allways get same error. any idea ?

That's a standard Python language error when the source code in your script is misaligned., i.e. all the tabs do not line up correctly. Did you alter the source code?

See here for an example: Python “expected an indented block”

I just checked out a fresh copy of PORC from Github and successfully ran it on both Linux and Windows 7.
 
For anyone wondering, I've tested in OSX and appears to work.

System:
-OSX 10.7.4
-Python 2.7.3 (installed via homebrew because the Python packaged with OSX is never up to date and needs sudo to install any python libraries and I don't agree with that on principle)
-Latest version of all dependencies from pip.

I've tested inside an iPython 'notebook' because that's my preferred way to work with python code and I can get matplotlib graphs output to the same window. I'd expect it to all work as intended from the command line.
 

Attachments

  • porc_testing.jpg
    porc_testing.jpg
    103.4 KB · Views: 877
Last edited:
Hi greenm01
congratulations for your work, I would like to know if you or someone other have compared the correction obtained from "Python Open Room Correction" with those from DRC <http://drc-fir.sourceforge.net/>.
Actually I have a system with FIR filter coefficients calculated by DRC and applied by brutefir <http://www.ludd.luth.se/~torger/brutefir.html> and I am pretty satisfied, when I will have the time (unfortunately not in the near future) I will try PORC + jconv.

Ciao
Andrea
 
Hi Andrea,

I would like to know if you or someone other have compared the correction obtained from "Python Open Room Correction" with those from DRC <http://drc-fir.sourceforge.net/>
I've had good success with DRC-FIR as well. My goal with PORC is to make the script simpler to use, and also employ a filter algorithm well documented in literature. I believe the results are quite nice. Subjectively I have not vigorously compared DRC-FIR to PORC.

I'm also a Python fan and wanted to make Dr. Bank's MATLAB scripts more readily accessible. There are a number of very expensive commercial packages that offer room correction. This is a shame because there are a number of readily available Open Source tools available for the DIY inclined person.