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