8magsvn – Blame information for rev 34

Subversion Repositories:
Rev:
Rev Author Line No. Line
34 kaklik 1 ///////////////////////////////////////////////////////////////////////////////////
2 //
3 //
4 ///////////////////////////////////////////////////////////////////////////////////
5  
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <string.h>
9 #include <sched.h>
10 #include <errno.h>
11 #include <getopt.h>
12 #include <alsa/asoundlib.h>
13 #include <sys/time.h>
14 #include <math.h>
15  
16 static char *device = "plughw:0,0"; /* playback device */
17 static snd_pcm_format_t format = SND_PCM_FORMAT_S16; /* sample format */
18 static unsigned int rate = 48000; /* stream rate */
19 static unsigned int buffer_time = 130000; /* ring buffer length in us */
20 static unsigned int period_time = 100000; /* period time in us */
21 static int verbose = 0; /* verbose flag */
22 static int resample = 1; /* enable alsa-lib resampling */
23 static int period_event = 0; /* produce poll event after each period */
24  
25 static snd_pcm_sframes_t buffer_size; // size of buffer at sound card
26 static snd_pcm_sframes_t period_size; //samples per frame
27 static snd_output_t *output = NULL;
28  
29 #define MAX_BINS 8
30  
31 int sample_count;
32 double q0;
33 double q1[MAX_BINS];
34 double q2[MAX_BINS];
35 double r[MAX_BINS];
36 double coefs[MAX_BINS] ;
37  
38 FILE *out;
39  
40 double freqs[MAX_BINS] =
41 {
42 697,
43 770,
44 852,
45 941,
46 1209,
47 1336,
48 1477,
49 1633
50 };
51  
52 /*----------------------------------------------------------------------------
53 * calc_coeffs
54 *----------------------------------------------------------------------------
55 * This is where we calculate the correct co-efficients.
56 */
57  
58 /*
59 * coef = 2.0 * cos( (2.0 * PI * k) / (float)GOERTZEL_N)) ;
60 * Where k = (int) (0.5 + ((float)GOERTZEL_N * target_freq) / SAMPLING_RATE));
61 *
62 * More simply: coef = 2.0 * cos( (2.0 * PI * target_freq) / SAMPLING_RATE );
63 */
64  
65 void calc_coeffs()
66 {
67 int n;
68  
69 for(n = 0; n < MAX_BINS; n++)
70 {
71 coefs[n] = 2.0 * cos(2.0 * M_PI * freqs[n] / rate);
72 }
73 }
74  
75 static int set_hwparams(snd_pcm_t *handle, snd_pcm_hw_params_t *params, unsigned int channels)
76 {
77 unsigned int rrate;
78 snd_pcm_uframes_t size;
79 int err, dir;
80  
81 /* choose all parameters */
82 err = snd_pcm_hw_params_any(handle, params);
83 if (err < 0) {
84 printf("Broken configuration for playback: no configurations available: %s\n", snd_strerror(err));
85 return err;
86 }
87 /* set hardware resampling */
88 err = snd_pcm_hw_params_set_rate_resample(handle, params, resample);
89 if (err < 0) {
90 printf("Resampling setup failed for playback: %s\n", snd_strerror(err));
91 return err;
92 }
93 /* set the interleaved read/write format */
94 err = snd_pcm_hw_params_set_access(handle, params, SND_PCM_ACCESS_RW_INTERLEAVED);
95 if (err < 0) {
96 printf("Access type not available for playback: %s\n", snd_strerror(err));
97 return err;
98 }
99 /* set the sample format */
100 err = snd_pcm_hw_params_set_format(handle, params, format);
101 if (err < 0) {
102 printf("Sample format not available for playback: %s\n", snd_strerror(err));
103 return err;
104 }
105 /* set the count of channels */
106 err = snd_pcm_hw_params_set_channels(handle, params, channels);
107 if (err < 0) {
108 printf("Channels count (%i) not available for playbacks: %s\n", channels, snd_strerror(err));
109 return err;
110 }
111 /* set the stream rate */
112 rrate = rate;
113 err = snd_pcm_hw_params_set_rate_near(handle, params, &rrate, 0);
114 if (err < 0) {
115 printf("Rate %iHz not available for playback: %s\n", rate, snd_strerror(err));
116 return err;
117 }
118 if (rrate != rate) {
119 printf("Rate doesn't match (requested %iHz, get %iHz)\n", rate, err);
120 return -EINVAL;
121 }
122 else printf("Rate set to %i Hz\n", rate, err);
123 /* set the buffer time */
124 err = snd_pcm_hw_params_set_buffer_time_near(handle, params, &buffer_time, &dir);
125 if (err < 0) {
126 printf("Unable to set buffer time %i for playback: %s\n", buffer_time, snd_strerror(err));
127 return err;
128 }
129 err = snd_pcm_hw_params_get_buffer_size(params, &size);
130 if (err < 0) {
131 printf("Unable to get buffer size for playback: %s\n", snd_strerror(err));
132 return err;
133 }
134 buffer_size = size;
135 /* set the period time */
136 err = snd_pcm_hw_params_set_period_time_near(handle, params, &period_time, &dir);
137 if (err < 0) {
138 printf("Unable to set period time %i for playback: %s\n", period_time, snd_strerror(err));
139 return err;
140 }
141 err = snd_pcm_hw_params_get_period_size(params, &size, &dir);
142 if (err < 0) {
143 printf("Unable to get period size for playback: %s\n", snd_strerror(err));
144 return err;
145 }
146 period_size = size;
147 /* write the parameters to device */
148 err = snd_pcm_hw_params(handle, params);
149 if (err < 0) {
150 printf("Unable to set hw params for playback: %s\n", snd_strerror(err));
151 return err;
152 }
153 return 0;
154 }
155  
156 static int set_swparams(snd_pcm_t *handle, snd_pcm_sw_params_t *swparams)
157 {
158 int err;
159  
160 /* get the current swparams */
161 err = snd_pcm_sw_params_current(handle, swparams);
162 if (err < 0) {
163 printf("Unable to determine current swparams for playback: %s\n", snd_strerror(err));
164 return err;
165 }
166 /* start the transfer when the buffer is almost full: */
167 /* (buffer_size / avail_min) * avail_min */
168 err = snd_pcm_sw_params_set_start_threshold(handle, swparams, (buffer_size / period_size) * period_size);
169 if (err < 0) {
170 printf("Unable to set start threshold mode for playback: %s\n", snd_strerror(err));
171 return err;
172 }
173 /* allow the transfer when at least period_size samples can be processed */
174 /* or disable this mechanism when period event is enabled (aka interrupt like style processing) */
175 err = snd_pcm_sw_params_set_avail_min(handle, swparams, period_event ? buffer_size : period_size);
176 if (err < 0) {
177 printf("Unable to set avail min for playback: %s\n", snd_strerror(err));
178 return err;
179 }
180 /* enable period events when requested */
181 if (period_event) {
182 err = snd_pcm_sw_params_set_period_event(handle, swparams, 1);
183 if (err < 0) {
184 printf("Unable to set period event: %s\n", snd_strerror(err));
185 return err;
186 }
187 }
188 /* write the parameters to the playback device */
189 err = snd_pcm_sw_params(handle, swparams);
190 if (err < 0) {
191 printf("Unable to set sw params for playback: %s\n", snd_strerror(err));
192 return err;
193 }
194 return 0;
195 }
196  
197 struct async_private_data {
198 signed short *samples;
199 snd_pcm_channel_area_t *areas;
200 unsigned int period;
201 };
202  
203 /////////// CALL BACK STUFF ///////////////////
204  
205 static void async_capture_callback(snd_async_handler_t *ahandler)
206 {
207 snd_pcm_t *handle = snd_async_handler_get_pcm(ahandler);
208 int err;
209 short signal[100000];
210 unsigned int n,i;
211  
212 while (snd_pcm_avail_update(handle) >= period_size) { // read until data is ready in buffer
213  
214 err = snd_pcm_readi(handle, (signal), period_size);
215 if (err < 0) {
216 printf("Read error: %s\n", snd_strerror(err));
217 exit(EXIT_FAILURE);
218 }
219 if (err != period_size) {
220 printf("Read error: red %i expected %li\n", err, period_size);
221 exit(EXIT_FAILURE);
222 }
223  
224 for ( n=0; n<period_size; n+=2 ){
225 for ( i=0; i<MAX_BINS; i++ )
226 {
227 q0 = coefs[i] * q1[i] - q2[i] + signal[n];
228 q2[i] = q1[i];
229 q1[i] = q0;
230 }
231 }
232  
233 for ( i=0; i<MAX_BINS; i++ )
234 {
235 r[i] = (q1[i] * q1[i]) + (q2[i] * q2[i]) - (coefs[i] * q1[i] * q2[i]);
236 q1[i] = 0.0;
237 q2[i] = 0.0;
238 }
239 out=fopen("./output.txt","a");
240 for(i=0;i<MAX_BINS;i++) fprintf(out,"%6f ",r[i]);
241 fprintf(out,"\n");
242 fclose(out);
243 }
244 }
245  
246  
247 int main(int argc, char *argv[])
248 {
249 snd_pcm_t *playback_handle, *capture_handle;
250 int err;
251 snd_pcm_hw_params_t *hwparams;
252 snd_pcm_sw_params_t *swparams;
253 signed short *frame; // pointer to array of samples
254 unsigned int chn;
255 snd_pcm_channel_area_t *areas;
256  
257 struct async_private_data data;
258 snd_async_handler_t *chandler, *phandler;
259 int count;
260 unsigned int i,j;
261  
262 snd_pcm_hw_params_alloca(&hwparams);
263 snd_pcm_sw_params_alloca(&swparams);
264  
265 printf("SID monitor 2.0 starting work.. \n");
266  
267 //open and set capture device
268 if ((err = snd_pcm_open(&capture_handle, device, SND_PCM_STREAM_CAPTURE, 0)) < 0) {
269 printf("Playback open error: %s\n", snd_strerror(err));
270 return 0;
271 }
272  
273 if ((err = set_hwparams(capture_handle, hwparams, 2)) < 0) {
274 printf("Setting of hwparams failed: %s\n", snd_strerror(err));
275 exit(EXIT_FAILURE);
276 }
277 if ((err = set_swparams(capture_handle, swparams)) < 0) {
278 printf("Setting of swparams failed: %s\n", snd_strerror(err));
279 exit(EXIT_FAILURE);
280 }
281  
282 // register capture callback
283 err = snd_async_add_pcm_handler(&chandler, capture_handle, async_capture_callback, &data); // fill by dummy &data
284 if (err < 0) {
285 printf("Unable to register async handler\n");
286 exit(EXIT_FAILURE);
287 }
288  
289 calc_coeffs();
290  
291 //start capture
292 if ((err = snd_pcm_prepare (capture_handle)) < 0) {
293 fprintf (stderr, "cannot prepare audio interface for use (%s)\n",
294 snd_strerror (err));
295 exit (1);
296 }
297  
298 err = snd_pcm_start(capture_handle);
299 if (err < 0) {
300 printf("Start error: %s\n", snd_strerror(err));
301 exit(EXIT_FAILURE);
302 }
303  
304 //wait until all samples aren't transmitted
305 printf("processing audio input.. \n");
306 for (i=0; i<5000; i++) usleep( 1000);
307  
308  
309  
310 snd_pcm_close(capture_handle);
311 return 0;
312 }
313