Python Open Room Correction (PORC)

Here is the updated code https://github.com/smartrobot/porc let me know if there are any issues. When porting the code I only ran into syntax and casting errors. Nothing to technical.
Hi Smartrobot,

Many thanks for the porting to Py3.

I've run into few issues.... some maybe related to the code itself (?).
I get this error:
Code:
TypeError: 'numpy.float32' object cannot be interpreted as an integer
when I perform python porc.py -n 1024 -o bin data/file-24b-48k.wav data/bin/file-24b-48k.bin
It doesn't matter whether I use 32 b or 24 b files. But I still get a .bin. I just don't know for sure it's correct.
I also don't have any kind of visual just these comments:

Code:
Loading impulse response

Sample rate =  48000

Generating correction filter

Output filter length = 1024 taps
Output filter written to data/bin/file-24b-48k.bin

Now what I am trying to achieve is a bit of a warped usage of PORC I guess but it shouldn't be the reason for the previous error.

I try to actually get a .bin from a filter correction I made with REW (which AFAIK can't output .bin). So I use a random measurement (A) together with my calculated filter impulse response (B) and I perform A/B (=C). Then I perform C/A. Which gives me pretty much 1/B. I input that in PORC and when I import that as a FIR into my miniDSP 2x4HD it seems that there is an error on the frequency scale and also some weird stuff in the low end.
See pictures. (in REW, green curve is the calculated filter curve, the purple the inverse of it. The miniDSP curve should look as close as possible to the green curve...)

Any advice would be appreciated.
Cheers,
 

Attachments

  • REW_Filters+inverse.jpg
    REW_Filters+inverse.jpg
    155.2 KB · Views: 64
  • miniDSP_FIR.jpg
    miniDSP_FIR.jpg
    45 KB · Views: 70
First of all the miniDSP 2x4HD only runs FIR filters at 96,000 samples per second. It is not adjustable to my knowledge. So loading a filter designed to run at 48,000 sps will produce "warped" results. Is it possible that this is what you are seeing? I recall that older, less expensive version, the 2x4, runs filters at 48,000 sps.

From my testing of the 2x4HD, using Arta and my sound card to measure the frequency response, I have found that filters with relatively low cutoff frequencies do not perform as expected. A 4th order 100 Hz low pass will give an initial 4th order roll off for maybe 10 dB and then it just flattens out to be something like first order roll off. I suspect this is due to the huge ratio of cutoff frequency to sample frequency creating filter coefficients very close to 1.0000 or 0.0000 so the round off error of the processors limited math precision creates large errors in the filter sums.

So great to see you working on this. I have tried to use the Align2 GUI version to run PORC but I was never able to get that to run. I was probably loading the wrong version of libraries or something.

https://www.ohl.to/about-audio/audio-softwares/align2 Align2 includes a file conversion utility that works with .bin and .wav files.

Align2 is a free audio software designed by JL Ohl to calculate loudspeaker correction for OpenDRC hardware or for convolution softwares.
It was first designed as a GUI for DRC (D. Sbragion) or PORC (M. Green) but evolved with many added functions.

Unfortunately when I run Align2 it has a bug in it so that it only creates filters at 48,000 sps, (the GUI sps selection is ignored) so they are not useful in miniDSP 2x4HD. I have never got a response from its author. Align2 is also dependent on an old version of Octave which is tricky to install. The old version Octave setup screen requires you to scroll down the "choose components" popup window and check the Octave Forge box. If you don't notice that scroll bar on the right side of the popup screen, your screwed and none of the plotting will work.

I have run OpenDRC in DOS and it works at all the sample rates just fine creating FIR filters. It requires long commend lines. I created .bat files to run all the commands.

I have also created room correction filters using REW. I didn't realize it could do that for a long while as the user interface is non-obvious. Follow a tutorial on youTube to see where to click to generate the filter. It is just a line of text, not an obvious button icon.

It would sure be great if the source for Align2 was available so a working GUI for PORC and OpenDRC could be fully functional again. I started trying to make a GUI for openDRC myself using Octave, but it didn't work very well.

If you don't have a miniDSP, equalizerAPO is a great way to run filters on a PC. Filters can be assigned to different inputs and outputs on the PC audio directly. https://sourceforge.net/projects/equalizerapo/
 
Last edited:
Hi all,
I commited align2 a very long time ago. But in the last years, I worked mainly on loudspeakers.audio wich includes an optimised calculation of FIR corrections. Maybe I should also add PORC to this online solution. And why not add conversion tools to this web interface.
I'm not so found of updating align2 (it works with python3 with some adjustments) but I have to think about it...
 
  • Like
Reactions: 1 users
Hi all,
I commited align2 a very long time ago. But in the last years, I worked mainly on loudspeakers.audio wich includes an optimised calculation of FIR corrections. Maybe I should also add PORC to this online solution. And why not add conversion tools to this web interface.
I'm not so found of updating align2 (it works with python3 with some adjustments) but I have to think about it...
Thanks for sharing all your great work with everyone. I will spend some time tomorrow trying your new website. Hopefully your website gets more exposure and you can make some money with it. This was the first I heard of it. The new site seems like a great solution. Many people are not able or don't want to install software or python etc. to run the shareware/donation software but they also don't want to spend thousands on special hardware or stand alone commercial software.
 
First of all the miniDSP 2x4HD only runs FIR filters at 96,000 samples per second. It is not adjustable to my knowledge. So loading a filter designed to run at 48,000 sps will produce "warped" results. Is it possible that this is what you are seeing? I recall that older, less expensive version, the 2x4, runs filters at 48,000 sps.

From my testing of the 2x4HD, using Arta and my sound card to measure the frequency response, I have found that filters with relatively low cutoff frequencies do not perform as expected. A 4th order 100 Hz low pass will give an initial 4th order roll off for maybe 10 dB and then it just flattens out to be something like first order roll off. I suspect this is due to the huge ratio of cutoff frequency to sample frequency creating filter coefficients very close to 1.0000 or 0.0000 so the round off error of the processors limited math precision creates large errors in the filter sums.

So great to see you working on this. I have tried to use the Align2 GUI version to run PORC but I was never able to get that to run. I was probably loading the wrong version of libraries or something.

https://www.ohl.to/about-audio/audio-softwares/align2 Align2 includes a file conversion utility that works with .bin and .wav files.

Align2 is a free audio software designed by JL Ohl to calculate loudspeaker correction for OpenDRC hardware or for convolution softwares.
It was first designed as a GUI for DRC (D. Sbragion) or PORC (M. Green) but evolved with many added functions.

Unfortunately when I run Align2 it has a bug in it so that it only creates filters at 48,000 sps, (the GUI sps selection is ignored) so they are not useful in miniDSP 2x4HD. I have never got a response from its author. Align2 is also dependent on an old version of Octave which is tricky to install. The old version Octave setup screen requires you to scroll down the "choose components" popup window and check the Octave Forge box. If you don't notice that scroll bar on the right side of the popup screen, your screwed and none of the plotting will work.

I have run OpenDRC in DOS and it works at all the sample rates just fine creating FIR filters. It requires long commend lines. I created .bat files to run all the commands.

I have also created room correction filters using REW. I didn't realize it could do that for a long while as the user interface is non-obvious. Follow a tutorial on youTube to see where to click to generate the filter. It is just a line of text, not an obvious button icon.

It would sure be great if the source for Align2 was available so a working GUI for PORC and OpenDRC could be fully functional again. I started trying to make a GUI for openDRC myself using Octave, but it didn't work very well.

If you don't have a miniDSP, equalizerAPO is a great way to run filters on a PC. Filters can be assigned to different inputs and outputs on the PC audio directly. https://sourceforge.net/projects/equalizerapo/
Thanks a lot. I overlooked the fact that miniDSP2x4HD was indeed set (and fixed) to 96KHz. Unfortunately, even when exporting 96 kHz from REW the loaded impulse response doesn't look like it should. I am giving up this route.

Too bad that your code using Octave did not work, great that you tried though.


Hi all,
I commited align2 a very long time ago. But in the last years, I worked mainly on loudspeakers.audio wich includes an optimised calculation of FIR corrections. Maybe I should also add PORC to this online solution. And why not add conversion tools to this web interface.
I'm not so found of updating align2 (it works with python3 with some adjustments) but I have to think about it...
Your website looks very promising. I'll dive further into it.

Cheers,
 
Thanks a lot. I overlooked the fact that miniDSP2x4HD was indeed set (and fixed) to 96KHz. Unfortunately, even when exporting 96 kHz from REW the loaded impulse response doesn't look like it should. I am giving up this route.

Too bad that your code using Octave did not work, great that you tried though.



Your website looks very promising. I'll dive further into it.

Cheers,
I found my octave file that lets you run DRC at 96KHz, or other rates. It isn't a GUI but just a script that prompts for file locations. It builds the DRC .bat file from your answers to a few prompts. You need to supply an impulse response of the system as a .wav files. I measure mine with Arta or REW. It looks for two files, left and right channel. It gets the sample rate from that wave file and computes the compensation. It depends on having align2 installed to work and runs in the latest version of Octave (5.2.0). Of course you can edit it to your taste.

clear
close all

% Load required packages
if (exist('audioread') == 0)
pkg load audio
endif

% If script was run before, load previous menu selections to use as default answers.
if (exist('drcDefaults', "file"))
load drcDefaults
endif

% locate align2 installed folders
if (exist('alignPath') == 0 || exist(alignPath,'dir') != 7)
dialog_name = 'Locate align2 directory'
init_path = 'C:\'
alignPath = uigetdir (init_path, dialog_name)
endif

flt = '*.wav' % file type
dialog_name = 'Locate Left impulse response .wav file'

if exist('fpath') && exist('fNameWavL') && ischar(fpath) && ischar(fNameWavL)
[fNameWavL, fpath, fltidx] = uigetfile (flt, dialog_name, [fpath fNameWavL])
else
[fNameWavL, fpath, fltidx] = uigetfile (flt, dialog_name)
endif

## handle return the number zero for file names!
if (exist('fNameWavL') == 0)
fNameWavL = '';
endif
if (exist('fNameWavR') == 0)
fNameWavR = '';
endif

dialog_name = 'Locate Right impulse response .wav file'
[fNameWavR, fpath, fltidx] = uigetfile (flt, dialog_name, [fpath fNameWavR])

% determine sample rate
[yL, fsL] = audioread([fpath fNameWavL]);

[n,m] = size(yL);

if (m == 1)
figure(1)
t = 1/fsL * [1:length(yL)];
plot(t, yL)
else
printf('multi channel .wav\n', m);
endif

## Select Target Compensation Frequency Response
[fsLstr] = num2str(fsL)
folderStr = [fsLstr(1:2) '.' fsLstr(3) 'KHz\']
fileStr = ['flat-' fsLstr(1:2) '.' fsLstr(3) '.txt']
flt = '*.txt'
dialog_name = 'Select Target Frequency Response file'
[fNameTargetL, fTargetPath, fltidx] = uigetfile (flt, dialog_name, [alignPath 'files\target\' folderStr fileStr ])

## Select DRC parameter file
fileStr = ['erb-' fsLstr(1:2) '.' fsLstr(3) '.drc']
flt = '*.drc'
dialog_name = 'Select Compensation Parameter file'
[fNameDRC, fDRCPath, fltidx] = uigetfile (flt, dialog_name, [alignPath 'files\drc\' folderStr fileStr ])

## Select Microphone Frequency Response File

flt = '*.txt'
dialog_name = 'Select Microphone Frequency Response File'
[fNameMIC, fMICPath, fltidx] = uigetfile (flt, dialog_name, [alignPath 'files\mic\'])

save drcDefaults alignPath fpath fNameWavL fNameWavR

% remove .wav
nC = length(fNameWavL)
fNameL = fNameWavL(1:nC-4);

nC = length(fNameWavR)
fNameR = fNameWavR(1:nC-4);

[filePtr] = fopen('cmd.bat', 'w');
fprintf(filePtr, 'set frequency=%d\n', fsL);
fprintf(filePtr, 'set directory2=%s\n', fpath);
fprintf(filePtr, 'set alignpath=%sfiles\\\n', alignPath);
fprintf(filePtr, 'set prefix=DRC%d\n', fsL/100);
fprintf(filePtr, 'set WEL1=7200\n');
fprintf(filePtr, 'set WEL2=5040\n');
fprintf(filePtr, 'set WEL3=2520\n');
fprintf(filePtr, 'set WEL4=1800\n');
fprintf(filePtr, 'set WEH=1\n');
fprintf(filePtr, 'set BCIW=1\n');
fprintf(filePtr, 'set UPW=48\n');
fprintf(filePtr, 'set taps=65536\n');
fprintf(filePtr, 'set mic=%s%s\n', fMICPath, fNameMIC);
fprintf(filePtr, 'set drc=%s%s\n', fDRCPath, fNameDRC);
fprintf(filePtr, 'set target=%s%s\n', fTargetPath, fNameTargetL );
fprintf(filePtr, 'set ir-L=%s%s\n', fpath, fNameL);
fprintf(filePtr, 'set ir-R=%s%s\n', fpath, fNameR);
fprintf(filePtr, 'set correction=100\n');
fprintf(filePtr, 'set maxgain=6.00\n');
fprintf(filePtr, 'set Fmin=25\n');
fprintf(filePtr, 'set Fmax=18000\n');
fprintf(filePtr, 'set PTType=N\n');

fprintf(filePtr, 'mkdir %%directory2%%convolution\n');
fprintf(filePtr, 'mkdir %%directory2%%opendrc\n');

fprintf(filePtr, 'REM DJO Convert Arta measured Impulse Exported as 16 bit PCM .wav to required .pcm format files.\n');
fprintf(filePtr, '%%alignpath%%sox.exe %%ir-L%%.wav -t raw -e float -b 32 -r %%frequency%% -c 1 %%ir-L%%.pcm\n');
fprintf(filePtr, '%%alignpath%%sox.exe %%ir-R%%.wav -t raw -e float -b 32 -r %%frequency%% -c 1 %%ir-R%%.pcm\n');
fprintf(filePtr, '\n');

fprintf(filePtr, '%%alignpath%%drc.exe --BCInFile=%%ir-L%%.pcm --MCPointsFile=%%mic%% --MCFilterType=M --MCOutFile=%%directory2%%%%prefix%%-irc-L.pcm --MPWindowExponent=%%WEH%% --EPWindowExponent=%%WEH%% --RTWindowExponent=%%WEH%% --MPLowerWindow=%%WEL1%% --MPUpperWindow=%%UPW%% --EPUpperWindow=%%UPW%% --RTUpperWindow=%%UPW%% --EPLowerWindow=%%WEL2%% --RTLowerWindow=%%WEL1%% --ISPELowerWindow=%%WEL3%% --ISPEUpperWindow=%%WEL4%% --PLStartFreq=%%Fmin%% --PLEndFreq=%%Fmax%% --PSOutWindow=%%taps%% --PSOutFile=%%directory2%%convolution\\%%prefix%%-SDLC-L.pcm --PSPointsFile=%%target%% --MSOutWindow=%%taps%% --MSOutFile=%%directory2%%convolution\\%%prefix%%-SDMC-L.pcm --TCOutFile=%%directory2%%%%prefix%%-ircd-L.pcm --PTType=%%PTType%% --PLType=M --PLMaxGain=%%maxgain%% --PSInterpolationType=H %%drc%%\n');
fprintf(filePtr, '%%alignpath%%drc.exe --BCInFile=%%ir-R%%.pcm --MCPointsFile=%%mic%% --MCFilterType=M --MCOutFile=%%directory2%%%%prefix%%-irc-R.pcm --MPWindowExponent=%%WEH%% --EPWindowExponent=%%WEH%% --RTWindowExponent=%%WEH%% --MPLowerWindow=%%WEL1%% --MPUpperWindow=%%UPW%% --EPUpperWindow=%%UPW%% --RTUpperWindow=%%UPW%% --EPLowerWindow=%%WEL2%% --RTLowerWindow=%%WEL1%% --ISPELowerWindow=%%WEL3%% --ISPEUpperWindow=%%WEL4%% --PLStartFreq=%%Fmin%% --PLEndFreq=%%Fmax%% --PSOutWindow=%%taps%% --PSOutFile=%%directory2%%convolution\\%%prefix%%-SDLC-R.pcm --PSPointsFile=%%target%% --MSOutWindow=%%taps%% --MSOutFile=%%directory2%%convolution\\%%prefix%%-SDMC-R.pcm --TCOutFile=%%directory2%%%%prefix%%-ircd-R.pcm --PTType=%%PTType%% --PLType=M --PLMaxGain=%%maxgain%% --PSInterpolationType=H %%drc%%\n');

fprintf(filePtr, '%%alignpath%%sox.exe -t raw -e float -b 32 -r %%frequency%% -c 1 %%ir-L%%.pcm -t wav -b 16 -c 1 -s %%directory2%%%%prefix%%-ir-L.wav\n');
fprintf(filePtr, '%%alignpath%%sox.exe -t raw -e float -b 32 -r %%frequency%% -c 1 %%ir-R%%.pcm -t wav -b 16 -c 1 -s %%directory2%%%%prefix%%-ir-R.wav\n');
fprintf(filePtr, '%%alignpath%%sox.exe -t raw -e float -b 32 -r %%frequency%% -c 1 %%directory2%%%%prefix%%-irc-L.pcm -t wav -b 16 -c 1 -s %%directory2%%%%prefix%%-irc-L1.wav\n');
fprintf(filePtr, '%%alignpath%%sox.exe -t raw -e float -b 32 -r %%frequency%% -c 1 %%directory2%%%%prefix%%-irc-R.pcm -t wav -b 16 -c 1 -s %%directory2%%%%prefix%%-irc-R1.wav\n');
fprintf(filePtr, '%%alignpath%%sox.exe -t raw -e float -b 32 -r %%frequency%% -c 1 %%directory2%%%%prefix%%-ircd-L.pcm -t wav -b 16 -c 1 -s %%directory2%%%%prefix%%-ircd-L1.wav\n');
fprintf(filePtr, '%%alignpath%%sox.exe -t raw -e float -b 32 -r %%frequency%% -c 1 %%directory2%%%%prefix%%-ircd-R.pcm -t wav -b 16 -c 1 -s %%directory2%%%%prefix%%-ircd-R1.wav\n');
fprintf(filePtr, '%%alignpath%%sox.exe -t raw -e float -b 32 -r %%frequency%% -c 1 %%directory2%%convolution\\%%prefix%%-SDLC-L.pcm -t wav -b 16 -c 1 -s %%directory2%%convolution\\%%prefix%%-SDLC--L1.wav\n');
fprintf(filePtr, '%%alignpath%%sox.exe -t raw -e float -b 32 -r %%frequency%% -c 1 %%directory2%%convolution\\%%prefix%%-SDLC-R.pcm -t wav -b 16 -c 1 -s %%directory2%%convolution\\%%prefix%%-SDLC--R1.wav\n');
fprintf(filePtr, '%%alignpath%%sox.exe -t raw -e float -b 32 -r %%frequency%% -c 1 %%directory2%%convolution\\%%prefix%%-SDMC-L.pcm -t wav -b 16 -c 1 -s %%directory2%%convolution\\%%prefix%%-SDMC--L1.wav\n');
fprintf(filePtr, '%%alignpath%%sox.exe -t raw -e float -b 32 -r %%frequency%% -c 1 %%directory2%%convolution\\%%prefix%%-SDMC-R.pcm -t wav -b 16 -c 1 -s %%directory2%%convolution\\%%prefix%%-SDMC--R1.wav\n');
fprintf(filePtr, '\n');
fprintf(filePtr, 'ping -n 2 127.0.0.1 >nul\n');
fprintf(filePtr, 'REM delay\n');
fprintf(filePtr, '\n');
fprintf(filePtr, '%%alignpath%%sox.exe --norm %%directory2%%%%prefix%%-irc-L1.wav %%directory2%%%%prefix%%-irc-L.wav\n');
fprintf(filePtr, '%%alignpath%%sox.exe --norm %%directory2%%%%prefix%%-irc-R1.wav %%directory2%%%%prefix%%-irc-R.wav\n');
fprintf(filePtr, '%%alignpath%%sox.exe --norm %%directory2%%%%prefix%%-ircd-L1.wav %%directory2%%%%prefix%%-ircd-L.wav\n');
fprintf(filePtr, '%%alignpath%%sox.exe --norm %%directory2%%%%prefix%%-ircd-R1.wav %%directory2%%%%prefix%%-ircd-R.wav\n');
fprintf(filePtr, '%%alignpath%%sox.exe --norm %%directory2%%convolution\\%%prefix%%-SDLC--L1.wav %%directory2%%convolution\\%%prefix%%-SDLC-L.wav\n');
fprintf(filePtr, '%%alignpath%%sox.exe --norm %%directory2%%convolution\\%%prefix%%-SDLC--R1.wav %%directory2%%convolution\\%%prefix%%-SDLC-R.wav\n');
fprintf(filePtr, '%%alignpath%%sox.exe --norm %%directory2%%convolution\\%%prefix%%-SDMC--L1.wav %%directory2%%convolution\\%%prefix%%-SDMC-L.wav\n');
fprintf(filePtr, '%%alignpath%%sox.exe --norm %%directory2%%convolution\\%%prefix%%-SDMC--R1.wav %%directory2%%convolution\\%%prefix%%-SDMC-R.wav\n');
fprintf(filePtr, '\n');
fprintf(filePtr, '%%alignpath%%sox.exe -M -v 1 %%directory2%%convolution\\%%prefix%%-SDMC-L.wav %%directory2%%convolution\\%%prefix%%-SDMC-R.wav %%directory2%%convolution\\%%prefix%%-SDMC-STEREO.wav\n');
fprintf(filePtr, '\n');
fprintf(filePtr, '%%alignpath%%sox.exe %%directory2%%convolution\\%%prefix%%-SDLC-L.wav %%directory2%%convolution\\%%prefix%%-SDLC-L1.wav trim 1500s 6144s\n');
fprintf(filePtr, '%%alignpath%%sox.exe %%directory2%%convolution\\%%prefix%%-SDLC-R.wav %%directory2%%convolution\\%%prefix%%-SDLC-R1.wav trim 1500s 6144s\n');
fprintf(filePtr, '%%alignpath%%sox.exe %%directory2%%convolution\\%%prefix%%-SDMC-L.wav %%directory2%%convolution\\%%prefix%%-SDMC-L1.wav trim 1000s 6144s\n');
fprintf(filePtr, '%%alignpath%%sox.exe %%directory2%%convolution\\%%prefix%%-SDMC-R.wav %%directory2%%convolution\\%%prefix%%-SDMC-R1.wav trim 1000s 6144s\n');
fprintf(filePtr, '\n');
fprintf(filePtr, '%%alignpath%%sox.exe -M -v 1 %%directory2%%convolution\\%%prefix%%-SDMC-L1.wav %%directory2%%convolution\\%%prefix%%-SDMC-R1.wav %%directory2%%convolution\\%%prefix%%-SDMC-STEREO1.wav\n');
fprintf(filePtr, '\n');
fprintf(filePtr, '%%alignpath%%sox.exe -t wav %%directory2%%convolution\\%%prefix%%-SDLC-L1.wav -t f32 %%directory2%%opendrc\\%%prefix%%-SDLO-L.bin\n');
fprintf(filePtr, '%%alignpath%%sox.exe -t wav %%directory2%%convolution\\%%prefix%%-SDLC-R1.wav -t f32 %%directory2%%opendrc\\%%prefix%%-SDLO-R.bin\n');
fprintf(filePtr, '%%alignpath%%sox.exe -t wav %%directory2%%convolution\\%%prefix%%-SDMC-L1.wav -t f32 %%directory2%%opendrc\\%%prefix%%-SDMO-L.bin\n');
fprintf(filePtr, '%%alignpath%%sox.exe -t wav %%directory2%%convolution\\%%prefix%%-SDMC-R1.wav -t f32 %%directory2%%opendrc\\%%prefix%%-SDMO-R.bin\n');
fprintf(filePtr, '\n');

fprintf(filePtr, 'del %%directory2%%convolution\\%%prefix%%-SDLC--L1.wav\n');
fprintf(filePtr, 'del %%directory2%%convolution\\%%prefix%%-SDLC--R1.wav\n');
fprintf(filePtr, 'del %%directory2%%convolution\\%%prefix%%-SDMC--L1.wav\n');
fprintf(filePtr, 'del %%directory2%%convolution\\%%prefix%%-SDMC--R1.wav\n');
fprintf(filePtr, 'del %%directory2%%%%prefix%%-irc-L1.wav\n');
fprintf(filePtr, 'del %%directory2%%%%prefix%%-irc-R1.wav\n');
fprintf(filePtr, 'del %%directory2%%%%prefix%%-ircd-L1.wav\n');
fprintf(filePtr, 'del %%directory2%%%%prefix%%-ircd-R1.wav\n');
fprintf(filePtr, 'del %%directory2%%*.pcm\n');
fprintf(filePtr, 'del %%directory2%%convolution\\*.pcm\n');

fclose(filePtr);

[status, output] = system('cmd.bat');

% [status, output] = system('ls', '-l');
 
I found my octave file that lets you run DRC at 96KHz, or other rates. It isn't a GUI but just a script that prompts for file locations. It builds the DRC .bat file from your answers to a few prompts. You need to supply an impulse response of the system as a .wav files. I measure mine with Arta or REW. It looks for two files, left and right channel. It gets the sample rate from that wave file and computes the compensation. It depends on having align2 installed to work and runs in the latest version of Octave (5.2.0). Of course you can edit it to your taste.

clear
close all

% Load required packages
if (exist('audioread') == 0)
pkg load audio
endif

% If script was run before, load previous menu selections to use as default answers.
if (exist('drcDefaults', "file"))
load drcDefaults
endif

% locate align2 installed folders
if (exist('alignPath') == 0 || exist(alignPath,'dir') != 7)
dialog_name = 'Locate align2 directory'
init_path = 'C:\'
alignPath = uigetdir (init_path, dialog_name)
endif

flt = '*.wav' % file type
dialog_name = 'Locate Left impulse response .wav file'

if exist('fpath') && exist('fNameWavL') && ischar(fpath) && ischar(fNameWavL)
[fNameWavL, fpath, fltidx] = uigetfile (flt, dialog_name, [fpath fNameWavL])
else
[fNameWavL, fpath, fltidx] = uigetfile (flt, dialog_name)
endif

## handle return the number zero for file names!
if (exist('fNameWavL') == 0)
fNameWavL = '';
endif
if (exist('fNameWavR') == 0)
fNameWavR = '';
endif

dialog_name = 'Locate Right impulse response .wav file'
[fNameWavR, fpath, fltidx] = uigetfile (flt, dialog_name, [fpath fNameWavR])

% determine sample rate
[yL, fsL] = audioread([fpath fNameWavL]);

[n,m] = size(yL);

if (m == 1)
figure(1)
t = 1/fsL * [1:length(yL)];
plot(t, yL)
else
printf('multi channel .wav\n', m);
endif

## Select Target Compensation Frequency Response
[fsLstr] = num2str(fsL)
folderStr = [fsLstr(1:2) '.' fsLstr(3) 'KHz\']
fileStr = ['flat-' fsLstr(1:2) '.' fsLstr(3) '.txt']
flt = '*.txt'
dialog_name = 'Select Target Frequency Response file'
[fNameTargetL, fTargetPath, fltidx] = uigetfile (flt, dialog_name, [alignPath 'files\target\' folderStr fileStr ])

## Select DRC parameter file
fileStr = ['erb-' fsLstr(1:2) '.' fsLstr(3) '.drc']
flt = '*.drc'
dialog_name = 'Select Compensation Parameter file'
[fNameDRC, fDRCPath, fltidx] = uigetfile (flt, dialog_name, [alignPath 'files\drc\' folderStr fileStr ])

## Select Microphone Frequency Response File

flt = '*.txt'
dialog_name = 'Select Microphone Frequency Response File'
[fNameMIC, fMICPath, fltidx] = uigetfile (flt, dialog_name, [alignPath 'files\mic\'])

save drcDefaults alignPath fpath fNameWavL fNameWavR

% remove .wav
nC = length(fNameWavL)
fNameL = fNameWavL(1:nC-4);

nC = length(fNameWavR)
fNameR = fNameWavR(1:nC-4);

[filePtr] = fopen('cmd.bat', 'w');
fprintf(filePtr, 'set frequency=%d\n', fsL);
fprintf(filePtr, 'set directory2=%s\n', fpath);
fprintf(filePtr, 'set alignpath=%sfiles\\\n', alignPath);
fprintf(filePtr, 'set prefix=DRC%d\n', fsL/100);
fprintf(filePtr, 'set WEL1=7200\n');
fprintf(filePtr, 'set WEL2=5040\n');
fprintf(filePtr, 'set WEL3=2520\n');
fprintf(filePtr, 'set WEL4=1800\n');
fprintf(filePtr, 'set WEH=1\n');
fprintf(filePtr, 'set BCIW=1\n');
fprintf(filePtr, 'set UPW=48\n');
fprintf(filePtr, 'set taps=65536\n');
fprintf(filePtr, 'set mic=%s%s\n', fMICPath, fNameMIC);
fprintf(filePtr, 'set drc=%s%s\n', fDRCPath, fNameDRC);
fprintf(filePtr, 'set target=%s%s\n', fTargetPath, fNameTargetL );
fprintf(filePtr, 'set ir-L=%s%s\n', fpath, fNameL);
fprintf(filePtr, 'set ir-R=%s%s\n', fpath, fNameR);
fprintf(filePtr, 'set correction=100\n');
fprintf(filePtr, 'set maxgain=6.00\n');
fprintf(filePtr, 'set Fmin=25\n');
fprintf(filePtr, 'set Fmax=18000\n');
fprintf(filePtr, 'set PTType=N\n');

fprintf(filePtr, 'mkdir %%directory2%%convolution\n');
fprintf(filePtr, 'mkdir %%directory2%%opendrc\n');

fprintf(filePtr, 'REM DJO Convert Arta measured Impulse Exported as 16 bit PCM .wav to required .pcm format files.\n');
fprintf(filePtr, '%%alignpath%%sox.exe %%ir-L%%.wav -t raw -e float -b 32 -r %%frequency%% -c 1 %%ir-L%%.pcm\n');
fprintf(filePtr, '%%alignpath%%sox.exe %%ir-R%%.wav -t raw -e float -b 32 -r %%frequency%% -c 1 %%ir-R%%.pcm\n');
fprintf(filePtr, '\n');

fprintf(filePtr, '%%alignpath%%drc.exe --BCInFile=%%ir-L%%.pcm --MCPointsFile=%%mic%% --MCFilterType=M --MCOutFile=%%directory2%%%%prefix%%-irc-L.pcm --MPWindowExponent=%%WEH%% --EPWindowExponent=%%WEH%% --RTWindowExponent=%%WEH%% --MPLowerWindow=%%WEL1%% --MPUpperWindow=%%UPW%% --EPUpperWindow=%%UPW%% --RTUpperWindow=%%UPW%% --EPLowerWindow=%%WEL2%% --RTLowerWindow=%%WEL1%% --ISPELowerWindow=%%WEL3%% --ISPEUpperWindow=%%WEL4%% --PLStartFreq=%%Fmin%% --PLEndFreq=%%Fmax%% --PSOutWindow=%%taps%% --PSOutFile=%%directory2%%convolution\\%%prefix%%-SDLC-L.pcm --PSPointsFile=%%target%% --MSOutWindow=%%taps%% --MSOutFile=%%directory2%%convolution\\%%prefix%%-SDMC-L.pcm --TCOutFile=%%directory2%%%%prefix%%-ircd-L.pcm --PTType=%%PTType%% --PLType=M --PLMaxGain=%%maxgain%% --PSInterpolationType=H %%drc%%\n');
fprintf(filePtr, '%%alignpath%%drc.exe --BCInFile=%%ir-R%%.pcm --MCPointsFile=%%mic%% --MCFilterType=M --MCOutFile=%%directory2%%%%prefix%%-irc-R.pcm --MPWindowExponent=%%WEH%% --EPWindowExponent=%%WEH%% --RTWindowExponent=%%WEH%% --MPLowerWindow=%%WEL1%% --MPUpperWindow=%%UPW%% --EPUpperWindow=%%UPW%% --RTUpperWindow=%%UPW%% --EPLowerWindow=%%WEL2%% --RTLowerWindow=%%WEL1%% --ISPELowerWindow=%%WEL3%% --ISPEUpperWindow=%%WEL4%% --PLStartFreq=%%Fmin%% --PLEndFreq=%%Fmax%% --PSOutWindow=%%taps%% --PSOutFile=%%directory2%%convolution\\%%prefix%%-SDLC-R.pcm --PSPointsFile=%%target%% --MSOutWindow=%%taps%% --MSOutFile=%%directory2%%convolution\\%%prefix%%-SDMC-R.pcm --TCOutFile=%%directory2%%%%prefix%%-ircd-R.pcm --PTType=%%PTType%% --PLType=M --PLMaxGain=%%maxgain%% --PSInterpolationType=H %%drc%%\n');

fprintf(filePtr, '%%alignpath%%sox.exe -t raw -e float -b 32 -r %%frequency%% -c 1 %%ir-L%%.pcm -t wav -b 16 -c 1 -s %%directory2%%%%prefix%%-ir-L.wav\n');
fprintf(filePtr, '%%alignpath%%sox.exe -t raw -e float -b 32 -r %%frequency%% -c 1 %%ir-R%%.pcm -t wav -b 16 -c 1 -s %%directory2%%%%prefix%%-ir-R.wav\n');
fprintf(filePtr, '%%alignpath%%sox.exe -t raw -e float -b 32 -r %%frequency%% -c 1 %%directory2%%%%prefix%%-irc-L.pcm -t wav -b 16 -c 1 -s %%directory2%%%%prefix%%-irc-L1.wav\n');
fprintf(filePtr, '%%alignpath%%sox.exe -t raw -e float -b 32 -r %%frequency%% -c 1 %%directory2%%%%prefix%%-irc-R.pcm -t wav -b 16 -c 1 -s %%directory2%%%%prefix%%-irc-R1.wav\n');
fprintf(filePtr, '%%alignpath%%sox.exe -t raw -e float -b 32 -r %%frequency%% -c 1 %%directory2%%%%prefix%%-ircd-L.pcm -t wav -b 16 -c 1 -s %%directory2%%%%prefix%%-ircd-L1.wav\n');
fprintf(filePtr, '%%alignpath%%sox.exe -t raw -e float -b 32 -r %%frequency%% -c 1 %%directory2%%%%prefix%%-ircd-R.pcm -t wav -b 16 -c 1 -s %%directory2%%%%prefix%%-ircd-R1.wav\n');
fprintf(filePtr, '%%alignpath%%sox.exe -t raw -e float -b 32 -r %%frequency%% -c 1 %%directory2%%convolution\\%%prefix%%-SDLC-L.pcm -t wav -b 16 -c 1 -s %%directory2%%convolution\\%%prefix%%-SDLC--L1.wav\n');
fprintf(filePtr, '%%alignpath%%sox.exe -t raw -e float -b 32 -r %%frequency%% -c 1 %%directory2%%convolution\\%%prefix%%-SDLC-R.pcm -t wav -b 16 -c 1 -s %%directory2%%convolution\\%%prefix%%-SDLC--R1.wav\n');
fprintf(filePtr, '%%alignpath%%sox.exe -t raw -e float -b 32 -r %%frequency%% -c 1 %%directory2%%convolution\\%%prefix%%-SDMC-L.pcm -t wav -b 16 -c 1 -s %%directory2%%convolution\\%%prefix%%-SDMC--L1.wav\n');
fprintf(filePtr, '%%alignpath%%sox.exe -t raw -e float -b 32 -r %%frequency%% -c 1 %%directory2%%convolution\\%%prefix%%-SDMC-R.pcm -t wav -b 16 -c 1 -s %%directory2%%convolution\\%%prefix%%-SDMC--R1.wav\n');
fprintf(filePtr, '\n');
fprintf(filePtr, 'ping -n 2 127.0.0.1 >nul\n');
fprintf(filePtr, 'REM delay\n');
fprintf(filePtr, '\n');
fprintf(filePtr, '%%alignpath%%sox.exe --norm %%directory2%%%%prefix%%-irc-L1.wav %%directory2%%%%prefix%%-irc-L.wav\n');
fprintf(filePtr, '%%alignpath%%sox.exe --norm %%directory2%%%%prefix%%-irc-R1.wav %%directory2%%%%prefix%%-irc-R.wav\n');
fprintf(filePtr, '%%alignpath%%sox.exe --norm %%directory2%%%%prefix%%-ircd-L1.wav %%directory2%%%%prefix%%-ircd-L.wav\n');
fprintf(filePtr, '%%alignpath%%sox.exe --norm %%directory2%%%%prefix%%-ircd-R1.wav %%directory2%%%%prefix%%-ircd-R.wav\n');
fprintf(filePtr, '%%alignpath%%sox.exe --norm %%directory2%%convolution\\%%prefix%%-SDLC--L1.wav %%directory2%%convolution\\%%prefix%%-SDLC-L.wav\n');
fprintf(filePtr, '%%alignpath%%sox.exe --norm %%directory2%%convolution\\%%prefix%%-SDLC--R1.wav %%directory2%%convolution\\%%prefix%%-SDLC-R.wav\n');
fprintf(filePtr, '%%alignpath%%sox.exe --norm %%directory2%%convolution\\%%prefix%%-SDMC--L1.wav %%directory2%%convolution\\%%prefix%%-SDMC-L.wav\n');
fprintf(filePtr, '%%alignpath%%sox.exe --norm %%directory2%%convolution\\%%prefix%%-SDMC--R1.wav %%directory2%%convolution\\%%prefix%%-SDMC-R.wav\n');
fprintf(filePtr, '\n');
fprintf(filePtr, '%%alignpath%%sox.exe -M -v 1 %%directory2%%convolution\\%%prefix%%-SDMC-L.wav %%directory2%%convolution\\%%prefix%%-SDMC-R.wav %%directory2%%convolution\\%%prefix%%-SDMC-STEREO.wav\n');
fprintf(filePtr, '\n');
fprintf(filePtr, '%%alignpath%%sox.exe %%directory2%%convolution\\%%prefix%%-SDLC-L.wav %%directory2%%convolution\\%%prefix%%-SDLC-L1.wav trim 1500s 6144s\n');
fprintf(filePtr, '%%alignpath%%sox.exe %%directory2%%convolution\\%%prefix%%-SDLC-R.wav %%directory2%%convolution\\%%prefix%%-SDLC-R1.wav trim 1500s 6144s\n');
fprintf(filePtr, '%%alignpath%%sox.exe %%directory2%%convolution\\%%prefix%%-SDMC-L.wav %%directory2%%convolution\\%%prefix%%-SDMC-L1.wav trim 1000s 6144s\n');
fprintf(filePtr, '%%alignpath%%sox.exe %%directory2%%convolution\\%%prefix%%-SDMC-R.wav %%directory2%%convolution\\%%prefix%%-SDMC-R1.wav trim 1000s 6144s\n');
fprintf(filePtr, '\n');
fprintf(filePtr, '%%alignpath%%sox.exe -M -v 1 %%directory2%%convolution\\%%prefix%%-SDMC-L1.wav %%directory2%%convolution\\%%prefix%%-SDMC-R1.wav %%directory2%%convolution\\%%prefix%%-SDMC-STEREO1.wav\n');
fprintf(filePtr, '\n');
fprintf(filePtr, '%%alignpath%%sox.exe -t wav %%directory2%%convolution\\%%prefix%%-SDLC-L1.wav -t f32 %%directory2%%opendrc\\%%prefix%%-SDLO-L.bin\n');
fprintf(filePtr, '%%alignpath%%sox.exe -t wav %%directory2%%convolution\\%%prefix%%-SDLC-R1.wav -t f32 %%directory2%%opendrc\\%%prefix%%-SDLO-R.bin\n');
fprintf(filePtr, '%%alignpath%%sox.exe -t wav %%directory2%%convolution\\%%prefix%%-SDMC-L1.wav -t f32 %%directory2%%opendrc\\%%prefix%%-SDMO-L.bin\n');
fprintf(filePtr, '%%alignpath%%sox.exe -t wav %%directory2%%convolution\\%%prefix%%-SDMC-R1.wav -t f32 %%directory2%%opendrc\\%%prefix%%-SDMO-R.bin\n');
fprintf(filePtr, '\n');

fprintf(filePtr, 'del %%directory2%%convolution\\%%prefix%%-SDLC--L1.wav\n');
fprintf(filePtr, 'del %%directory2%%convolution\\%%prefix%%-SDLC--R1.wav\n');
fprintf(filePtr, 'del %%directory2%%convolution\\%%prefix%%-SDMC--L1.wav\n');
fprintf(filePtr, 'del %%directory2%%convolution\\%%prefix%%-SDMC--R1.wav\n');
fprintf(filePtr, 'del %%directory2%%%%prefix%%-irc-L1.wav\n');
fprintf(filePtr, 'del %%directory2%%%%prefix%%-irc-R1.wav\n');
fprintf(filePtr, 'del %%directory2%%%%prefix%%-ircd-L1.wav\n');
fprintf(filePtr, 'del %%directory2%%%%prefix%%-ircd-R1.wav\n');
fprintf(filePtr, 'del %%directory2%%*.pcm\n');
fprintf(filePtr, 'del %%directory2%%convolution\\*.pcm\n');

fclose(filePtr);

[status, output] = system('cmd.bat');

% [status, output] = system('ls', '-l');
Woah! That's great. Thanks a lot.
I will look into it.
Cheers,
 
Is there anyone who can use Align2?
I knew and installed Align2 because I couldn't do target curve and frequency limit while using DRC designer.
1.png


However, I kept getting the notification that file not found, and I couldn't get the convolution file I wanted.
(octave has been installed, and setup tap chooes exe locate)
I like its UI and want to try it, but it's sad that it doesn't work.
Is there anyone who can help me?

I just want to use up to 300 Hz as a flat target.
 

Attachments

  • Left n Right wav.zip
    845.9 KB · Views: 36
Did you install the required old version of octave all all the packages as I mentioned in post #113 of this thread? I had trouble as selecting the correct package required scrolling down in a pop up window during the install to find the required option.
I've tried reinstalling octave again and again, but when I press Process DRC, only the file not found message appears.
There is a folder customized as Dummy in the Message folder, and there are four irc L, R/ir L, R wav files, but when I checked this in rew, it seems to be the same as my wav file that has not been corrected.
There is nothing in the convolution folder.
 
I don't know. If you installed the version 3.2.4 and all the packages and pointed to it in the Locate octave.exe window as below, it should work.
install.jpg

I used my phone to video record the execution so I could catch the error messages and was able to find my error that way. The messages are only displayed for a short time and the window closes. You can scroll through the video to see what file was missing.

Here you go. I went ahead and ran your files.
See the attached .zip file for the filters.

graph.jpg
gui.jpg
 

Attachments

  • dingdongOut.zip
    458.2 KB · Views: 40
Did you install the required old version of octave all all the packages as I mentioned in post #113 of this thread? I had trouble as selecting the correct package required scrolling down in a pop up window during the install to find the required option.

Video Record

33.png


44.png


55.png


66.png





I left a video link at the top. And I may have missed something because it went by so fast, but I captured it by repeating pause/play.
Do you know what my problem is?
I don't know much about computer programming. I'm sorry.
 
I don't know. If you installed the version 3.2.4 and all the packages and pointed to it in the Locate octave.exe window as below, it should work.
View attachment 1136553
I used my phone to video record the execution so I could catch the error messages and was able to find my error that way. The messages are only displayed for a short time and the window closes. You can scroll through the video to see what file was missing.

Here you go. I went ahead and ran your files.
See the attached .zip file for the filters.

View attachment 1136551 View attachment 1136552
Oh! I tried to create a folder in the messagement folder, put the wav file, and run it just in case I saw your folder path. It's working!
Thanks!
However, even if the fmax is reduced to 300, it applies to the entire frequency. What's wrong with this?
 
Hi all,
sorry but I've not worked on Align2 for a long time as I allready said last year.
But the website loudspeakers.audio does same things but without any software to install (and it's free for now).
The correction has also been improved and you'll get a lot of new graphs.
At the moment, I have not added PORC but I'm thinking about it.
Please tell me why you would prefer to use Align2 instead of the website, so I can improve the website or work back on Align2.
 
Last edited:
Hi all,
sorry but I've not worked on Align2 for a long time as I allready said last year.
But the website loudspeakers.audio does same things but without any software to install (and it's free for now).
The correction has also been improved and you'll get a lot of new graphs.
At the moment, I have not added PORC but I'm thinking about it.
Please tell me why you would prefer to use Align2 instead of the website, so I can improve the website or work back on Align2.
Hi Jean Luc. Great to see you are active on here. I also tried the website a while back. It took a long time and the file I got back didn't work well. I like to correct individual drivers using gated measurements sometimes rather than whole speaker in a room correction, so align2 could let me do that sort of thing if it would process at 96 ksps. I have had success using REW lately, but it doesn't generate an FIR filter so it won't correct reflections or other non minimum phase induced errors correctly. It would be great if you updated align2 and followed the free features demo mode, pay for all features model like the Arta software suite does. If you don't want to work on it, it would be great if the source code was made available on github so others could move it forward.
 
Oh! I tried to create a folder in the messagement folder, put the wav file, and run it just in case I saw your folder path. It's working!
Thanks!
However, even if the fmax is reduced to 300, it applies to the entire frequency. What's wrong with this?
Hi, Great to see that you made progress. You can open the .bat command file that is generated by align2. Look through that to see if the fmax was set to 300. You can edit that file and run it directly and get results. That is what I was doing with the simple octave script I posted here. The script writes a .bat file that runs the DRC program elements one at a time. You would have to look at the DRC documentation to see what to do.
 
Hi, it seems that the main problem is related to sox when folder/files are with spaces, special characters, aso...
I know how to manage this, just give me a few days to check. I'll upload a beta version of align2 somewhere.
But anyway, I won't add all features that I do on loudspeakers.audio : I use MMM measurement instead of a sweep and the correction file is better adapted to one's setup and room. At the moment, it is easier to use but less configurable for DIYers.

By the way, I did a lot of work on the website to deal with all possible uploads. When I started, you had really to comply to all exact formats. Now, it is much more flexible and calculation is quicker, just a few minutes to get all graphs.
 
Last edited:
  • Like
Reactions: 1 users