Digital Room Correction Project

Status
This old topic is closed. If you want to reopen this topic, contact a moderator using the "Report Post" button.
Hi all.....Whew, that's a long post!

And a very informative and helpful one! Thanks for posting it, its clarified a number of things for me.

So, I guess I’m likely to need to fix-up the latency difference between the video and audio. Any recommendations on a value-for-money unit that can delay video?

I tried to apply as strong as possible correction to the filter of my system, until pre-echo is perceivable. A quick way to do this is to find how sensitive is your system vs pre-echo. Then make simulations, find the most possible strong correction. And verify it.

That seems sensible.

Check DRC document, you can find normalization factor... Balance, means, equal loudness of left & right channel. It's judged by ears. You know human ears are not frequency linear... One of the correction of DRC is magnitude frequency response. That is, DRC does the inverse of your system response.

Your post led me to re-read the DRC documentation. Yes, it does turn out that manual rebalancing is required once the filters have been created (as a final step). So the DRC program will make the frequency response of each speaker almost identical, but the relative signal magnitude between speakers may be different.
 
Originally posted by boconnor
Any recommendations on a value-for-money unit that can delay video?

I've never seen any, though, it would require a lot of memory so I think embedded systems would be expensive. If you're using a PC for your source though, you're in luck - I believe that most software video players allow you to adjustably delay the video specifically for lip-sync purposes.
 
I've never seen any, though, it would require a lot of memory so I think embedded systems would be expensive. If you're using a PC for your source though, you're in luck - I believe that most software video players allow you to adjustably delay the video specifically for lip-sync purposes.

I'm just using a DVD player for playback so this might get tricky about fixing the latency issue.
 
Dealing with audio latency

I’ve been thinking about the options to deal with the audio latency issues highlighted in previous posts on this thread. I see three options at present:

  1. Only FIR filter the squeezebox outputs, leaving the home cinema audio channels to go through my current 1/3 octave eq setup, which has no latency. This has the advantage of retaining the investment in existing DVD players etc and dealing with the latency by effectively bypassing it. The disadvantage is the need to have remote controlled switches to route the output signals from either the BruteFIR box in the case of music, or from the home cinema decoder. Also, it means I would have inferior sounding audio when playing music videos - although I’m not sure if that’s so much of an issue given the quality of audio mixing on many DVDs.
  2. FIR filter all audio channels, and purchase a video delay unit to match the audio latency through the filters. Major disadvantage of this is the time to source a suitable video delay unit and the subsequent cost to purchase. New units on eBay by Rane, which offer variable delays and delay of PAL signals, look to be about US $800 – not cheap. There doesn’t seem to be much of a second hand market for variable delay units. I have seen some fairly cheap second hand units that do fixed delay (eg 2 frames of video) but I would have to know exactly how much delay the BruteFIR program is producing and then do matching compensation to get the audio and video lined up – doesn’t sound easy.
  3. Change the hardware architecture – replace the existing PVR and DVD players with a properly tailored PC with high def tuners and video cards, so that video signals are captured within the PC and then can be delayed. Major advantage of this is that I can then FIR all audio outputs (music and home cinema). Disadvantage is cost and time as this would require replacement of the existing video systems.
Decisions, decisions.
 
[*]Change the hardware architecture – replace the existing PVR and DVD players with a properly tailored PC with high def tuners and video cards, so that video signals are captured within the PC and then can be delayed. Major advantage of this is that I can then FIR all audio outputs (music and home cinema). Disadvantage is cost and time as this would require replacement of the existing video systems.
[/LIST]
boconnor,
Capturing video signal on a pc means that you will be taking it from analog to digital and then back again? That might mean exchanging one devil with another, Audio quality will be exchanged for video quality. It would be good if you could take Video in digital domain into a PC, delay it and send it back out in digital domain.

Decisions, decisions.
Indeed.
 
Decision on audio latency

I have thought about the best way forward. Because I like to fully utilise existing equipment, and get value for money for my expenditure, I have decided to keep my existing video gear, and not to buy a video delay unit. So the current plan is:

FIR filter all audio (both music and from the home cinema). Check sync between video image and audio. If there is a sync problem, then change the BruteFIR configuration file to not filter the home cinema audio except for the sub-woofer channel, which will always be filtered. On balance this seems reasonable given the quality of audio on DVDs.
Any delay in the sub woofer channel is fine because I need to delay the sub woofer channel in any case, since it is too close to the listening position relative to the front speakers. I also need to deal with the sub 100Hz room modes.

The trick here is to get the overall delay right, which combines the inherent delay of the filter with the delay required because of physical distance between speakers.

So, if anyone has an easy method to determine the FIR filter delay through BruteFIR (I need a method that provides the actual millisecond number), please jump in.
 
Hmmm, there's the `manual' method:
- I believe that both BruteFIR's block latency and the sound card's latency should be choosable/reported to you.
- If you have a filter file and some means to graph it (Excel, et all might work? MATLAB definitely does), then you can eyeball it for the first large peak.

Just add all those up and I think you should get your answer. If it's in samples then of course just divide by sample rate to get a value in seconds.

If you don't have the means to look at the filter file yourself then I'll be happy to do it - just send it over to me.
 
Last edited:
Hmmm, there's the `manual' method: - I believe that both BruteFIR's block latency and the sound card's latency should be choosable/reported to you. -

Eh… a good reminder of the importance of reading the manual.:)

So I looked more closely at the BruteFIR documentation, which of course turns out to be a more useful thing to do than the cursory glance I gave some sections of the documentation when I first read them!

It looks like changing a parameter called the ‘partition size’ can vary the latency (delay), although the latency does also depend on hardware performance of RAM and other factors. It also turns out that BruteFIR can produce benchmark statistics. A configuration file with a specified filter is provided where you can check actual latency results against a table in the documentation.

Ominously, there is this in the documentation: “If you want to run BruteFIR to achieve high throughput, you should expect to have a delay of at least 100 ms …"

Like most things I guess I will only really know by applying my own filters with my own hardware. Although for my soundcard there appears to be a restriction on the partition size that can be specified (RME Digi9632 - max 8 partitions? – need to check the manual on that ;)). So before actually doing some measurements I suspect the latency will be above the threshold that has been mentioned earlier that causes problems in syncing audio with the video images.

Still, I’ve got some things to get right before we get to the point of doing actual measurements with filters. I’m having all sorts of problems getting Linux installed on the mini PC box I purchased. But that, as they say, is another story ...
 
Originally posted by boconnor
It looks like changing a parameter called the ‘partition size’ can vary the latency (delay)

That's right. BruteFIR uses a specific algorithm for convolution called `partitioned convolution'. In conventional frequency-domain convolution, a block of samples has to be collected and then processed all at once; this is where the latency comes from, as you have to wait to collect the whole block, which is dictated by the length of the filter kernel. For a long filter, this clearly adds a lot of latency, even if you can compute the result instantly.
Partitioned convolution allows you to get the same result with less latency by partitioning up the large block, processing the sub-blocks individually and adding the results up in a specific way. Using smaller partitions produces less latency, but requires more CPU power.

I think by `high throughput', the author is likely to be talking about very very long filters (say, 32k taps). With a filter that long you'd be limited by most hardware in terms of how many partitions could be handled. 32k taps far longer than you'd need for a conventional audio filter, but I don't know about room correction. It's less than a second's worth of impulse response, so longer still might be needed.

In the end, I think you're right - you'll just need to try it on your computer with your filters, and see what happens. I don't see why there'd be a limit on the number of partitions with your soundcard - I thought the two were entirely independent. But yeah, do check the manual :)
 
Update: Linux software, replaced PC hardware and other things

Sound card and associated hardware

I purchased a superseded RME9636 sound card on EBay for use in the system. It has two SPDIF connectors and four ADAT optical connectors providing 16 input channels and 16 output channels (simultaneous) at 48kHz sampling frequency. But no on-board convertors.

I also purchased a Behringer ADA8000, providing 8 DACs and 8 ADCs. The Behringer is set as the clock master, with a 48kHz sampling frequency. It produces a 24 bit data stream for each channel.

PC hardware

I initially bought a super small PC box to use for running BruteFIR. It looked like the real deal: small, fast, neat and quiet, and with a full sized PCI slot. The specs were:

Processor: Via Low Power C3/Eden Processor at 800Mhz
Chipset: VIA VT-133 for EPIA (North / South)
System Memory: 512MB Memory 1 x Slots available
Video: 64 bit 2D/3D graphic engine and video accelerator , 1280x1024 16 bit colour or 1024x768 32 bit colour
Audio: 3D sound system complies with PC98 audio specifications/Audio-out and Mic-in.
LAN: Built-in high speed Ethernet 10/100Mbps LAN controller
USB: Integrated 4 independent OHCI controller supporting USB 1.1 ports
Hard Drive: Ultra DMA 33/66/100 IDE Connector
Hard Drive Adaptors: IDE to CF -II Adaptor with Cable Mounted on the IDE Slot , A CF Card is not included

But, I couldn’t get Linux to install, in any of the flavours of Fedora, Ubuntu or SPLinux. So, I ditched that hardware and went for a second-hand small form factor IBM PC, spec’d as follows:

Make/Model: IBM/ThinkCentre M51 8106-D1M
Processor/Speed: Pentium 4/3.0GHz Intel® Pentium® 4 Processor 630 with HT Technology
Motherboard/Chipset: IBM/Intel 915GV
Memory slots: 400MHz DDR2 (Double Data Rate) dual channel memory support, PC2-4200 (400MHz) memory supported, 2 x 240 pin DDR2 SDRAM DIMM sockets, supports a maximum memory up to 4.0GB, ECC or parity memory is not supported
Installed memory: 1024mb
Storage: 80gb SATA Hard Disk Drive
Optical devices: CD-Rom
Video: Integrated Intel Graphics Media Accelerator 900
Network: Integrated 10/100/1000 (Gigabit) Ethernet with Wake on LAN
On board I/O: Six USB ( two in front, four in back) [Ver 2.0], One Ethernet RJ-45, One serial 9-pin 16550 compatible, One parallel 25-pin (EPP, ECP), IEEE 1284, Keyboard, monitor, and mouse ports, Audio line in, headphone out, and microphone in jacks
Other: Slot 1: Full height, half length PCI
Expansion bays: One fixed Ultrabay Enhanced optical drive (accessible) One 3.5-inch HDD (hidden)
Physical: 85mm high x 280mm wide x 260mm deep, weight fully loaded - approximately 9kgs

The BIOS has a “quiet” mode for the fan which is actually really quiet, very useful for making sure there is no intrusion while listening.

Ironically the IBM is faster, has more memory, a hard drive (absent from the other box), and was cheaper than the first box. Oh well, such is the life of the filter DIYer.

Fedora installed without a hitch in under 30 minutes. The RME card also installed without a problem and was recognised by ALSA. No GUI interface for the card (too old) so its command line prompts only.

I also bought a USB wireless receiver and I can now remotely control the PC from my laptop, using ssh and vncserver under Fedora.

The ALSA “amixer contents” command shows the following:

Code:
numid=5,iface=MIXER,name='IEC958 Input Connector'
  ; type=ENUMERATED,access=rw------,values=1,items=3
  ; Item #0 'ADAT1'
  ; Item #1 'Coaxial'
  ; Item #2 'Internal'
  : values=1
numid=6,iface=MIXER,name='IEC958 Output also on ADAT1'
  ; type=BOOLEAN,access=rw------,values=1
  : values=off
numid=10,iface=MIXER,name='IEC958 Sample Rate'
  ; type=INTEGER,access=r-------,values=1,min=0,max=96000,step=0
  : values=-1
numid=15,iface=MIXER,name='ADAT1 Input Source'
  ; type=ENUMERATED,access=rw------,values=1,items=2
  ; Item #0 'ADAT1'
  ; Item #1 'Internal'
  : values=0
numid=11,iface=MIXER,name='ADAT1 Sync Check'
  ; type=ENUMERATED,access=r-------,values=1,items=4
  ; Item #0 'No Lock'
  ; Item #1 'Lock'
  ; Item #2 'No Lock Sync'
  ; Item #3 'Lock Sync'
  : values=0
numid=12,iface=MIXER,name='ADAT2 Sync Check'
  ; type=ENUMERATED,access=r-------,values=1,items=4
  ; Item #0 'No Lock'
  ; Item #1 'Lock'
  ; Item #2 'No Lock Sync'
  ; Item #3 'Lock Sync'
  : values=0
numid=9,iface=MIXER,name='Channels Thru'
  ; type=BOOLEAN,access=rw------,values=18
  : values=off,off,off,off,off,off,off,off,off,off,off,off,off,off,off,off,off,off
numid=14,iface=MIXER,name='Passthru'
  ; type=BOOLEAN,access=rw------,values=1
  : values=off
numid=8,iface=MIXER,name='Preferred Sync Source'
  ; type=ENUMERATED,access=rw------,values=1,items=3
  ; Item #0 'IEC958 In'
  ; Item #1 'ADAT1 In'
  ; Item #2 'ADAT2 In'
  : values=1
numid=7,iface=MIXER,name='Sync Mode'
  ; type=ENUMERATED,access=rw------,values=1,items=3
  ; Item #0 'AutoSync'
  ; Item #1 'Master'
  ; Item #2 'Word Clock'
  : values=0
numid=13,iface=MIXER,name='Timecode Valid'
  ; type=BOOLEAN,access=r-------,values=1
  : values=off
numid=3,iface=PCM,name='IEC958 Playback Con Mask'
  ; type=IEC958,access=r-------,values=1
  : values=[AES0=0x3b AES1=0x00 AES2=0x00 AES3=0x00]
numid=1,iface=PCM,name='IEC958 Playback Default'
  ; type=IEC958,access=rw------,values=1
  : values=[AES0=0x00 AES1=0x00 AES2=0x00 AES3=0x00]
numid=4,iface=PCM,name='IEC958 Playback Pro Mask'
  ; type=IEC958,access=r-------,values=1
  : values=[AES0=0x1f AES1=0x00 AES2=0x00 AES3=0x00]

All the default settings work with the RME card and Behringer combination. But what’s a mystery are the “Channels Thru” and “Passthru” controls. They are set to off by default, and I don’t know what they do. But at least they don’t seem to be getting in the way.

BruteFIR setup

The BruteFIR configuration file looks like this:

Code:
##
#	Version 1
#	
# Squeeze box output to filter PC then to CX310 crossover. From X'over to front end system, sub to A500 amp and Thor.
# Decoder FR and FL output to same chain as SQB. Surround channels to DSPA1.
# Decoder centre mixed to FR and FL. 
# Sub from crossover delayed but not otherwise filtered.
# No LFE signal from decoder.
#
# ADA8000 physical connections
# 	IN Channel		OUT Channel
	
#	1 - SQB left		1 - Spkr Front Left
#	2 - SQB right		2 - Spkr Front Right
#	3 - Decoder Front L	3 - Spkr Surr Left
#	4 - Decoder Front R	4 - Spkr Surr Right
#	5 - Decoder centre	5 - Spkr Side Left - future use
#	6 - Decoder Surr L	6 - Spkr Side Right - future use
#	7 - Decoder Surr R	7 - Spkr Sub
#	8 - crossover_sub	8 - not used
##

## General Settings that overide defaults in .brutefir_defaults ##

float_bits: 32;             # internal floating point precision
sampling_rate: 48000;       # sampling rate in Hz of audio interfaces
filter_length: 4096;	    # length of filters
overflow_warnings: true;    # echo warnings to stderr if overflow occurs
show_progress: true;       # echo filtering progress to stderr
#show_progress: false;       # echo filtering progress to stderr
max_dither_table_size: 0;   # maximum size in bytes of precalculated dither
allow_poll_mode: false;     # allow use of input poll mode
modules_path: ".";          # extra path where to find BruteFIR modules
monitor_rate: false;        # monitor sample rate
powersave: -70;		    # pause filtering when input is below 70 db from 0db reference
#powersave: false;	    # pause filtering when input is null samples
lock_memory: true;          # try to lock memory if realtime prio is set
sdf_length: -1;             # subsample filter half length in samples
convolver_config: "~/.brutefir_convolver"; # location of convolver config file

########################################## COEFFS ##

coeff "DRC_erb_44100_wav"
{
	filename: "/home/bryan/drc filters/erb-44.1.wav";
	format: "S16_LE";     # file format
	blocks: -1;         # how long in blocks
	skip: 0;            # how many bytes to skip
	shared_mem: false;  # allocate in shared memory
};

########################################### INPUTS ##

input	"squeeze_left", "squeeze_right", "decoder_front_left", "decoder_front_right", "decoder_centre", "decoder_sur_left", "decoder_sur_right", "crossover_sub" 
{	
	device: "alsa" { param: "hw:R15"; } ;	    # module and parameters to output audio
	sample: "S24_4LE";   		# sample format
	channels: 18/0,1,2,3,4,5,6,7;  	# number of open channels / which to use
	delay: 0,0,0,0,0,0,0,0;        	# delay in samples for each channel
	maxdelay: -1;       		# max delay for variable delays
	mute: false,false;  		# mute active on startup for each channel
};

########################################### OUTPUTS ##

output "spkr_front_left", "spkr_front_right", "spkr_sur_left", "spkr_sur_right", "spkr_side_left", "spkr_side_right", "spkr_sub" 
{
	device: "alsa" { param: "hw:R15"; } ;	    # module and parameters to output audio
	sample: "S24_4LE";   		# sample format
	channels: 18/0,1,2,3,4,5,6;    	# number of open channels / which to use
	delay: 0,0,0,0,0,0,210;  	# delay in samples for each channel. For sub, need to delay 1.5 metres = 4.373 milliseconds. @ 48KHz sampling = 210 samples.
					#	@ 44100Hz sampling = 193 samples.
	maxdelay: -1;       		# max delay for variable delays
	mute: false,false;  		# mute active on startup for each channel
	dither: false;      		# apply dither
};

############################################# FILTERS  ##

##
## INTERMEDIATE FILTERS ##
##

filter "squeeze_left_passthru"
{
	from_inputs: "squeeze_left";
	to_filters: "front_left_filter";
	coeff: -1;			# no filtering, just pass through
	#coeff: "DRC_erb_44100_wav";	# 16 bit wave file for filter
	process: 0;        		# process index to run in (-1 means auto)
	delay: 0;           		# predelay, in blocks
	crossfade: false;   		# crossfade when coefficient is changed
};

filter "squeeze_right_passthru"
{
	from_inputs: "squeeze_right";
	to_filters: "front_right_filter";
	coeff: -1;			# no filtering, just pass through
	#coeff: "DRC_erb_44100_wav";	# 16 bit wave file for filter
	process: 0;        		# process index to run in (-1 means auto)
	delay: 0;           		# predelay, in blocks
	crossfade: false;   		# crossfade when coefficient is changed
};

filter "decoder_front_left_mix"
{
	from_inputs: "decoder_front_left", "decoder_centre"/3.0;
	to_filters: "front_left_filter";
	coeff: -1;			# no filtering, just pass through
	#coeff: "DRC_erb_44100_wav";	# 16 bit wave file for filter
	process: 0;        		# process index to run in (-1 means auto)
	delay: 0;           		# predelay, in blocks
	crossfade: false;   		# crossfade when coefficient is changed
};

filter "decoder_front_right_mix"
{
	from_inputs: "decoder_front_right", "decoder_centre"/3.0;
	to_filters: "front_right_filter";
	coeff: -1;			# no filtering, just pass through
	#coeff: "DRC_erb_44100_wav";	# 16 bit wave file for filter
	process: 0;        		# process index to run in (-1 means auto)
	delay: 0;           		# predelay, in blocks
	crossfade: false;   		# crossfade when coefficient is changed
};

##
## FINAL FILTERS TO OUTPUTS ##
##

filter "front_left_filter"
{
	from_filters: "decoder_front_left_mix", "squeeze_left_passthru";
	to_outputs: "spkr_front_left";
	#coeff: -1;			# no filtering, just pass through
	coeff: "DRC_erb_44100_wav";	# 16 bit wave file for filter
	process: 0;        		# process index to run in (-1 means auto)
	delay: 0;           		# predelay, in blocks
	crossfade: false;   		# crossfade when coefficient is changed
};

filter "front_right_filter"
{
	from_filters: "decoder_front_right_mix", "squeeze_right_passthru";
	to_outputs: "spkr_front_right";
	#coeff: -1;			# no filtering, just pass through
	coeff: "DRC_erb_44100_wav";	# 16 bit wave file for filter
	process: 0;        		# process index to run in (-1 means auto)
	delay: 0;           		# predelay, in blocks
	crossfade: false;   		# crossfade when coefficient is changed
};

filter "sur_left_passthru"
{
	from_inputs: "decoder_sur_left" ;
	to_outputs: "spkr_sur_left";
	coeff: -1;			# no filtering, just pass through
	#coeff: "DRC_erb_44100_wav";	# 16 bit wave file for filter
	process: 0;        		# process index to run in (-1 means auto)
	delay: 0;           		# predelay, in blocks
	crossfade: false;   		# crossfade when coefficient is changed
};

filter "sur_right_passthru"
{
	from_inputs: "decoder_sur_right" ;
	to_outputs: "spkr_sur_right";
	coeff: -1;			# no filtering, just pass through
	#coeff: "DRC_erb_44100_wav";	# 16 bit wave file for filter
	process: 0;        		# process index to run in (-1 means auto)
	delay: 0;           		# predelay, in blocks
	crossfade: false;   		# crossfade when coefficient is changed
};

filter "side_left_passthru"
{
	from_inputs: "decoder_sur_left" ;
	to_outputs: "spkr_side_left";
	coeff: -1;			# no filtering, just pass through
	#coeff: "DRC_erb_44100_wav";	# 16 bit wave file for filter
	process: 0;        		# process index to run in (-1 means auto)
	delay: 0;           		# predelay, in blocks
	crossfade: false;   		# crossfade when coefficient is changed
};

filter "side_right_passthru"
{
	from_inputs: "decoder_sur_right" ;
	to_outputs: "spkr_side_right";
	coeff: -1;			# no filtering, just pass through
	#coeff: "DRC_erb_44100_wav";	# 16 bit wave file for filter
	process: 0;        		# process index to run in (-1 means auto)
	delay: 0;           		# predelay, in blocks
	crossfade: false;   		# crossfade when coefficient is changed
};

filter "sub_passthru"
{
	from_inputs: "crossover_sub" ;
	to_outputs: "spkr_sub";
	coeff: -1;			# no filtering, just pass through
	#coeff: "DRC_erb_44100_wav";	# 16 bit wave file for filter
	process: 0;        		# process index to run in (-1 means auto)
	delay: 0;           		# predelay, in blocks
	crossfade: false;   		# crossfade when coefficient is changed
};

I created a script to run it as a daemon at logon, using the BruteFIR daemon parameter in the command line.

At present its using just one .wav file as a filter, created under DRC then put into a .wav format by the Inguz software (for use with the squeezebox server).

The main item of note in the configuration file is the filter length parameter. It only works for a value of 4096. Anything larger and the output signal has strange echo artefacts - maybe its because the filter is a 16 bit wav file. I won’t know for sure until I create proper floating point .pcm coefficient files from DRC.

Also a weird situation: the PC now has two sound cards: the built-in Intel one, and the RME. Sometimes on start-up the RME would be listed as card zero, sometimes as card 1. I originally had an ALSA call in the BruteFIR file to “hw:1,0” (assuming the RME card would always be 1 and the Intel card zero) but of course that would fall over if the RME was card zero. So I changed it to read “hw:R15” which is the other way ALSA knows about the card (got that info from /proc/asound/cards). So now its independent from how ALSA loads the cards at start-up.

One neat function is that BruteFIR can delay input or output channels in single sample increments. So I can delay the output to the Thor sub-woofer by 210 samples (at 48kHz sampling), which is equivalent to delaying the signal by 1.5 metres. It also means I can sell my digital delay unit which has now become redundant, so that’s one less box to power.

Physical setup

The PC is located in the dining room next to the lounge room. So I need to run toslink optical cable from the main collection of equipment to the PC and then back again to the amps and speakers. So I’ve ordered 2 x 10 metres of toslink cable: the analogue inputs (CD, PVR etc) go into the ADA8000 located in the same cabinet, then the data stream goes via optical cable to the PC, then back to the ADA8000 for conversion to analogue and routing to the amps and speakers.

Ten metres is apparently the limit for toslink cable, so we’ll just have to see how that goes.

More as things progress. As always questions welcome.
 
Last edited:
Update: 10m Toslink cable installed

So, the 10m Toslink cable arrived and has been installed. No problems with 10m length that I can detect. The PC running the filters can be placed in an adjacent room to the listening (lounge) room. Even though the PC is pretty quiet, the distance means there is no noise at all from the PC to the listening position.

Next update: dealing with latency problems with the audio stream from video playback.
 
Update: Latency on audio from video

Previous posts have discussed the problem of latency caused by FIR filters. After some experimenting I have found that its not possible (in my setup) to get video images and the video audio in sync with each other, if the audio is processed through a FIR room correction filter with BruteFIR.

I have tried the following to reduce the latency delay:

  • installed a low latency version of Fedora (Planet CCRMA).
  • used the BruteFIR configuration file to set small (128 sample) partitions. This resulted in high CPU usage (over 60%) but still noticeable delay. Any partition size less than 128 caused instability and “broken pipe” messages.
  • used the JACK low latency server to provide the audio stream to BruteFIR.
Unfortunately none of these changes could bring the delay down to non-noticeable levels. It seems that the size of the room correction filter (0.7 seconds long, about 32,000 samples) is just too large to make the delay low enough for video use. I used videos of drum playing as the test source.

So, the audio from videos is processed thus:

  • PVR and DVD player digital outputs go to a Mocha 5.1 decoder.
  • From there, four of the six analogue output channels (front left, front right, centre and low frequency effect ) go into a Behringer mixer and get down mixed to a 2 channel stream. This is because the Mocha does not have any bass management smarts.
  • This 2 channel stream is then fed into a Behringer DEQ2496 that applies a 1/3 octave equalisation to both channels. This is the combined eq from the anechoic and in-situ room measurements referenced in earlier posts on this thread.
  • The output from the DEQ is fed to a Behringer CX2100 crossover, which splits the signal into a front left and front right high-pass (> 60Hz) stream and a single low-pass (< 60Hz) stream.
  • All three streams then go into the Behringer ADA8000.
  • Also into the ADA8000 are the surround left and surround right channels from the Mocha.
  • The ADA conversion frequency is set at 44100Hz, with 24 bit word length. The ADA is also set as the clock master.
  • The digital ADAT output from the ADA then goes to the PC running BruteFIR.
In this case there is (relatively) nothing much for the program to do. It:
  • copies the front left and front right high-pass signals from input to output.
  • applies a simple FIR crossover to the surround left and right channels. The crossover frequency is 60Hz. There are 4096 taps per filter. The filter was created with Octave (free Linux software), using a script I found on this forum. From a latency perspective, a 4096 tap filter is small change for the BrutreFIR program.
  • mixes the sub woofer input signal with the low-pass (<60Hz) components from the surround channels.
  • outputs the combined sub signal with a delay, since the sub is located too close to the listening position relative to the front left and right speakers.

The front left and right output from the PC is then sent via SPDIF to a Behringer DCX2496 for 3 way active crossover processing and onto the front speaker amps.

The delayed sub woofer signal is sent back to the ADA8000 via the Toslink cable and after conversion to analogue fed to a Behringer A500 amp that drives the subwoofer.

By avoiding any long FIR calculations the audio from video is completely in sync with the video image. Sound quality is still excellent.

Over time I will experiment with getting the audio from video into the filter chain. Current thoughts are to use VLC under Linux as the video player. It has great options for user defined delays to video streams. What I need to do is get the multi-channel digital audio stream out of VLC and into BruteFIR. Probably by using the JACK server, but I haven’t really explored this yet.

Next update: Finally, concert hall impulses and rear channel reverb!
 
If your audio setup has a constant delay, playing video from the same PC should allow any controllable delays in the video stream to synchronize with the sound - see e.g. the -delay option of mplayer.

Yes, thats what I will be trying to do. The trick with my current setup is to get the audio stream out of the video player so it can be either (a) processed by the 5.1 decoder and go through the analogue chain, or (b) processed directly by BruteFIR. I have not been able to get either to happen, yet. VLC has good delay logic for the video stream. Btw I think its a better video player under Linux than mplayer.

As I said, the video stuff is on the radar, not just the highest priority at present (there are concert halls to simulate!:D.)
 
I have brutefir running roomcorrection in 5.1 system and doing 3-way crossovers for each speaker. No problem with latency. 50ms measured with PS3 Singstar mic-loop :rolleyes:.

The way to do it
  • Ubuntu & real-time kernel.
  • Brutefir having 256 sample partitions
  • Jackd having 256 sample partitions
  • Minimum phase crossovers. Impulse response of LR8 filters windowed to 4096 FIR taps.
  • 4096 tap room correction filters, calculated by Denis Sbragion's drc
  • Intel D945GCLF based mini-itx running at CPU usage about 80%. All unneccessary processes (eg. window manager) killed.
 
I have brutefir running roomcorrection in 5.1 system and doing 3-way crossovers for each speaker. No problem with latency. 50ms measured with PS3 Singstar mic-loop :rolleyes:.

The way to do it
  • Ubuntu & real-time kernel.
  • Brutefir having 256 sample partitions
  • Jackd having 256 sample partitions
  • Minimum phase crossovers. Impulse response of LR8 filters windowed to 4096 FIR taps.
  • 4096 tap room correction filters, calculated by Denis Sbragion's drc
  • Intel D945GCLF based mini-itx running at CPU usage about 80%. All unneccessary processes (eg. window manager) killed.

Hmm...If I had a 4096 tap room correction filter I'd have no problems either!:cool:

How did you get such a short filter? I use Denis Sbragion's DRC program. With the default settings it produced a 32,000 tap filter. It would be appreciated if you expand on your room correction procedure / DRC filter settings.
 
drc manual says..

6.11.8 PSOutWindow

Final window after post filtering. This is also the length of the generated correction filter. Usual values are between 8192 and 65536. Filter with 65536 taps gives about 0.5 Hz resolution at 44.1 KHz sample rate, 16384 is usually enough for most situation and 8192 gives somewhat good results with much less computing needs during real time convolution.


May be that correction in bass tones is slightly decreased if the filter length is 4096.
 
...May be that correction in bass tones is slightly decreased if the filter length is 4096.

Interesting. Did you do any listening comparisons between a short (4096) filter and a longer one?

I must admit I haven't done so - I just implicitly trusted Sbragion's default values. Your post has piqued my interest in trying out some shorter filters.

As to the benefits of filter length, my understanding is that the longer the filter the better the filter is at controlling low frequency variations (as you noted). I really like how controlled the bass is in my listening room now - sort of a seamless transition from mid frequencies down to the sub 40Hz range.
 
Status
This old topic is closed. If you want to reopen this topic, contact a moderator using the "Report Post" button.