|
| 1 | +# Room equalisation tools |
| 2 | + |
| 3 | +Room equalisation filter calculation is handled by a HiFiBerry web service. There are command line tools to use it |
| 4 | + |
| 5 | +## roomeq-preset |
| 6 | + |
| 7 | +`roomeq-preset --curves` displays target curves supported by the optimizer: |
| 8 | + |
| 9 | +``` |
| 10 | +{ |
| 11 | + "room_only": [[20, 0, [1, 0.5]], [250, 0]], |
| 12 | + "falling_slope": [[20, 0, [1, 0.3]], [100, 0, [1, 0.6]], [200, 0, [0.9, 0.7]], [500, 0, [0.9, 0.5]], [1000, 0, [0.5, 0.3]], [10000, -3, 0.1], [25000, -6]], |
| 13 | + "weighted_flat": [[20, 0, [1, 0.3]], [100, 0, [1, 0.6]], [200, 0, [0.9, 0.7]], [500, 0, 0.6], [5000, 0, 0.4], [10000, 0, 0.1], [25000, 0]], |
| 14 | + "flat": [[20, 0], [25000, 0]] |
| 15 | +} |
| 16 | +``` |
| 17 | + |
| 18 | +Each curve consists of a list of tuples: |
| 19 | +frequency, target-decibel, weight for corrections |
| 20 | + |
| 21 | +Weight is a value between 0 and 1. The higher the value the more the optimizer will try to optimize at this frequency. |
| 22 | + |
| 23 | +The optimizer will only work in the range from the first to the last given frequency, e.g. the "room_only" |
| 24 | +optimizer shown above will not touch the frequency response above 250Hz |
| 25 | + |
| 26 | +## Uploading data to the optimzer |
| 27 | + |
| 28 | +The optimzer tools expect a data in JSON format as follows |
| 29 | + |
| 30 | +``` |
| 31 | +{ |
| 32 | + "measurement": |
| 33 | + { |
| 34 | + "f": [ 20, 40, 80, 160, 320, 640, 1280, 2560, 5120, 10240, 20480], |
| 35 | + "db": [-25, -15, -5, 2.4, -5, 2.1, 0.5, 4.6, -2.1, -1.3, -7.0], |
| 36 | + "phase": [ 0, 0, 0.1, 0.15, 0.2, 0.25, 0.2, 0.15, 0.1, 0.05, 0.1] |
| 37 | + }, |
| 38 | + "curve": "flat", |
| 39 | + "optimizer": "smooth", |
| 40 | + "filtercount": 10, |
| 41 | + "samplerate": 48000, |
| 42 | + "settings": |
| 43 | + { |
| 44 | + "qmax": 10, |
| 45 | + "mindb": -10, |
| 46 | + "maxdb": 3, |
| 47 | + "add_highpass": true |
| 48 | + } |
| 49 | +} |
| 50 | +``` |
| 51 | + |
| 52 | +Depending on the function you are using, not all parameters may be required. You always need to send frequency (f) and decibel (db) values. |
| 53 | +The JSON data will just uses as a command line argument to the scripts (see below) |
| 54 | + |
| 55 | +## roomeq-range |
| 56 | + |
| 57 | +Returns the usuable frequency range. "Usuable" means that the output is at least -10dB of the average value in the range between 200-8000Hz. This makes sure not to try to optimize at frequencies that speaker can't handle. |
| 58 | + |
| 59 | +Result will look like this: |
| 60 | +``` |
| 61 | +{"fmin": 20, "fmax": 20480} |
| 62 | +``` |
| 63 | + |
| 64 | + |
| 65 | +### roomeq-optimize |
| 66 | + |
| 67 | +Optimizes frequency response to match the target curve by applying equalizers. |
| 68 | + |
| 69 | +The result will look like this: |
| 70 | + |
| 71 | +``` |
| 72 | +{ |
| 73 | + "samplerate": 48000, |
| 74 | + "f_min": 80, |
| 75 | + "f_max": 20480, |
| 76 | + "error_input": 2.0523979190035857, |
| 77 | + "frequencies_full": [ |
| 78 | + 20, |
| 79 | + 40, |
| 80 | + 80, |
| 81 | + 160, |
| 82 | + 320, |
| 83 | + 640, |
| 84 | + 1280, |
| 85 | + 2560, |
| 86 | + 5120, |
| 87 | + 10240, |
| 88 | + 20480 |
| 89 | + ], |
| 90 | + "response_normalized_full": [ |
| 91 | + -25.02, |
| 92 | + -15.02, |
| 93 | + -5.02, |
| 94 | + 2.38, |
| 95 | + -5.02, |
| 96 | + 2.08, |
| 97 | + 0.4800000000000001, |
| 98 | + 4.58, |
| 99 | + -2.12, |
| 100 | + -1.32, |
| 101 | + -7.02 |
| 102 | + ], |
| 103 | + "response_optimize_range": [ |
| 104 | + -5.02, |
| 105 | + 2.38, |
| 106 | + -5.02, |
| 107 | + 2.08, |
| 108 | + 0.4800000000000001, |
| 109 | + 4.58, |
| 110 | + -2.12, |
| 111 | + -1.32 |
| 112 | + ], |
| 113 | + "frequencies": [ |
| 114 | + 80, |
| 115 | + 160, |
| 116 | + 320, |
| 117 | + 640, |
| 118 | + 1280, |
| 119 | + 2560, |
| 120 | + 5120, |
| 121 | + 10240 |
| 122 | + ], |
| 123 | + "target_curve": [ |
| 124 | + -7.4999999999999964, |
| 125 | + 0.0, |
| 126 | + 0.0, |
| 127 | + 0.0, |
| 128 | + 0.0, |
| 129 | + 0.0, |
| 130 | + 0.0, |
| 131 | + 0.0 |
| 132 | + ], |
| 133 | + "target_weights": [ |
| 134 | + [ |
| 135 | + 1, |
| 136 | + 0.5 |
| 137 | + ], |
| 138 | + [ |
| 139 | + 1, |
| 140 | + 1 |
| 141 | + ], |
| 142 | + [ |
| 143 | + 1, |
| 144 | + 1 |
| 145 | + ], |
| 146 | + [ |
| 147 | + 1, |
| 148 | + 1 |
| 149 | + ], |
| 150 | + [ |
| 151 | + 1, |
| 152 | + 1 |
| 153 | + ], |
| 154 | + [ |
| 155 | + 1, |
| 156 | + 1 |
| 157 | + ], |
| 158 | + [ |
| 159 | + 1, |
| 160 | + 1 |
| 161 | + ], |
| 162 | + [ |
| 163 | + 1, |
| 164 | + 1 |
| 165 | + ] |
| 166 | + ], |
| 167 | + "correction_curve": [ |
| 168 | + -9.897985643870312, |
| 169 | + -3.5943769392580585, |
| 170 | + 4.0282395594494504, |
| 171 | + -2.3451890631928403, |
| 172 | + -0.10399883187746006, |
| 173 | + -4.097423887314459, |
| 174 | + 1.158949800292876, |
| 175 | + 1.7362519113401598 |
| 176 | + ], |
| 177 | + "correction_angle": [ |
| 178 | + |
| 179 | + ], |
| 180 | + "response_corrected": [ |
| 181 | + -8.897385730585672, |
| 182 | + 0.7237280685098911, |
| 183 | + -0.46532173890818523, |
| 184 | + -0.13067525446896433, |
| 185 | + 0.40970691834508327, |
| 186 | + 0.4908962879942015, |
| 187 | + -0.959086744647456, |
| 188 | + 0.41663097537377136 |
| 189 | + ], |
| 190 | + "eqs": [ |
| 191 | + { |
| 192 | + "a0": 1, |
| 193 | + "a1": -1.979164950637508, |
| 194 | + "a2": 0.9792734754579923, |
| 195 | + "b0": 0.9896096065238751, |
| 196 | + "b1": -1.9792192130477502, |
| 197 | + "b2": 0.9896096065238751, |
| 198 | + "type": "hp", |
| 199 | + "f0": 80.0, |
| 200 | + "q": 0.5, |
| 201 | + "db": null |
| 202 | + }, |
| 203 | + { |
| 204 | + "a0": 1, |
| 205 | + "a1": -1.811353369759114, |
| 206 | + "a2": 0.9180418176956454, |
| 207 | + "b0": 0.9832944696506943, |
| 208 | + "b1": -1.811353369759114, |
| 209 | + "b2": 0.9347473480449511, |
| 210 | + "type": "eq", |
| 211 | + "f0": 2560, |
| 212 | + "q": 4.999999999999999, |
| 213 | + "db": -4.5485766507754315 |
| 214 | + }, |
| 215 | + { |
| 216 | + "a0": 1, |
| 217 | + "a1": -1.9872078279457714, |
| 218 | + "a2": 0.9873167937865033, |
| 219 | + "b0": 0.99817334443985, |
| 220 | + "b1": -1.9872078279457714, |
| 221 | + "b2": 0.9891434493466532, |
| 222 | + "type": "eq", |
| 223 | + "f0": 80, |
| 224 | + "q": 0.9723036318902865, |
| 225 | + "db": -2.9509269755882244 |
| 226 | + }, |
| 227 | + { |
| 228 | + "a0": 1, |
| 229 | + "a1": -0.19788015225129915, |
| 230 | + "a2": -0.13343815087978864, |
| 231 | + "b0": 1.1267853517864534, |
| 232 | + "b1": -0.19788015225129915, |
| 233 | + "b2": -0.26022350266624217, |
| 234 | + "type": "eq", |
| 235 | + "f0": 10240, |
| 236 | + "q": 0.33643579295814874, |
| 237 | + "db": 1.7536281379290026 |
| 238 | + }, |
| 239 | + { |
| 240 | + "a0": 1, |
| 241 | + "a1": -1.99122976689195, |
| 242 | + "a2": 0.9929779471608385, |
| 243 | + "b0": 1.0014484302182394, |
| 244 | + "b1": -1.99122976689195, |
| 245 | + "b2": 0.991529516942599, |
| 246 | + "type": "eq", |
| 247 | + "f0": 320, |
| 248 | + "q": 4.999999999999999, |
| 249 | + "db": 2.9999999999999316 |
| 250 | + }, |
| 251 | + { |
| 252 | + "a0": 1, |
| 253 | + "a1": -1.9743561549472772, |
| 254 | + "a2": 0.9813048699959958, |
| 255 | + "b0": 0.9980037508983862, |
| 256 | + "b1": -1.9743561549472772, |
| 257 | + "b2": 0.9833011190976094, |
| 258 | + "type": "eq", |
| 259 | + "f0": 640, |
| 260 | + "q": 4.999999999999964, |
| 261 | + "db": -2.086668164877255 |
| 262 | + }, |
| 263 | + { |
| 264 | + "a0": 1, |
| 265 | + "a1": -1.990912309213979, |
| 266 | + "a2": 0.9926602107740726, |
| 267 | + "b0": 1.0010733564587682, |
| 268 | + "b1": -1.990912309213979, |
| 269 | + "b2": 0.9915868543153045, |
| 270 | + "type": "eq", |
| 271 | + "f0": 320, |
| 272 | + "q": 4.999999999999999, |
| 273 | + "db": 2.22845041124511 |
| 274 | + }, |
| 275 | + { |
| 276 | + "a0": 1, |
| 277 | + "a1": -1.9650962596041421, |
| 278 | + "a2": 0.9652040129870725, |
| 279 | + "b0": 0.9980547935236838, |
| 280 | + "b1": -1.9650962596041421, |
| 281 | + "b2": 0.9671492194633885, |
| 282 | + "type": "eq", |
| 283 | + "f0": 80, |
| 284 | + "q": 0.3137728334227004, |
| 285 | + "db": -1.029846904118282 |
| 286 | + }, |
| 287 | + { |
| 288 | + "a0": 1, |
| 289 | + "a1": -1.6494955634868824, |
| 290 | + "a2": 0.6553009368568666, |
| 291 | + "b0": 0.9978116307096956, |
| 292 | + "b1": -1.6494955634868824, |
| 293 | + "b2": 0.6574893061471712, |
| 294 | + "type": "eq", |
| 295 | + "f0": 640, |
| 296 | + "q": 0.20220513139405033, |
| 297 | + "db": -0.11099328071738762 |
| 298 | + }, |
| 299 | + { |
| 300 | + "a0": 1, |
| 301 | + "a1": -1.921299544544896, |
| 302 | + "a2": 0.9214048963944732, |
| 303 | + "b0": 1.000549207468468, |
| 304 | + "b1": -1.921299544544896, |
| 305 | + "b2": 0.9208556889260052, |
| 306 | + "type": "eq", |
| 307 | + "f0": 80, |
| 308 | + "q": 0.12711603312221625, |
| 309 | + "db": 0.120550219409348 |
| 310 | + } |
| 311 | + ], |
| 312 | + "eqdefinitions": [ |
| 313 | + "hp:80.0:0.5", |
| 314 | + "eq:2560:4.999999999999999:-4.5485766507754315", |
| 315 | + "eq:80:0.9723036318902865:-2.9509269755882244", |
| 316 | + "eq:10240:0.33643579295814874:1.7536281379290026", |
| 317 | + "eq:320:4.999999999999999:2.9999999999999316", |
| 318 | + "eq:640:4.999999999999964:-2.086668164877255", |
| 319 | + "eq:320:4.999999999999999:2.22845041124511", |
| 320 | + "eq:80:0.3137728334227004:-1.029846904118282", |
| 321 | + "eq:640:0.20220513139405033:-0.11099328071738762", |
| 322 | + "eq:80:0.12711603312221625:0.120550219409348" |
| 323 | + ] |
| 324 | +} |
| 325 | +``` |
| 326 | + |
| 327 | +### Examples |
| 328 | + |
| 329 | +You can run a simple test using the sample file /opt/hifiberry/contrib/frequency-demo.json: |
| 330 | +``` |
| 331 | +/opt/hifiberry/bin/roomeq-range /opt/hifiberry/contrib/frequency-demo.json |
| 332 | +/opt/hifiberry/bin/roomeq-optimize /opt/hifiberry/contrib/frequency-demo.json |
| 333 | +``` |
0 commit comments