Mercurial > mplayer.hg
annotate libaf/af_volume.c @ 7789:17956aff04e1
bypass palette from bih, when codec cannot give it in o_bih
author | arpi |
---|---|
date | Sat, 19 Oct 2002 00:57:44 +0000 |
parents | 1d3a3dc1f488 |
children | db1f16543379 |
rev | line source |
---|---|
7745
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
1 /* This audio filter changes the volume of the sound, and can be used |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
2 when the mixer doesn't support the PCM channel. It can handel |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
3 between 1 and 6 channels. The volume can be adjusted between -60dB |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
4 to +10dB and is set on a per channels basis. The volume can be |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
5 written ad read by AF_CONTROL_VOLUME_SET and AF_CONTROL_VOLUME_GET |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
6 respectivly. |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
7 |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
8 The plugin has support for softclipping, it is enabled by |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
9 AF_CONTROL_VOLUME_SOFTCLIPP. It has also a probing feature which |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
10 can be used to measure the power in the audio stream, both an |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
11 instantanious value and the maximum value can be probed. The |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
12 probing is enable by AF_CONTROL_VOLUME_PROBE_ON_OFF and is done on a |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
13 per channel basis. The result from the probing is obtained using |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
14 AF_CONTROL_VOLUME_PROBE_GET and AF_CONTROL_VOLUME_PROBE_GET_MAX. The |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
15 probed values are calculated in dB. The control of the volume can |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
16 be turned off by the AF_CONTROL_VOLUME_ON_OFF switch. |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
17 */ |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
18 |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
19 #include <stdio.h> |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
20 #include <stdlib.h> |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
21 |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
22 #include <unistd.h> |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
23 #include <inttypes.h> |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
24 #include <math.h> |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
25 |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
26 #include "../config.h" |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
27 #include "../mp_msg.h" |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
28 |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
29 #include "af.h" |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
30 |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
31 // Some limits |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
32 #define MIN_S16 -32650 |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
33 #define MAX_S16 32650 |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
34 |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
35 #define MAX_VOL +10.0 |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
36 #define MIN_VOL -60.0 |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
37 |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
38 // Number of channels |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
39 #define NCH 6 |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
40 |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
41 #include "../libao2/afmt.h" |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
42 |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
43 |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
44 // Data for specific instances of this filter |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
45 typedef struct af_volume_s |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
46 { |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
47 double volume[NCH]; // Volume for each channel |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
48 double power[NCH]; // Instantaneous power in each channel |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
49 double maxpower[NCH]; // Maximum power in each channel |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
50 double alpha; // Forgetting factor for power estimate |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
51 int softclip; // Soft clippng on/off |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
52 int probe; // Probing on/off |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
53 int onoff; // Volume control on/off |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
54 }af_volume_t; |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
55 |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
56 /* Convert to gain value from dB. Returns AF_OK if of and AF_ERROR if |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
57 fail */ |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
58 inline int from_dB(double* in, double* out) |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
59 { |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
60 int i = 0; |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
61 // Sanity check |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
62 if(!in || !out) |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
63 return AF_ERROR; |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
64 |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
65 for(i=0;i<NCH;i++) |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
66 out[i]=pow(10.0,clamp(in[i],MIN_VOL,MAX_VOL)/10.0); |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
67 return AF_OK; |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
68 } |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
69 |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
70 /* Convert from gain value to dB. Returns AF_OK if of and AF_ERROR if |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
71 fail */ |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
72 inline int to_dB(double* in, double* out) |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
73 { |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
74 int i = 0; |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
75 // Sanity check |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
76 if(!in || !out) |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
77 return AF_ERROR; |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
78 |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
79 for(i=0;i<NCH;i++) |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
80 out[i]=10.0*log10(clamp(in[i],MIN_VOL,MAX_VOL)); |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
81 return AF_OK; |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
82 } |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
83 |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
84 // Initialization and runtime control |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
85 static int control(struct af_instance_s* af, int cmd, void* arg) |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
86 { |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
87 af_volume_t* s = (af_volume_t*)af->setup; |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
88 |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
89 switch(cmd){ |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
90 case AF_CONTROL_REINIT: |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
91 // Sanity check |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
92 if(!arg) return AF_ERROR; |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
93 |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
94 af->data->rate = ((af_data_t*)arg)->rate; |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
95 af->data->nch = ((af_data_t*)arg)->nch; |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
96 af->data->format = AFMT_S16_LE; |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
97 af->data->bps = 2; |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
98 |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
99 // Time constant set to 0.1s |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
100 s->alpha = (1.0/0.2)/(2.0*M_PI*(double)((af_data_t*)arg)->rate); |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
101 |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
102 // Only AFMT_S16_LE is supported for now |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
103 if(af->data->format != ((af_data_t*)arg)->format || |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
104 af->data->bps != ((af_data_t*)arg)->bps) |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
105 return AF_FALSE; |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
106 return AF_OK; |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
107 case AF_CONTROL_VOLUME_SET: |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
108 return from_dB((double*)arg,s->volume); |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
109 case AF_CONTROL_VOLUME_GET: |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
110 return to_dB(s->volume,(double*)arg); |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
111 case AF_CONTROL_VOLUME_PROBE_GET: |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
112 return to_dB(s->power,(double*)arg); |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
113 case AF_CONTROL_VOLUME_PROBE_GET_MAX: |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
114 return to_dB(s->maxpower,(double*)arg); |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
115 case AF_CONTROL_VOLUME_SOFTCLIP: |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
116 s->softclip = (int)arg; |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
117 return AF_OK; |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
118 case AF_CONTROL_VOLUME_PROBE_ON_OFF: |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
119 s->probe = (int)arg; |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
120 return AF_OK; |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
121 case AF_CONTROL_VOLUME_ON_OFF: |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
122 s->onoff = (int)arg; |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
123 return AF_OK; |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
124 } |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
125 return AF_UNKNOWN; |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
126 } |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
127 |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
128 // Deallocate memory |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
129 static void uninit(struct af_instance_s* af) |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
130 { |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
131 if(af->data) |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
132 free(af->data); |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
133 if(af->setup) |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
134 free(af->setup); |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
135 } |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
136 |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
137 // Filter data through filter |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
138 static af_data_t* play(struct af_instance_s* af, af_data_t* data) |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
139 { |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
140 af_data_t* c = data; // Current working data |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
141 af_volume_t* s = (af_volume_t*)af->setup; // Setup for this instance |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
142 int16_t* a = (int16_t*)c->audio; // Audio data |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
143 int len = c->len/2; // Number of samples |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
144 int ch = 0; // Channel counter |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
145 register int nch = c->nch; // Number of channels |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
146 register int i = 0; |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
147 |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
148 // Probe the data stream |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
149 if(s->probe){ |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
150 for(ch = 0; ch < nch ; ch++){ |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
151 double alpha = s->alpha; |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
152 double beta = 1 - alpha; |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
153 double pow = s->power[ch]; |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
154 double maxpow = s->maxpower[ch]; |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
155 register double t = 0; |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
156 for(i=ch;i<len;i+=nch){ |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
157 t = ((double)a[i])/32768.0; |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
158 t *= t; |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
159 // Check maximum power value |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
160 if(t>maxpow) |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
161 maxpow=t; |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
162 // Power estimate made using first order AR model |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
163 if(t>pow) |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
164 pow=t; |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
165 else |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
166 pow = beta*pow+alpha*t; |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
167 } |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
168 s->power[ch] = pow; |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
169 s->maxpower[ch] = maxpow; |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
170 } |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
171 } |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
172 |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
173 // Change the volume. |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
174 if(s->onoff){ |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
175 register int sc = s->softclip; |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
176 for(ch = 0; ch < nch ; ch++){ |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
177 register int vol = (int)(255.0 * s->volume[ch]); |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
178 for(i=ch;i<len;i+=nch){ |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
179 register int x; |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
180 x=(a[i] * vol) >> 8; |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
181 if(sc){ |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
182 int64_t t=x*x; |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
183 t=(t*x) >> 30; |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
184 x = (3*x - (int)t) >> 1; |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
185 } |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
186 a[i]=clamp(x,MIN_S16,MAX_S16); |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
187 } |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
188 } |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
189 } |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
190 |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
191 return c; |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
192 } |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
193 |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
194 // Allocate memory and set function pointers |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
195 static int open(af_instance_t* af){ |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
196 int i = 0; |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
197 af->control=control; |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
198 af->uninit=uninit; |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
199 af->play=play; |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
200 af->mul.n=1; |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
201 af->mul.d=1; |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
202 af->data=calloc(1,sizeof(af_data_t)); |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
203 af->setup=calloc(1,sizeof(af_volume_t)); |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
204 if(af->data == NULL || af->setup == NULL) |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
205 return AF_ERROR; |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
206 // Enable volume control and set initial volume to 0.1 |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
207 ((af_volume_t*)af->setup)->onoff = 1; |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
208 for(i=0;i<NCH;i++) |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
209 ((af_volume_t*)af->setup)->volume[i]=0.1; |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
210 |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
211 return AF_OK; |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
212 } |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
213 |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
214 // Description of this filter |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
215 af_info_t af_info_volume = { |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
216 "Volume control audio filter", |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
217 "volume", |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
218 "Anders", |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
219 "", |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
220 AF_FLAGS_NOT_REENTRANT, |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
221 open |
1d3a3dc1f488
Adding volume control and moving control() call parameters to a seperate file
anders
parents:
diff
changeset
|
222 }; |