1 /*
2 * MOC - music on console
3 * Copyright (C) 2004-2008 Damian Pietras <daper@daper.net>
4 *
5 * Equalizer-extension Copyright (C) 2008 Hendrik Iben <hiben@tzi.de>
6 * Provides a parametric biquadratic equalizer.
7 *
8 * This code is based on the 'Cookbook formulae for audio EQ biquad filter
9 * coefficients' by Robert Bristow-Johnson.
10 * http://www.musicdsp.org/files/Audio-EQ-Cookbook.txt
11 *
12 * TODO:
13 * - Merge somehow with softmixer code to avoid multiple endianness
14 * conversions.
15 * - Implement equalizer routines for integer samples... conversion
16 * to float (and back) is lazy...
17 *
18 * This program is free software; you can redistribute it and/or modify
19 * it under the terms of the GNU General Public License as published by
20 * the Free Software Foundation; either version 2 of the License, or
21 * (at your option) any later version.
22 *
23 */
24
25 #ifdef HAVE_CONFIG_H
26 #include "config.h"
27 #endif
28
29 #include <stdio.h>
30 #include <string.h>
31 #include <assert.h>
32 #include <stdint.h>
33 #include <math.h>
34 #include <stdlib.h>
35 #include <errno.h>
36 #include <sys/types.h>
37 #include <sys/stat.h>
38 #include <unistd.h>
39 #include <dirent.h>
40 #include <locale.h>
41
42 #include "common.h"
43 #include "audio.h"
44 #include "audio_conversion.h"
45 #include "options.h"
46 #include "log.h"
47 #include "files.h"
48 #include "equalizer.h"
49
50 #define TWOPI (2.0 * M_PI)
51
52 #define NEWLINE 0x0A
53 #define CRETURN 0x0D
54 #define SPACE 0x20
55
56 #define EQSET_HEADER "EQSET"
57
58 #define EQUALIZER_CFG_ACTIVE "Active:"
59 #define EQUALIZER_CFG_PRESET "Preset:"
60 #define EQUALIZER_CFG_MIXIN "Mixin:"
61
62 #define EQUALIZER_SAVE_FILE "equalizer"
63 #define EQUALIZER_SAVE_OPTION "Equalizer_SaveState"
64
65 typedef struct t_biquad t_biquad;
66
67 struct t_biquad
68 {
69 float a0, a1, a2, a3, a4;
70 float x1, x2, y1, y2;
71 float cf, bw, gain, srate;
72 int israte;
73 };
74
75 typedef struct t_eq_setup t_eq_setup;
76
77 struct t_eq_setup
78 {
79 char *name;
80 float preamp;
81 int bcount;
82 float *cf;
83 float *bw;
84 float *dg;
85 };
86
87 typedef struct t_eq_set t_eq_set;
88
89 struct t_eq_set
90 {
91 char *name;
92 int channels;
93 float preamp;
94 int bcount;
95 t_biquad *b;
96 };
97
98 typedef struct t_eq_set_list t_eq_set_list;
99
100 struct t_eq_set_list
101 {
102 t_eq_set *set;
103 t_eq_set_list *prev, *next;
104 };
105
106 typedef struct t_active_set t_active_set;
107
108 struct t_active_set
109 {
110 int srate;
111 t_eq_set *set;
112 };
113
114 typedef struct t_eq_settings t_eq_settings;
115
116 struct t_eq_settings
117 {
118 char *preset_name;
119 int bcount;
120 float *gain;
121 t_eq_settings *next;
122 };
123
124 /* config processing */
125 static char *skip_line(char *s);
126 static char *skip_whitespace(char *s);
127 static int read_float(char *s, float *f, char **endp);
128 static int read_setup(char *name, char *desc, t_eq_setup **sp);
129 static void equalizer_adjust_preamp();
130 static void equalizer_read_config();
131 static void equalizer_write_config();
132
133 /* biquad application */
134 static inline void apply_biquads(float *src, float *dst, int channels, int len, t_biquad *b, int blen);
135
136 /* biquad filter creation */
137 static t_biquad *mk_biquad(float dbgain, float cf, float srate, float bw, t_biquad *b);
138
139 /* equalizer list processing */
140 static t_eq_set_list *append_eq_set(t_eq_set *eqs, t_eq_set_list *l);
141 static void clear_eq_set(t_eq_set_list *l);
142
143 /* sound processing */
144 static void equ_process_buffer_u8(uint8_t *buf, size_t size);
145 static void equ_process_buffer_s8(int8_t *buf, size_t size);
146 static void equ_process_buffer_u16(uint16_t *buf, size_t size);
147 static void equ_process_buffer_s16(int16_t *buf, size_t size);
148 static void equ_process_buffer_u32(uint32_t *buf, size_t size);
149 static void equ_process_buffer_s32(int32_t *buf, size_t size);
150 static void equ_process_buffer_float(float *buf, size_t size);
151
152 /* static global variables */
153 static t_eq_set_list equ_list, *current_equ;
154
155 static int sample_rate, equ_active, equ_channels;
156
157 static float mixin_rate, r_mixin_rate;
158 static float preamp, preampf;
159
160 static char *eqsetdir;
161
162 static char *config_preset_name;
163
164 /* public functions */
equalizer_is_active()165 int equalizer_is_active()
166 {
167 return equ_active?1:0;
168 }
169
equalizer_set_active(int active)170 int equalizer_set_active(int active)
171 {
172 return equ_active = active?1:0;
173 }
174
equalizer_current_eqname()175 char *equalizer_current_eqname()
176 {
177 if(equ_active && current_equ && current_equ->set)
178 {
179 return xstrdup(current_equ->set->name);
180 }
181
182 return xstrdup("off");
183 }
184
equalizer_next()185 void equalizer_next()
186 {
187 if(current_equ)
188 {
189 if(current_equ->next)
190 {
191 current_equ = current_equ->next;
192 }
193 else
194 {
195 current_equ = &equ_list;
196 }
197
198 if(!current_equ->set && !(current_equ == &equ_list && !current_equ->next))
199 equalizer_next();
200 }
201
202 equalizer_adjust_preamp();
203 }
204
equalizer_prev()205 void equalizer_prev()
206 {
207 if(current_equ)
208 {
209 if(current_equ->prev)
210 {
211 current_equ = current_equ->prev;
212 }
213 else
214 {
215 while(current_equ->next)
216 current_equ = current_equ->next;
217 }
218
219 if(!current_equ->set && !(current_equ == &equ_list && !current_equ->next))
220 equalizer_prev();
221 }
222
223 equalizer_adjust_preamp();
224 }
225
226 /* biquad functions */
227
228 /* Create a Peaking EQ Filter.
229 * See 'Audio EQ Cookbook' for more information
230 */
mk_biquad(float dbgain,float cf,float srate,float bw,t_biquad * b)231 static t_biquad *mk_biquad(float dbgain, float cf, float srate, float bw, t_biquad *b)
232 {
233 if(b==NULL)
234 b = (t_biquad *)xmalloc(sizeof(t_biquad));
235
236 float A = powf(10.0f, dbgain / 40.0f);
237 float omega = TWOPI * cf / srate;
238 float sn = sin(omega);
239 float cs = cos(omega);
240 float alpha = sn * sinh(M_LN2 / 2.0f * bw * omega / sn);
241
242 float alpha_m_A = alpha * A;
243 float alpha_d_A = alpha / A;
244
245 float b0 = 1.0f + alpha_m_A;
246 float b1 = -2.0f * cs;
247 float b2 = 1.0f - alpha_m_A;
248 float a0 = 1.0f + alpha_d_A;
249 float a1 = b1;
250 float a2 = 1.0f - alpha_d_A;
251
252 b->a0 = b0 / a0;
253 b->a1 = b1 / a0;
254 b->a2 = b2 / a0;
255 b->a3 = a1 / a0;
256 b->a4 = a2 / a0;
257
258 b->x1 = 0.0f;
259 b->x2 = 0.0f;
260 b->y1 = 0.0f;
261 b->y2 = 0.0f;
262
263 b->cf = cf;
264 b->bw = bw;
265 b->srate = srate;
266 b->israte = (int)srate;
267 b->gain = dbgain;
268
269 return b;
270 };
271
272 /*
273 * not used but keep as example use for biquad filter
274 static inline void biquad(float *src, float *dst, int len, t_biquad *b)
275 {
276 while(len-->0)
277 {
278 float s = *src++;
279 float f = s * b->a0 + b->a1 * b->x1 + b->a2 * b->x2 - b->a3 * b->y1 - b->a4 * b->y2;
280 *dst++=f;
281 b->x2 = b->x1;
282 b->x1 = s;
283 b->y2 = b->y1;
284 b->y1 = f;
285 }
286
287 };
288 */
289
290 /* Applies a set of biquadratic filters to a buffer of floating point
291 * samples.
292 * It is safe to have the same input and output buffer.
293 *
294 * blen is the sample-count ignoring channels (samples per channel * channels)
295 */
apply_biquads(float * src,float * dst,int channels,int len,t_biquad * b,int blen)296 static inline void apply_biquads(float *src, float *dst, int channels, int len, t_biquad *b, int blen)
297 {
298 int bi, ci, boffs, idx;
299 while(len>0)
300 {
301 boffs = 0;
302 for(ci=0; ci<channels; ci++)
303 {
304 float s = *src++;
305 float f = s;
306 for(bi=0; bi<blen; bi++)
307 {
308 idx = boffs + bi;
309 f =
310 s * b[idx].a0 \
311 + b[idx].a1 * b[idx].x1 \
312 + b[idx].a2 * b[idx].x2 \
313 - b[idx].a3 * b[idx].y1 \
314 - b[idx].a4 * b[idx].y2;
315 b[idx].x2 = b[idx].x1;
316 b[idx].x1 = s;
317 b[idx].y2 = b[idx].y1;
318 b[idx].y1 = f;
319 s = f;
320 }
321 *dst++=f;
322 boffs += blen;
323 len--;
324 };
325 };
326 };
327
328 /*
329 preamping
330 XMMS / Beep Media Player / Audacious use all the same code but
331 do something I do not understand for preamping...
332
333 actually preamping by X dB should be like
334 sample * 10^(X/20)
335
336 they do:
337 sample * (( 1.0 + 0.0932471 * X + 0.00279033 * X^2 ) / 2)
338
339 what are these constants ?
340 the equations are not even close to each other in their results...
341 - hiben
342 */
equalizer_adjust_preamp()343 static void equalizer_adjust_preamp()
344 {
345 if(current_equ && current_equ->set)
346 {
347 preamp = current_equ->set->preamp;
348 preampf = powf(10.0f, current_equ->set->preamp / 20.0f);
349 }
350 }
351
equalizer_read_config()352 static void equalizer_read_config()
353 {
354 char *curloc = xstrdup(setlocale(LC_NUMERIC, NULL));
355 setlocale(LC_NUMERIC, "C"); // posix decimal point
356
357 char *sfile = xstrdup(create_file_name("equalizer"));
358
359 FILE *cf = fopen(sfile, "r");
360
361 free (sfile);
362
363 if(cf==NULL)
364 {
365 logit ("Unable to read equalizer configuration");
366 if (curloc)
367 free (curloc);
368 return;
369 }
370
371 char *linebuffer = NULL;
372 char presetbuf[128];
373 presetbuf[0] = 0;
374
375 int tmp;
376 float ftmp;
377
378 while((linebuffer=read_line(cf)))
379 {
380 if(
381 strncasecmp
382 (
383 linebuffer
384 , EQUALIZER_CFG_ACTIVE
385 , strlen(EQUALIZER_CFG_ACTIVE)
386 ) == 0
387 )
388 {
389 if(sscanf(linebuffer, "%*s %i", &tmp)>0)
390 {
391 if(tmp>0)
392 {
393 equ_active = 1;
394 }
395 else
396 {
397 equ_active = 0;
398 }
399 }
400 }
401 if(
402 strncasecmp
403 (
404 linebuffer
405 , EQUALIZER_CFG_MIXIN
406 , strlen(EQUALIZER_CFG_MIXIN)
407 ) == 0
408 )
409 {
410 if(sscanf(linebuffer, "%*s %f", &ftmp)>0)
411 {
412 if(RANGE(0.0f, ftmp, 1.0f))
413 {
414 mixin_rate = ftmp;
415 }
416 }
417 }
418 if(
419 strncasecmp
420 (
421 linebuffer
422 , EQUALIZER_CFG_PRESET
423 , strlen(EQUALIZER_CFG_PRESET)
424 ) == 0
425 )
426 {
427 if(sscanf(linebuffer, "%*s %127s", presetbuf)>0)
428 {
429 /* ignore too large strings... */
430 if(strlen(presetbuf)<127)
431 {
432 if(config_preset_name)
433 free(config_preset_name);
434 config_preset_name = xstrdup(presetbuf);
435 }
436 }
437 }
438 free(linebuffer);
439 }
440
441 fclose(cf);
442
443 if (curloc) {
444 setlocale(LC_NUMERIC, curloc);
445 free (curloc);
446 }
447 }
448
equalizer_write_config()449 static void equalizer_write_config()
450 {
451 char *curloc = xstrdup(setlocale(LC_NUMERIC, NULL));
452 setlocale(LC_NUMERIC, "C"); /* posix decimal point */
453
454 char *cfname = create_file_name(EQUALIZER_SAVE_FILE);
455
456 FILE *cf = fopen(cfname, "w");
457
458 if(cf==NULL)
459 {
460 logit ("Unable to write equalizer configuration");
461 if (curloc)
462 free (curloc);
463 return;
464 }
465
466 fprintf(cf, "%s %i\n", EQUALIZER_CFG_ACTIVE, equ_active);
467 if(current_equ && current_equ->set)
468 fprintf(cf, "%s %s\n", EQUALIZER_CFG_PRESET, current_equ->set->name);
469 fprintf(cf, "%s %f\n", EQUALIZER_CFG_MIXIN, mixin_rate);
470
471 fclose(cf);
472
473 if (curloc) {
474 setlocale(LC_NUMERIC, curloc);
475 free (curloc);
476 }
477
478 logit ("Equalizer configuration written");
479 }
480
equalizer_init()481 void equalizer_init()
482 {
483 equ_active = 1;
484
485 equ_list.set = NULL;
486 equ_list.next = NULL;
487 equ_list.prev = NULL;
488
489 sample_rate = 44100;
490
491 equ_channels = 2;
492
493 preamp = 0.0f;
494
495 preampf = powf(10.0f, preamp / 20.0f);
496
497 eqsetdir = xstrdup(create_file_name("eqsets"));
498
499 config_preset_name = NULL;
500
501 mixin_rate = 0.25f;
502
503 equalizer_read_config();
504
505 r_mixin_rate = 1.0f - mixin_rate;
506
507 equalizer_refresh();
508
509 logit ("Equalizer initialized");
510 }
511
equalizer_shutdown()512 void equalizer_shutdown()
513 {
514 if(options_get_int(EQUALIZER_SAVE_OPTION))
515 equalizer_write_config();
516
517 clear_eq_set(&equ_list);
518
519 logit ("Equalizer stopped");
520 }
521
equalizer_refresh()522 void equalizer_refresh()
523 {
524 t_eq_setup *eqs = NULL;
525 char buf[1024];
526
527 char *current_set_name = NULL;
528
529 if(current_equ && current_equ->set)
530 {
531 current_set_name = xstrdup(current_equ->set->name);
532 }
533 else
534 {
535 if(config_preset_name)
536 current_set_name = xstrdup(config_preset_name);
537 }
538
539 clear_eq_set(&equ_list);
540
541 current_equ = NULL;
542
543 DIR *d = opendir(eqsetdir);
544
545 if(!d)
546 {
547 return;
548 }
549
550 struct dirent *de = readdir(d);
551 struct stat st;
552
553 t_eq_set_list *last_elem;
554
555 last_elem = &equ_list;
556
557 while(de)
558 {
559 sprintf(buf, "eqsets/%s", de->d_name);
560
561 char *filename = xstrdup(create_file_name(buf));
562
563 stat(filename, &st);
564
565 if( S_ISREG(st.st_mode) )
566 {
567 FILE *f = fopen(filename, "r");
568
569 if(f)
570 {
571 char filebuffer[4096];
572
573 char *fb = filebuffer;
574
575 int maxread = 4095 - (fb - filebuffer);
576
577 // read in whole file
578 while(!feof(f) && maxread>0)
579 {
580 maxread = 4095 - (fb - filebuffer);
581 int rb = fread(fb, sizeof(char), maxread, f);
582 fb+=rb;
583 }
584
585 fclose(f);
586
587 *fb = 0;
588 int r = read_setup(de->d_name, filebuffer, &eqs);
589
590 if(r==0)
591 {
592 int i, channel;
593 t_eq_set *eqset = (t_eq_set *)xmalloc(sizeof(t_eq_set));
594 eqset->b = (t_biquad *)xmalloc(sizeof(t_biquad)*eqs->bcount*equ_channels);
595
596 eqset->name = xstrdup(eqs->name);
597 eqset->preamp = eqs->preamp;
598 eqset->bcount = eqs->bcount;
599 eqset->channels = equ_channels;
600
601 for(i=0; i<eqs->bcount; i++)
602 {
603 mk_biquad(eqs->dg[i], eqs->cf[i], sample_rate, eqs->bw[i], &eqset->b[i]);
604
605 for(channel=1; channel<equ_channels; channel++)
606 {
607 eqset->b[channel*eqset->bcount + i] = eqset->b[i];
608 }
609 }
610
611 last_elem = append_eq_set(eqset, last_elem);
612
613 free(eqs->name);
614 free(eqs->cf);
615 free(eqs->bw);
616 free(eqs->dg);
617
618 }
619 else
620 {
621 switch(r)
622 {
623 case 0:
624 logit ("This should not happen: No error but no EQSET was parsed: %s", filename);
625 break;
626 case -1:
627 logit ("Not an EQSET (empty file): %s", filename);
628 break;
629 case -2:
630 logit ("Not an EQSET (invalid header): %s", filename);
631 break;
632 case -3:
633 logit ("Error while parsing settings from EQSET: %s", filename);
634 break;
635 default:
636 logit ("Unknown error while parsing EQSET: %s", filename);
637 break;
638 }
639 }
640
641 if(eqs)
642 free(eqs);
643
644 eqs = NULL;
645 }
646 }
647
648 free(filename);
649
650 de = readdir(d);
651 }
652
653 closedir(d);
654
655 current_equ = &equ_list;
656
657 if(current_set_name)
658 {
659 current_equ = &equ_list;
660
661 while(current_equ)
662 {
663 if(current_equ->set)
664 {
665 if(strcmp(current_set_name, current_equ->set->name)==0)
666 break;
667 }
668 current_equ = current_equ->next;
669 }
670
671 if(current_equ)
672 {
673 // only free name when EQ was found to allow logging
674 free(current_set_name);
675 }
676 }
677
678 if (!current_equ && current_set_name)
679 {
680 logit ("EQ %s not found.", current_set_name);
681 /* equalizer not found, pick next equalizer */
682 current_equ = &equ_list;
683 // free name now
684 free(current_set_name);
685 }
686 if(current_equ && !current_equ->set)
687 equalizer_next();
688
689 equalizer_adjust_preamp();
690 }
691
692 /* sound processing code */
equalizer_process_buffer(char * buf,size_t size,const struct sound_params * sound_params)693 void equalizer_process_buffer(char *buf, size_t size, const struct sound_params *sound_params)
694 {
695 debug ("EQ Processing %zu bytes...", size);
696
697 if(!equ_active || !current_equ || !current_equ->set)
698 return;
699
700 if(sound_params->rate != current_equ->set->b->israte || sound_params->channels != equ_channels)
701 {
702 logit ("Recreating filters due to sound parameter changes...");
703 sample_rate = sound_params->rate;
704 equ_channels = sound_params->channels;
705
706 equalizer_refresh();
707 }
708
709 long sound_endianness = sound_params->fmt & SFMT_MASK_ENDIANNESS;
710 long sound_format = sound_params->fmt & SFMT_MASK_FORMAT;
711
712 int samplesize = sfmt_Bps(sound_format);
713 int is_float = (sound_params->fmt & SFMT_MASK_FORMAT) == SFMT_FLOAT;
714
715 int need_endianness_swap = 0;
716
717 if((sound_endianness != SFMT_NE) && (samplesize > 1) && (!is_float))
718 {
719 need_endianness_swap = 1;
720 }
721
722 assert (size % (samplesize * sound_params->channels) == 0);
723
724 /* setup samples to perform arithmetic */
725 if(need_endianness_swap)
726 {
727 debug ("Converting endianness before mixing");
728 if(samplesize == 4)
729 audio_conv_bswap_32((int32_t *)buf, size / sizeof(int32_t));
730 else
731 audio_conv_bswap_16((int16_t *)buf, size / sizeof(int16_t));
732 }
733
734 switch(sound_format)
735 {
736 case SFMT_U8:
737 equ_process_buffer_u8((uint8_t *)buf, size);
738 break;
739 case SFMT_S8:
740 equ_process_buffer_s8((int8_t *)buf, size);
741 break;
742 case SFMT_U16:
743 equ_process_buffer_u16((uint16_t *)buf, size / sizeof(uint16_t));
744 break;
745 case SFMT_S16:
746 equ_process_buffer_s16((int16_t *)buf, size / sizeof(int16_t));
747 break;
748 case SFMT_U32:
749 equ_process_buffer_u32((uint32_t *)buf, size / sizeof(uint32_t));
750 break;
751 case SFMT_S32:
752 equ_process_buffer_s32((int32_t *)buf, size / sizeof(int32_t));
753 break;
754 case SFMT_FLOAT:
755 equ_process_buffer_float((float *)buf, size / sizeof(float));
756 break;
757 }
758
759 /* restore sample-endianness */
760 if(need_endianness_swap)
761 {
762 debug ("Restoring endianness after mixing");
763 if(samplesize == 4)
764 audio_conv_bswap_32((int32_t *)buf, size / sizeof(int32_t));
765 else
766 audio_conv_bswap_16((int16_t *)buf, size / sizeof(int16_t));
767 }
768 }
769
equ_process_buffer_u8(uint8_t * buf,size_t size)770 static void equ_process_buffer_u8(uint8_t *buf, size_t size)
771 {
772 size_t i;
773 float *tmp;
774
775 debug ("equalizing");
776
777 tmp = (float *)xmalloc (size * sizeof (float));
778
779 for(i=0; i<size; i++)
780 tmp[i] = preampf * (float)buf[i];
781
782 apply_biquads(tmp, tmp, equ_channels, size, current_equ->set->b, current_equ->set->bcount);
783
784 for(i=0; i<size; i++)
785 {
786 tmp[i] = r_mixin_rate * tmp[i] + mixin_rate * buf[i];
787 tmp[i] = CLAMP(0, tmp[i], UINT8_MAX);
788 buf[i] = (uint8_t)tmp[i];
789 }
790
791 free(tmp);
792 }
793
equ_process_buffer_s8(int8_t * buf,size_t size)794 static void equ_process_buffer_s8(int8_t *buf, size_t size)
795 {
796 size_t i;
797 float *tmp;
798
799 debug ("equalizing");
800
801 tmp = (float *)xmalloc (size * sizeof (float));
802
803 for(i=0; i<size; i++)
804 tmp[i] = preampf * (float)buf[i];
805
806 apply_biquads(tmp, tmp, equ_channels, size, current_equ->set->b, current_equ->set->bcount);
807
808 for(i=0; i<size; i++)
809 {
810 tmp[i] = r_mixin_rate * tmp[i] + mixin_rate * buf[i];
811 tmp[i] = CLAMP(INT8_MIN, tmp[i], INT8_MAX);
812 buf[i] = (int8_t)tmp[i];
813 }
814
815 free(tmp);
816 }
817
equ_process_buffer_u16(uint16_t * buf,size_t size)818 static void equ_process_buffer_u16(uint16_t *buf, size_t size)
819 {
820 size_t i;
821 float *tmp;
822
823 debug ("equalizing");
824
825 tmp = (float *)xmalloc (size * sizeof (float));
826
827 for(i=0; i<size; i++)
828 tmp[i] = preampf * (float)buf[i];
829
830 apply_biquads(tmp, tmp, equ_channels, size, current_equ->set->b, current_equ->set->bcount);
831
832 for(i=0; i<size; i++)
833 {
834 tmp[i] = r_mixin_rate * tmp[i] + mixin_rate * buf[i];
835 tmp[i] = CLAMP(0, tmp[i], UINT16_MAX);
836 buf[i] = (uint16_t)tmp[i];
837 }
838
839 free(tmp);
840 }
841
equ_process_buffer_s16(int16_t * buf,size_t size)842 static void equ_process_buffer_s16(int16_t *buf, size_t size)
843 {
844 size_t i;
845 float *tmp;
846
847 debug ("equalizing");
848
849 tmp = (float *)xmalloc (size * sizeof (float));
850
851 for(i=0; i<size; i++)
852 tmp[i] = preampf * (float)buf[i];
853
854 apply_biquads(tmp, tmp, equ_channels, size, current_equ->set->b, current_equ->set->bcount);
855
856 for(i=0; i<size; i++)
857 {
858 tmp[i] = r_mixin_rate * tmp[i] + mixin_rate * buf[i];
859 tmp[i] = CLAMP(INT16_MIN, tmp[i], INT16_MAX);
860 buf[i] = (int16_t)tmp[i];
861 }
862
863 free(tmp);
864 }
865
equ_process_buffer_u32(uint32_t * buf,size_t size)866 static void equ_process_buffer_u32(uint32_t *buf, size_t size)
867 {
868 size_t i;
869 float *tmp;
870
871 debug ("equalizing");
872
873 tmp = (float *)xmalloc (size * sizeof (float));
874
875 for(i=0; i<size; i++)
876 tmp[i] = preampf * (float)buf[i];
877
878 apply_biquads(tmp, tmp, equ_channels, size, current_equ->set->b, current_equ->set->bcount);
879
880 for(i=0; i<size; i++)
881 {
882 tmp[i] = r_mixin_rate * tmp[i] + mixin_rate * buf[i];
883 tmp[i] = CLAMP(0, tmp[i], UINT32_MAX);
884 buf[i] = (uint32_t)tmp[i];
885 }
886
887 free(tmp);
888 }
889
equ_process_buffer_s32(int32_t * buf,size_t size)890 static void equ_process_buffer_s32(int32_t *buf, size_t size)
891 {
892 size_t i;
893 float *tmp;
894
895 debug ("equalizing");
896
897 tmp = (float *)xmalloc (size * sizeof (float));
898
899 for(i=0; i<size; i++)
900 tmp[i] = preampf * (float)buf[i];
901
902 apply_biquads(tmp, tmp, equ_channels, size, current_equ->set->b, current_equ->set->bcount);
903
904 for(i=0; i<size; i++)
905 {
906 tmp[i] = r_mixin_rate * tmp[i] + mixin_rate * buf[i];
907 tmp[i] = CLAMP(INT32_MIN, tmp[i], INT32_MAX);
908 buf[i] = (int32_t)tmp[i];
909 }
910
911 free(tmp);
912 }
913
equ_process_buffer_float(float * buf,size_t size)914 static void equ_process_buffer_float(float *buf, size_t size)
915 {
916 size_t i;
917 float *tmp;
918
919 debug ("equalizing");
920
921 tmp = (float *)xmalloc (size * sizeof (float));
922
923 for(i=0; i<size; i++)
924 tmp[i] = preampf * (float)buf[i];
925
926 apply_biquads(tmp, tmp, equ_channels, size, current_equ->set->b, current_equ->set->bcount);
927
928 for(i=0; i<size; i++)
929 {
930 tmp[i] = r_mixin_rate * tmp[i] + mixin_rate * buf[i];
931 tmp[i] = CLAMP(-1.0f, tmp[i], 1.0f);
932 buf[i] = tmp[i];
933 }
934
935 free(tmp);
936 }
937
938 /* equalizer list maintenance */
append_eq_set(t_eq_set * eqs,t_eq_set_list * l)939 static t_eq_set_list *append_eq_set(t_eq_set *eqs, t_eq_set_list *l)
940 {
941 if(l->set == NULL)
942 {
943 l->set = eqs;
944 }
945 else
946 {
947 if(l->next)
948 {
949 append_eq_set(eqs, l->next);
950 }
951 else
952 {
953 l->next = (t_eq_set_list *)xmalloc(sizeof(t_eq_set_list));
954 l->next->set = NULL;
955 l->next->next = NULL;
956 l->next->prev = l;
957 l = append_eq_set(eqs, l->next);
958 }
959 };
960
961 return l;
962 };
963
clear_eq_set(t_eq_set_list * l)964 static void clear_eq_set(t_eq_set_list *l)
965 {
966 if(l->set)
967 {
968 free(l->set->name);
969 free(l->set->b);
970 free(l->set);
971 l->set = NULL;
972 }
973 if(l->next)
974 {
975 clear_eq_set(l->next);
976 free(l->next);
977 l->next = NULL;
978 }
979 };
980
981 /* parsing stuff */
read_setup(char * name,char * desc,t_eq_setup ** sp)982 static int read_setup(char *name, char *desc, t_eq_setup **sp)
983 {
984 char *curloc = xstrdup(setlocale(LC_NUMERIC, NULL));
985 setlocale(LC_NUMERIC, "C"); // posix decimal point
986
987 t_eq_setup *s = *sp;
988
989 desc = skip_whitespace(desc);
990
991 if(!*desc)
992 {
993 if (curloc)
994 free (curloc);
995 return -1;
996 }
997
998 if(strncasecmp(desc, EQSET_HEADER, sizeof(EQSET_HEADER)-1))
999 {
1000 if (curloc)
1001 free (curloc);
1002 return -2;
1003 }
1004
1005 desc+=5;
1006
1007 desc = skip_whitespace(skip_line(desc));
1008
1009 if(s==NULL)
1010 {
1011 s=(t_eq_setup *)xmalloc(sizeof(t_eq_setup));
1012 *sp = s;
1013 }
1014
1015 s->name = xstrdup(name);
1016 s->bcount = 0;
1017 s->preamp = 0.0f;
1018 int max_values = 16;
1019 s->cf = (float *)xmalloc(max_values*sizeof(float));
1020 s->bw = (float *)xmalloc(max_values*sizeof(float));
1021 s->dg = (float *)xmalloc(max_values*sizeof(float));
1022
1023 int r;
1024
1025 while(*desc)
1026 {
1027 char *endp;
1028
1029 float cf = 0.0f;
1030
1031 r = read_float(desc, &cf, &endp);
1032
1033 if(r!=0)
1034 {
1035 free(s->name);
1036 free(s->cf);
1037 free(s->bw);
1038 free(s->dg);
1039 if (curloc)
1040 free (curloc);
1041 return -3;
1042 }
1043
1044 desc = skip_whitespace(endp);
1045
1046 float bw = 0.0f;
1047
1048 r = read_float(desc, &bw, &endp);
1049
1050 if(r!=0)
1051 {
1052 free(s->name);
1053 free(s->cf);
1054 free(s->bw);
1055 free(s->dg);
1056 if (curloc)
1057 free (curloc);
1058 return -3;
1059 }
1060
1061 desc = skip_whitespace(endp);
1062
1063 float dg = 0.0f;
1064
1065 /* 0Hz means preamp, only one parameter then */
1066 if(cf!=0.0f)
1067 {
1068 r = read_float(desc, &dg, &endp);
1069
1070 if(r!=0)
1071 {
1072 free(s->name);
1073 free(s->cf);
1074 free(s->bw);
1075 free(s->dg);
1076 if (curloc)
1077 free (curloc);
1078 return -3;
1079 }
1080
1081 desc = skip_whitespace(endp);
1082
1083 if(s->bcount>=(max_values-1))
1084 {
1085 max_values*=2;
1086 s->cf=xrealloc(s->cf, max_values*sizeof(float));
1087 s->bw=xrealloc(s->bw, max_values*sizeof(float));
1088 s->dg=xrealloc(s->dg, max_values*sizeof(float));
1089 }
1090
1091 s->cf[s->bcount]=cf;
1092 s->bw[s->bcount]=bw;
1093 s->dg[s->bcount]=dg;
1094
1095 s->bcount++;
1096 }
1097 else
1098 {
1099 s->preamp = bw;
1100 }
1101 }
1102
1103 if (curloc) {
1104 setlocale(LC_NUMERIC, curloc); // posix decimal point
1105 free (curloc);
1106 }
1107
1108 return 0;
1109 }
1110
skip_line(char * s)1111 static char *skip_line(char *s)
1112 {
1113 int dos_line = 0;
1114 while(*s && (*s!=CRETURN && *s!=NEWLINE) )
1115 s++;
1116
1117 if(*s==CRETURN)
1118 dos_line = 1;
1119
1120 if(*s)
1121 s++;
1122
1123 if(dos_line && *s==NEWLINE)
1124 s++;
1125
1126 return s;
1127 }
1128
skip_whitespace(char * s)1129 static char *skip_whitespace(char *s)
1130 {
1131 while(*s && (*s<=SPACE))
1132 s++;
1133
1134 if(!*s)
1135 return s;
1136
1137 if(*s=='#')
1138 {
1139 s = skip_line(s);
1140
1141 s = skip_whitespace(s);
1142 }
1143
1144 return s;
1145 }
1146
read_float(char * s,float * f,char ** endp)1147 static int read_float(char *s, float *f, char **endp)
1148 {
1149 errno = 0;
1150
1151 float t = strtof(s, endp);
1152
1153 if(errno==ERANGE)
1154 return -1;
1155
1156 if(*endp == s)
1157 return -2;
1158
1159 *f = t;
1160
1161 return 0;
1162 };
1163