diff --git a/datas/eq/Proson Twin 716/iir-autoeq.txt b/datas/eq/Proson Twin 716/iir-autoeq.txt index 50aa1c125..4dfe09bc8 100644 --- a/datas/eq/Proson Twin 716/iir-autoeq.txt +++ b/datas/eq/Proson Twin 716/iir-autoeq.txt @@ -1,14 +1,14 @@ EQ for Proson Twin 716 computed from Misc data -Preference Score 2.57 with EQ 5.29 +Preference Score 2.57 with EQ 5.36 Generated from https://github.com/pierreaubert/spinorama/generate_peqs.py v0.26 -Dated: 2024-12-11-10:03:05 +Dated: 2024-12-11-11:02:39 Preamp: -5.6 dB Filter 1: ON PK Fc 29 Hz Gain +6.00 dB Q 0.56 -Filter 2: ON PK Fc 80 Hz Gain -6.75 dB Q 1.89 -Filter 3: ON PK Fc 332 Hz Gain -2.50 dB Q 0.55 -Filter 4: ON PK Fc 879 Hz Gain -2.82 dB Q 3.00 -Filter 5: ON PK Fc 1642 Hz Gain -3.38 dB Q 2.99 +Filter 2: ON PK Fc 80 Hz Gain -6.75 dB Q 1.82 +Filter 3: ON PK Fc 190 Hz Gain -1.99 dB Q 2.99 +Filter 4: ON PK Fc 522 Hz Gain -3.00 dB Q 0.69 +Filter 5: ON PK Fc 1642 Hz Gain -3.20 dB Q 2.98 Filter 6: ON PK Fc 2670 Hz Gain +6.00 dB Q 1.00 -Filter 7: ON PK Fc 9648 Hz Gain -4.09 dB Q 0.50 +Filter 7: ON PK Fc 9648 Hz Gain -4.16 dB Q 0.50 diff --git a/scripts/update_one_eq.sh b/scripts/update_one_eq.sh index 047082944..3812ab573 100755 --- a/scripts/update_one_eq.sh +++ b/scripts/update_one_eq.sh @@ -32,19 +32,23 @@ start_ray() compute_eq() { EXTRA="" - smooth="asis" + smooth="none" if [ "$4" != "" ]; then - smooth="smooth" EXTRA="${EXTRA} $4" + IFS=' ' read -r -a parameters <<< "${4//[a-z-=]/}" + window=${parameters[0]} + order=${parameters[1]} + smooth="sw${window}o${order}" fi full="pk" if [ "$5" != "" ]; then - full="all" EXTRA="${EXTRA} $5" + full="all" fi - target_dir="$(pwd)/build/eqs/$3/$2-$1-$smooth-$full" + target_dir="$(pwd)/build/eqs/$3/$2-$1-${smooth}-${full}" + echo "Creating ${target_dir}" mkdir -p "$target_dir" - echo ./generate_peqs.py --verbose --force --optimisation=global --max-iter=15000 --speaker="$3" --max-peq=$1 --fitness=$2 --ray-cluster=$IP:$PORT ${EXTRA} --output-dir="$target_dir" + # echo ./generate_peqs.py --verbose --force --optimisation=global --max-iter=15000 --speaker="$3" --max-peq=$1 --fitness=$2 --ray-cluster=$IP:$PORT ${EXTRA} --output-dir="$target_dir" { ./generate_peqs.py \ --verbose \ --force \ @@ -89,6 +93,30 @@ do compute_eq 6 "Score" "$spk" "--smooth-measurements=7 --smooth-order=3" "" compute_eq 7 "Score" "$spk" "--smooth-measurements=7 --smooth-order=3" "" + compute_eq 3 "Flat" "$spk" "--smooth-measurements=11 --smooth-order=3" "" + compute_eq 4 "Flat" "$spk" "--smooth-measurements=11 --smooth-order=3" "" + compute_eq 5 "Flat" "$spk" "--smooth-measurements=11 --smooth-order=3" "" + compute_eq 6 "Flat" "$spk" "--smooth-measurements=11 --smooth-order=3" "" + compute_eq 11 "Flat" "$spk" "--smooth-measurements=11 --smooth-order=3" "" + + compute_eq 3 "Score" "$spk" "--smooth-measurements=11 --smooth-order=3" "" + compute_eq 4 "Score" "$spk" "--smooth-measurements=11 --smooth-order=3" "" + compute_eq 5 "Score" "$spk" "--smooth-measurements=11 --smooth-order=3" "" + compute_eq 6 "Score" "$spk" "--smooth-measurements=11 --smooth-order=3" "" + compute_eq 11 "Score" "$spk" "--smooth-measurements=11 --smooth-order=3" "" + + compute_eq 3 "Flat" "$spk" "--smooth-measurements=21 --smooth-order=5" "" + compute_eq 4 "Flat" "$spk" "--smooth-measurements=21 --smooth-order=5" "" + compute_eq 5 "Flat" "$spk" "--smooth-measurements=21 --smooth-order=5" "" + compute_eq 6 "Flat" "$spk" "--smooth-measurements=21 --smooth-order=5" "" + compute_eq 21 "Flat" "$spk" "--smooth-measurements=21 --smooth-order=5" "" + + compute_eq 5 "Score" "$spk" "--smooth-measurements=21 --smooth-order=5" "" + compute_eq 4 "Score" "$spk" "--smooth-measurements=21 --smooth-order=5" "" + compute_eq 5 "Score" "$spk" "--smooth-measurements=21 --smooth-order=5" "" + compute_eq 6 "Score" "$spk" "--smooth-measurements=21 --smooth-order=5" "" + compute_eq 21 "Score" "$spk" "--smooth-measurements=21 --smooth-order=5" "" + done for job in $(jobs -p) diff --git a/src/spinorama/auto_global.py b/src/spinorama/auto_global.py index b34dbe051..4826ad844 100644 --- a/src/spinorama/auto_global.py +++ b/src/spinorama/auto_global.py @@ -140,6 +140,7 @@ def __init__( self.max_q = self.config["MAX_Q"] self.max_peq = self.config["MAX_NUMBER_PEQ"] self.max_iter = self.config["MAX_ITER"] + self.current_score = None def _freq2index(self, f: float): return bisect.bisect_left(self.freq_space, f) @@ -178,6 +179,10 @@ def _x2peq(self, x: Encoded) -> Peq: peq.append((1.0, Biquad(iir_type, freq, 48000, q, spl))) return peq + def _x2print(self, x: Encoded) -> None: + peq = self._x2peq(x) + peq_print(peq) + def _x2spl(self, x: Encoded) -> Vector: # take a list of encoded filters and return the magnitude of the filter across the freq range return peq_spl(self.freq_space, self._x2peq(x)) @@ -228,9 +233,10 @@ def _opt_peq_flat(self, x: list[float | int]) -> float: def _opt_peq(self, x: list[float | int]) -> float: # for a given encoded peq, compute a loss function - return ( + self.current_score = ( self._opt_peq_score(x) if self.config["loss"] == "score_loss" else self._opt_peq_flat(x) ) + return self.current_score def _opt_bounds_all(self, n: int) -> list[list[int | float]]: # compute bounds for variables @@ -338,20 +344,32 @@ def _opt_constraints_q(x) -> int: l = len(x) // 4 for i in range(l): _, f, q, _, _ = self._x2params(x, i) + if q > self.max_q or q < self.min_q: + return 1 f_hz = self._index2freq(f) - if (f_hz > 2000 and q > 1.0) or (f_hz > 3400 and q > 0.5): + if (f_hz > 2000 and q > 1.0) or (f_hz > 3500 and q > 0.5): return 1 return -1 def _opt_constraints_gain(x) -> int: # check that total gain at any point in lower that max_db l = len(x) // 4 - m = 0 for i in range(l): - _, f, _, _, _ = self._x2params(x, i) - m += self._x2peq(x)[i][1].log_result(f) - if np.max(np.clip(m, 0, None)) > self.max_db: + _, f, _, g, _ = self._x2params(x, i) + # ko if between -min and +min + if (g > 0.0 and (g < self.min_db) or (g > self.max_db)) or ( + g < 0.0 and g > -self.min_db + ): + # print("gain {} = {} rejected".format(i, g)) return 1 + + # check that we do not clip + spl = self._x2spl(x) + spl_max = np.max(np.clip(spl, 0, None)) + if spl_max > self.max_db: + # print("max gain {} > {} rejected".format(spl_max, self.max_db)) + # print(spl) + return 1 return -1 def _opt_constraints_freq(x) -> int: @@ -373,11 +391,11 @@ def _opt_constraints_freq(x) -> int: return -1 def _opt_constraints_all(x) -> int: - if ( - _opt_constraints_freq(x) == 1 - or _opt_constraints_gain(x) == 1 - or _opt_constraints_q(x) == 1 - ): + c_freq = _opt_constraints_freq(x) == 1 + c_gain = _opt_constraints_gain(x) == 1 + c_q = _opt_constraints_q(x) == 1 + if c_freq or c_gain or c_q: + # print("NL constraints: freq={} gain={} q={}".format(c_freq, c_gain, c_q)) return 1 return -1 @@ -387,7 +405,11 @@ def _opt_constraints_all(x) -> int: def _opt_display(self, xk, convergence): # comment if you want to print verbose traces - print(f"[f={1-convergence}<{CONVERGENCE_TOLERANCE}] iir={self.config['use_all_biquad']}") + iir_status = "*" if self.config["use_all_biquad"] else "pk" + score_status = ( + "{:3.1f}".format(self.current_score) if self.current_score is not None else "?" + ) + print(f"[f={1-convergence}<{CONVERGENCE_TOLERANCE}] iir={iir_status} score={score_status}") peq_print(self._x2peq(xk)) def run(self): diff --git a/tests/test_go.py b/tests/test_go.py index 4f7ecd2aa..4eda63cd3 100755 --- a/tests/test_go.py +++ b/tests/test_go.py @@ -26,6 +26,7 @@ import numpy.testing as npt import pandas as pd +from spinorama.filter_peq import peq_print from spinorama.load_klippel import parse_graph_freq_klippel from spinorama.auto_global import GlobalOptimizer, _resample @@ -73,7 +74,7 @@ def setUp(self): "target_max_freq": 16000, "MIN_Q": 1.0, "MAX_Q": 3.0, - "MIN_DBGAIN": -3.0, + "MIN_DBGAIN": 1.0, "MAX_DBGAIN": 3.0, "MAX_ITER": 500, "MAX_NUMBER_PEQ": 3, @@ -180,13 +181,16 @@ def test_linear_constraint(self): def test_non_linear_constraint(self): nlc = self.go._opt_constraints_nonlinear(3) fun = nlc.fun - x = np.array([0, 25, 0, 0, 0, 50, 0, 0, 0, 75, 0, 0]) + x = np.array([0, 25, 2, 2, 1, 50, 2, -2, 2, 75, 2, 2]) + # self.go._x2print(x) c = fun(x) self.assertEqual(c, -1) # true - x = np.array([0, 25, 0, 0, 0, 34, 0, 0, 0, 75, 0, 0]) + x = np.array([0, 25, 2, 2, 1, 34, 2, -2, 2, 75, 2, 2]) + # self.go._x2print(x) c = fun(x) self.assertEqual(c, 1) # false - x = np.array([0, 25, 0, 0, 0, 100, 0, 0, 0, 75, 0, 0]) + x = np.array([0, 25, 2, 2, 1, 100, 2, -2, 2, 75, 2, 2]) + # self.go._x2print(x) c = fun(x) self.assertEqual(c, 1) # false