ERRATUM und Ergänzung
Die Filterfunktion rutschte in der Hitze des Publikationsgefechts leider eine Filterdefinition zu tief ab:
Die Filterfunktion Corr_S muss auf den Filter [Filt_LR-to-S] wirken, und nicht auf die nachgeschalteten Filter [Filt_MS-to-L] und [Filt_MS-to-R] !!!. So wie zuvor irrtümlich publiziert, wirkt das Shelvin-Filter einfach bloss linear auf beide Ausgänge, ohne jeglichen FLOW-Effekt.
Richtig ist:
filter "Filt_LR-to-S" {
from_filters: "Filt_L_pre" /0/1, "Filt_R_pre" /0/-1;
to_filters: "Filt_MS-to-L", "Filt_MS-to-R", "Filt_Null";
process: -1;
coeff: "Coeff_S"; # <--- Coeff_S gehört hierher ... #
Hier allerdings...
filter "Filt_MS-to-L" {
from_filters: "Filt_LR-to-M" /0/1, "Filt_LR-to-S" /0/1;
... und hier ...
filter "Filt_MS-to-R" {
from_filters: "Filt_LR-to-M" /0/1, "Filt_LR-to-S" /0/-1;
... lässt sich die Stereo-Breite stufenlos und linear von Max. bis Mono einstellen. Falls der S-Anteil ganz weggenommen wird, wird das Ausgangsignal Mono auf beiden L/R Kanälen:
filter "Filt_MS-to-L" {
from_filters: "Filt_LR-to-M" /0/1, "Filt_LR-to-S" /
100/1;
... und hier ...
filter "Filt_MS-to-R" {
from_filters: "Filt_LR-to-M" /0/1, "Filt_LR-to-S" /
100/-1;
Im Beispiel wird in Fettschrift eine Absenkung von -100dB für die S-Komponente definiert.
Richtig also lautet die Brutefir-Config folgendermassen:
Code: Alles auswählen
#############################################
## brutefirconfig
## Filterlänge 64k
## Test
## Soundcard: Thinkpad Intern
## FLOW
#############################################
float_bits: 64; # internal floating point precision
sampling_rate: 44100; # sampling rate in Hz of audio interfaces
#filter_length: 32768,2;
#filter_length: 16384,4;
filter_length: 8192,8;
#filter_length: 4096,16;
#
allow_poll_mode: true; # allow use of input poll mode
lock_memory: false; # try to lock memory if realtime prio is set - set to false, dafür keine systemweite SWAP-file
max_dither_table_size: 0; # maximum size in bytes of precalculated dither
powersave: false; # pause filtering when input is zero - nur sinnvoll für Leistungsmessungen ohne Eingangssignal
sdf_length: 0; # subsample filter half length in samples
#
overflow_warnings: true; # echo warnings to stderr if overflow occurs
monitor_rate: true; # monitor sample rate
show_progress: true; # echo filtering progress to stderr
#safety_limit: -14.5;
#
convolver_config: "/home/privat/_fracon/brutefir_convolver"; # location of convolver config file
#config_file: "/home/privat/_fracon/brutefir_config"; # standard location of main config file
modules_path: "/usr/lib/brutefir"; # extra path where to find BruteFIR modules
## LOGIC ##
logic: "cli" { port: 3000; };
## COEFFS ##
#coeff <STRING: name | NUMBER: index> {
# filename: <STRING: filename>; | <NUMBER: shmid>/<NUMBER: offset>/<NUMBER: blocks>[,...];
# format: <STRING: sample format string | "text" | "processed">;
# attenuation: <NUMBER: attenuation in dB>;
# blocks: <NUMBER: length in blocks>;
# skip: <NUMBER: bytes to skip in beginning of file>;
# shared_mem: <BOOLEAN: allocate in shared mem>
#};
coeff "Coeff_S" {
filename: "/home/privat/_fracon/filter/500-4000-2_044.dbl";
format: "FLOAT64_LE";
attenuation: 0.0;
blocks: -1;
skip: 0;
shared_mem: false;
};
## INPUT ##
#input <STRING: name | NUMBER: index>[, ...] {
# device: <STRING: I/O module name> { <I/O module settings>> };
# sample: <STRING: sample format>;
# channels: <NUMBER: open channels>[/<NUMBER: channel index>[, ...]];
# delay: <NUMBER: delay in samples>[, ...];
# subdelay: <NUMBER: additional delay in 1/100th samples (valid range -99 - 99)>[, ...];
# maxdelay: <NUMBER: maximum delay for dynamic changes>;
# individual_maxdelay: <NUMBER: maximum delay for dynamic changes>[, ...];;
# mute: <BOOLEAN: mute channel>[, ...];
# mapping: <NUMBER: channel index>[, ...];
#};
input "In_L", "In_R" {
# device: "alsa" { device: "hw:0"; }; # ALSA
device: "file" { path: "/dev/stdin"; };
sample: "S16_LE";
channels: 2/0,1;
delay: 0,0;
# subdelay: 0,0;
# maxdelay: -1;
# individual_maxdelay: 0,0;
mute: false, false;
};
## OUTPUT ##
#output <STRING: name | NUMBER: index>[, ...] {
# device: <same syntax as for the input structure>;
# sample: <same syntax as for the input structure>;
# channels: <same syntax as for the input structure>;
# delay: <same syntax as for the input structure>;
# subdelay: <NUMBER: additional delay in 1/100th samples (valid range -99 - 99)>[, ...];
# maxdelay: <same syntax as for the input structure>;
# individual_maxdelay: <same syntax as for the input structure>;
# mute: <same syntax as for the input structure>;
# mapping: <same syntax as for the input structure>;
# dither: <BOOLEAN: apply dither>;
# merge: <BOOLEAN: merge discontinuities at coeff change>;
#};
output "Out_L","Out_R" {
device: "alsa" { device: "hw:0,0"; };
# device: "file" { path: "/dev/stdout"; };
sample: "S16_LE";
channels: 2/0,1;
delay: 0,0;
# maxdelay: -1;
# individual_maxdelay: 0,0;
mute: false,false;
dither: true;
};
output "Out_Null" {
device: "file" { path: "/home/privat/Downloads/nullfile.raw"; };
sample: "S16_LE";
channels: 1;
};
## FILTERS ##
#filter <STRING: name | NUMBER: index> {
# from_inputs: <STRING: name | NUMBER: index>[/<NUMBER:attenuation in dB>][/<NUMBER:multiplier>][, ...];
# from_filters: <same syntax as from_inputs field>;
# to_outputs: <same syntax as from_inputs field>;
# to_filters: <STRING: name | NUMBER: index>[, ...];
# process: <NUMBER: process index>;
# coeff: <STRING: name | NUMBER: index>;
# delay: <NUMBER: pre-delay in blocks>;
# crossfade: <BOOLEAN: cross-fade when coefficient is changed>;
#};
### Input filter section
filter "Filt_L_pre" {
from_inputs: "In_L" /0/1;
to_filters: "Filt_LR-to-M", "Filt_LR-to-S", "Filt_LR-to-S_inv";
process: -1;
coeff: -1;
delay: 0;
crossfade: false;
};
filter "Filt_R_pre" {
from_inputs: "In_R" /0/1;
to_filters: "Filt_LR-to-M", "Filt_LR-to-S", "Filt_LR-to-S_inv";
process: -1;
coeff: -1;
delay: 0;
crossfade: false;
};
### Matrix L-R to M-S
filter "Filt_LR-to-M" {
from_filters: "Filt_L_pre" /0/1, "Filt_R_pre" /0/1;
to_filters: "Filt_MS-to-L", "Filt_MS-to-R";
process: -1;
coeff: -1;
delay: 0;
crossfade: false;
};
filter "Filt_LR-to-S" {
from_filters: "Filt_L_pre" /0/1, "Filt_R_pre" /0/-1;
to_filters: "Filt_MS-to-L", "Filt_MS-to-R", "Filt_Null";
process: -1;
coeff: "Coeff_S"; # <--- Coeff_S gehört hierher ... #
# coeff: -1;
delay: 0;
crossfade: false;
};
filter "Filt_LR-to-S_inv" {
from_filters: "Filt_L_pre" /0/-1, "Filt_R_pre" /0/1;
to_filters: "Filt_Null";
process: -1;
coeff: -1;
delay: 0;
crossfade: false;
};
### Matrix M-S back to L-R
filter "Filt_MS-to-L" {
from_filters: "Filt_LR-to-M" /0/1, "Filt_LR-to-S" /0/1;
to_outputs: "Out_L";
process: -1;
coeff: -1; # <--- ... und weder hierher ... #
delay: 0;
crossfade: false;
};
filter "Filt_MS-to-R" {
from_filters: "Filt_LR-to-M" /0/1, "Filt_LR-to-S" /0/-1;
to_outputs: "Out_R";
process: -1;
coeff: -1; # <--- ... noch hierher !!! #
delay: 0;
crossfade: false;
};
### Control
filter "Filt_Null" {
from_filters: "Filt_LR-to-S" /0/1, "Filt_LR-to-S_inv" /0/-1;
to_outputs: "Out_Null";
process: -1;
coeff: -1;
delay: 0;
crossfade: false;
};
Berichtigende Grüsse
Simon