Python Open Room Correction (PORC)

simplified!

I'm still trying to get my head around the pole distribution in the new papers vs the earlier papers in the warped pole IIR filter design stage. It's a complex topic and I haven't looked at DSP stuff since uni 5+years ago and we really only covered the basics then.

DRC is not easy to wrap your head around, and the field is quite academic with very few resources for the layman. I had to resort to reading scores of academic papers and emailing questions to several PhD types. I have a Master of Engineering (Electrical) and I can barely understand most of it myself.

The beauty of the anaconda or enthought python distributions is that they cover those numpy/scipy/IPython/mpl dependencies in a single installer, that's why I chose anaconda for the install guide, keeps it simple for people new to scientific python world.

I agree 100%: this morning I removed the libsndfile dependencies from PORC! Now "all one has to do" is to install Anaconda and maybe sox if one is going to be using OpenDRC (like me).

A few things I would like to do soon:

  1. Automatically remove leading zeros from the IR for mixed-phase compensation.
  2. Add an option to export the .bin file for folks that use OpenDRC, thus eliminating sox from the equation.
 
DRC is not easy to wrap your head around, and the field is quite academic with very few resources for the layman. I had to resort to reading scores of academic papers and emailing questions to several PhD types. I have a Master of Engineering (Electrical) and I can barely understand most of it myself.

That makes me feel a lot better about myself, I am B.Eng(elec) but work mostly in power distribution planning so I don't exactly do much of this stuff ;)

I've been scratching my head trying to work out how to generate the warped pole distribution based on Bark scales or ERB and I don't feel like I'm any closer yet. I'm taking roughly the same approach just reading lots and seeing what's done already. I think some of the stuff on this page - WarpTB - Matlab Toolbox for Warped DSP (pre-release) - might be of interest but working out what parts is applicable to room correction is ... challenging!

I agree 100%: this morning I removed the libsndfile dependencies from PORC! Now "all one has to do" is to install Anaconda and maybe sox if one is going to be using OpenDRC (like me).

A few things I would like to do soon:

  1. Automatically remove leading zeros from the IR for mixed-phase compensation.
  2. Add an option to export the .bin file for folks that use OpenDRC, thus eliminating sox from the equation.

Well you can just about tick the second one off that list! I was working tidying up my code for this that I actually worked out on the weekend, but I was just making libsndfile optional .... which isn't necessary as of 30mins ago haha.

Here is a commit to my branch that should show how I did the bin file part. https://github.com/objektifi/porc/commit/c26c9dacfb0417e9cfec1e067a95850cb21f7322 Some of that code isn't useful anymore and I'd have to rebase on your new updates and apply the changes that remain relevant before sending a pull request. It's just ticked over midnight here so I'm not likely to do that tonight! Mostly the section for new argument and the bin file generation itself could be used directly so it shouldn't take long.


The interesting part is:
+ f = open(filter, 'w')
+ norm(np.real(equalizer)).astype('float32').tofile(f)
+ f.close()

Though I don't have a opendrc here to test that file with but after importing it and the sox generated bin file to numpy arrays and comparing them I think the values look right and there is some small quantization differences.

Cheers,
Chris
 
Last edited:
Having some trouble with my git newbness and not really working out how to clean up some of my revert/update commits from the transaction log to put together a clean pull request for you.

Here is the diff for what I've got working at the moment that is now based on your most recent updates - https://github.com/objektifi/porc/commit/f18a5d204c079e4f1eb1e62bfb4c74a50eba2cc8 - somehow a few of your changes to the README show up in there though, I think I've rolled back one step too far before applying my commit, not sure how that happened. So, looks like I've got some reading to do on how to use git I think!! I guess I need to make a clean branch based on your 'master' then apply my changes and send a pull request based on that, probably a challenge for another evening for me.

Regardless, should be easier for you to use than the one that I linked in my last post.

Chris
 
Last edited:
Regardless, should be easier for you to use than the one that I linked in my last post.Chris

Thanks, Chris. I'll take a look within the next several days.

Git's learning curve is fairly steep; it's quite a powerful tool. I only know the basics on how to update and commit changes. Reverting and merging changes can be a big pain if you don't do it very often.
 
Thougts on Digital Room Correction (DRC)

After experimenting with room correction for the last year, reading dozens of academic papers, coding PORC, and building several different types of loudspeakers I have a few thoughts on "room correction":

When I first created PORC, I was listening to omnidirectional speakers (Pluto and Demokrit), that needed proper equalization badly. DRC worked excellent for this purpose; the difference was startling.

Earlier this year I constructed transmission line DTQWT mkII speakers, and the on-axis response without EQ it's quite good with these loudspeakers. In fact, I would say that my current speakers don't need correction with the exception of compensating for low frequency room modes.

I believe that early reflections above the transition region in a typical home listening environment filled with furniture, etc, don't require correction if you have a nice set of speakers with very a good anechoic response. Because of the precedence effect, the direct sound we hear dominates our perception of quality. If the anechoic behavior is good, then the direct sound we hear in a typical room is going to be good. Early reflections aren't something to worry about or need "correcting" (see Floy's Toole's paper, "Loudspeakers and Rooms for Sound Reproduction—A Scientific Review")..... most people would probably agree that early reflections actually help improve the listening experience.

The problem in a typical room originate from below the transition region, where low frequencies live. These can cause nasty room modes in an untreated/bad room. I believe that a smart combination of room treatment, multiple sub-woofer placement (in each corner [total of 4] or two placed asymmetrically - See Chapter 13 of Dr. Floyd Toole's book and/or the aforementioned paper), and finally DRC can help tame this problem.

There are limits to DRC in regard to "room correction,", although it has the potential to automatically equalize your speakers if your speakers aren't very good to begin with, and potentially help tame room modes after other methods have been tried first - room treatment, multiple strategically placed woofers, etc...
 
in upper 300 Hz region correction some how will destroy stereo imaging/stage.

Can't say I observed the same thing with my omni's, as I had a very nice sound-stage with DRC applied. The speakers sounded not very good uncorrected, but quite nice w/ PORC applied. The improvement was startling.

As alluded to before, I believe "Room Correction" is a misnomer. More accurately, we could call it "loudspeaker correction" or simply "automatic equalization...."
 
I think it's down to the measurements that you're using to generate the 'correction' filter.

The counterpoint to kaameelis' hypothesis is that using a single in room measurement and correcting for room modes will only be of limited utility. Consider also that baffle edge diffraction and other artefacts may arrive within the measurement window but almost certainly shouldn't be corrected for. Is it possible that the omni speakers greenm01 was using had less issues in that regard hence more positive result with less fiddling of the measurement results before processing?
 
The Introduction section in this paper from earlier this year by Bank, gives an interesting run down of exactly the issues we're talking about in this thread at the moment

Yes, that's a very good paper. Interestingly, I was explaining to Dr. Bank (in a private email) that I no longer use room correction on my new loudspeakers, and he agreed that a well designed speaker may not need correction if the anechoic response is already smooth. His observation in regard to low frequency correction is in sync with Dr. Toole.

For bass correction, I would personally consider strategically distributing multiple woofers in the room, applying room treatment, and then finally DRC/EQ as a last resort.

As others have mentioned, at high volumes it's probably not a good idea to be driving your amplifiers with +/- 15-20dB correction..... You are definitely going to clip your amp.
 
Last edited:
Sorry for dredging up an old thread. I see greenm01 has not been active here for a while, so I'm posting this here to hopefully save someone else the trouble of figuring this out themselves.

The current master-trunk version of PORC may output incorrect binary files when run on Windows. This is caused by the output .bin file being opened for writing in text mode instead of binary. Changing the file access mode on line 231 from 'w' to 'wb' will fix the problem:

Code:
f = open(filter, 'wb')
 
Sorry for dredging up an old thread. I see greenm01 has not been active here for a while, so I'm posting this here to hopefully save someone else the trouble of figuring this out themselves.

The current master-trunk version of PORC may output incorrect binary files when run on Windows. This is caused by the output .bin file being opened for writing in text mode instead of binary. Changing the file access mode on line 231 from 'w' to 'wb' will fix the problem:

Code:
f = open(filter, 'wb')

Thanks for pointing that out, greenm01 gave me access to the repository, so I've just fixed that :)

Chris
 
Thanks!

I had some spare time, so I added a few things to the script. Attached is the modified python source file.

Changelog:
+ Slightly more verbose output
+ Added an option to trim leading slience (--trim) with an adjustable threshold value (-s [0,1])
+ Added an option to skip showing the FR plot (--noplot)
+ Added an option to output 32bit .wav files (-o wav32)
 

Attachments

  • porc.txt
    12.4 KB · Views: 93
Thanks for those new features, if you're able to do a PR on github that might make things easier, I need to set git up on my new OS install so I may not have time to look at this until the weekend. The trim leading silence option will be handy. I have in mind an IPython Notebook widget interface also but I haven't had time to create that yet.


Regards,
Chris
 
I actually whipped up a quick C# front-end for PORC yesterday, I can post it somewhere if there's interest. I already started porting it to Python/Tkinter for cross-platform compatibility, but my with lack of experience with Tkinter and general Python newbness it might take a day or two.

I'll look into putting in a pull request for the changes later today.
 
greenm01: I'd be happy to help in any way I can. My Github account is anlin93. I have no previous experience with Github so I'll do some reading up before changing anything to avoid messing up your repo.

As for the the C# GUI I made yesterday, it is a bit rough around the edges as it was originally meant for my use only. I can post the source somewhere for you and hochopeper/Chris, as I don't think it is ready for a public release just yet. In any case, I don't think a Windows only graphical interface is a good long-term solution, which is why I've already started work on a very similar 'native' Python/Tkinter GUI.

hochopeper: I just put in a pull request for the changes I made. I'll post later with some thoughts about the UI, it's getting really late..