HydrogenAudio

Hosted Forums => foobar2000 => 3rd Party Plugins - (fb2k) => Topic started by: Juha on 2023-08-06 10:54:39

Title: AutoEq --> Foobar2k EQ presets
Post by: Juha on 2023-08-06 10:54:39
AutoEq (https://github.com/jaakkopasanen/AutoEq) (by Jaakko Pasanen) is an utility for headphone equalization.

I made routines to make it support SuperEQ, which can be found on few software as like Foobar2k DT/Foobar Mobile and DeaDBeeF (originally SuperEQ was made for Winamp by N. Shibata).  At this point AutoEq has to be installed in your system with these routines ... . Here are the functions to be added in frequency_response.py :

Aitken interpolation (you can use some interpolation method from library as well):

Code: [Select]
def aitkeninterp(x, y, xi):
         
        n = np.size(x)
        if n != np.size(y):
            return
     
        A = np.zeros((n,n), float)
        D = np.zeros(n, float)
        yi = 0.0

        for i in range(0, n):
            D[i] = xi - x[i]
            A[i, 0] = y[i]
        for i in range(1, n):
            for j in range(1, i+1):
                A[i, j] = (D[j-1] * A[i,j-1] - D[i] * A[j-1,j-1]) / (x[i] - x[j-1]);
     
        yi = A[n-1, n-1];

        return round(yi)

SuperEQ preset file calculator/writer (not sure of the file extension 'seq'):

  
Code: [Select]
 def write_supereq(self, file_path):
        """Writes SuperEq's 18 band eq settings to a preset file."""
        """Gain values are interpolated using Aitken's interpolation method from same memory data which is stored into csv file by AutoEQ"""
        last_idx = np.size(self.frequency)-1
        prev_idx = 0

        with open(file_path.replace('.txt', '.feq'), 'w', encoding='utf-8') as f:  # .feq = foobar2k preset file extension
            s = ''
            file_path = os.path.abspath(file_path)
            cfreq = [55.0, 77.0, 110.0, 156.0, 220.0, 311.0, 440.0, 622.0, 880.0, 1200.0, 1800.0, \
                     2500.0, 3500.0, 5000.0, 7000.0, 10000.0, 14000.0, 20000.0] # SuperEQ band center frequencies
            idx = 0
          
            for i in cfreq:
                idx = bisect.bisect_left(self.frequency, i, lo=prev_idx, hi=last_idx-1)
                if last_idx > idx+1:
                    G = FrequencyResponse.aitkeninterp([self.frequency[idx-2], self.frequency[idx-1], self.frequency[idx], self.frequency[idx+1]], \
                                                       [self.equalization[idx-2], self.equalization[idx-1], self.equalization[idx], self.equalization[idx+1]], i)
                    s += f'{G:d}\n'
                    prev_idx = idx
                else: # get value from the last element
                    G = round(self.equalization[-1])
                    s += f'{G:d}\n'
                  
            f.write(s)

! remember import bisect in frequency_response.py header.

I have tested functionality by calling the function from write_eqapo_parametric_eq() with a command line FrequencyResponse.write_supereq(self, file_path).

At least this allows generation of presets for SuperEQ/Foobar2k/etc. without need for full SuperEQ implementation.

As for an example, for AKG K240 Studio I got this data for the preset : 6, 4, 1, -2, -3, -3, -2, -1, -1, 1, 4, -1, 3, 3, -1, -1, 1, 5

Compare : https://github.com/jaakkopasanen/AutoEq/tree/master/results/oratory1990/over-ear/AKG%20K240%20Studio
Title: Re: AutoEq --> Foobar2k EQ presets
Post by: Juha on 2023-08-06 17:55:15
Code changes needed to support SuperEQ preset file generation directly with a commandline parameter --supereq :

__main__.py

Code: [Select]
38 arg_parser.add_argument('--supereq', action='store_true',
                            help='Will produce SuperEQ settings if this parameter exists, no value needed.')
                           
                           
batch_processing.py

Code: [Select]
19 def batch_processing( ....  ,supereq=False, ...)

33 if not compensation and (... or supereq):

112 args = (... ,supereq, ...)

133 def process_file(..., supereq, ...)

163     if supereq:
        supereq = True
       
233    if supereq:
        fr.write_supereq(output_file_path.replace('.csv', '.feq'))    

       

frequency_response.py

Code: [Select]
38 def __init__(..., supereq=None, ...)

67         self.supereq = self._init_data(supereq)

73 def copy(..., supereq=self._init_data(self.supereq), ...)

def reset(..., supereq=True, ...)   

160         if supereq:
            self.supereq = self._init_data(None)
           
907 def compensate(...
self.reset(..., supereq=True, ...)
)                 

1044 def smoothen_fractional_octave(...
self.reset(..., supereq=True, ...)
)


Tested with console command:

Code: [Select]
$ python3 -m autoeq --input-file="measurements/oratory1990/data/over-ear/AKG K240 Studio.csv" --output-dir="my_results" --compensation="compensation/harman_over-ear_2018_wo_bass.csv" --supereq
Title: Re: AutoEq --> Foobar2k EQ presets
Post by: Julien on 2024-04-04 08:02:06
Hi Juha,

This is a great idea. I was surprised it wasn't already implemented in the Autoeq web application.

I tried to follow the instructions in your second post step by step.

Unfortunately, it seems that "frequency_response.py" has been modified since then. The line numbers for the instructions are different (slightly in some places) or missing (1044 def smoothen_fractional_octave doesn't seem to be there anymore).

Not being a programmer, I'm a little confused as to how to proceed.

Would you be so kind as to provide some guidance? Could you possibly post the updated code?

Thanks in advance!

J
Title: Re: AutoEq --> Foobar2k EQ presets
Post by: sympathyisaknife on 2024-11-24 22:29:39
I was able to make it work by switching back to the version of AutoEq this additional code was most likely written for:
Code: [Select]
git checkout 402ccd4c0497e70a01263a9a77691535de6f8b8c
Thanks for this by the way! heehee (and sorry for necroposting)