| Rev 29 |
|
Rev 31 |
| Line 14... |
|
Line 14... |
| 14 |
#include <math.h> |
|
14 |
#include <math.h> |
| 15 |
#include <fftw3.h> |
|
15 |
#include <fftw3.h> |
| 16 |
|
|
16 |
|
| 17 |
static char *device = "plughw:0,0"; /* playback device */ |
|
17 |
static char *device = "plughw:0,0"; /* playback device */ |
| 18 |
static snd_pcm_format_t format = SND_PCM_FORMAT_S16; /* sample format */ |
|
18 |
static snd_pcm_format_t format = SND_PCM_FORMAT_S16; /* sample format */ |
| 19 |
static unsigned int rate = 24000; /* stream rate */ |
|
19 |
static unsigned int rate = 48000; /* stream rate */ |
| 20 |
//static unsigned int buffer_size = 200000; /* ring buffer length in us */ |
|
- |
|
| 21 |
//static unsigned int period_size = 10000; /* period time in us */ |
|
- |
|
| 22 |
static int verbose = 0; /* verbose flag */ |
|
- |
|
| 23 |
static int resample = 1; /* enable alsa-lib resampling */ |
|
20 |
static int resample = 1; /* enable alsa-lib resampling */ |
| 24 |
static int period_event = 0; /* produce poll event after each period */ |
|
21 |
static int period_event = 0; /* produce poll event after each period */ |
| 25 |
|
|
22 |
|
| 26 |
static snd_pcm_sframes_t buffer_size=7008; // size of buffer at sound card |
|
23 |
static snd_pcm_sframes_t buffer_size=7008; // size of buffer at sound card |
| 27 |
static snd_pcm_sframes_t period_size=3504; //samples per frame |
|
24 |
static snd_pcm_sframes_t period_size=2336; //samples per frame |
| 28 |
static snd_output_t *output = NULL; |
|
25 |
static snd_output_t *output = NULL; |
| 29 |
|
|
26 |
|
| 30 |
FILE *out; |
|
27 |
FILE *out; |
| 31 |
|
|
28 |
|
| 32 |
double df; //frequency resolution |
|
29 |
double df; //frequency resolution |
| Line 37... |
|
Line 34... |
| 37 |
fftw_plan fft_plan_left, fft_plan_right; |
|
34 |
fftw_plan fft_plan_left, fft_plan_right; |
| 38 |
|
|
35 |
|
| 39 |
double *spect_avg_left, *spect_avg_right; |
|
36 |
double *spect_avg_left, *spect_avg_right; |
| 40 |
unsigned int period; |
|
37 |
unsigned int period; |
| 41 |
|
|
38 |
|
| - |
|
|
39 |
#define PERIODS 50 // number of periods to average |
| - |
|
|
40 |
|
| - |
|
|
41 |
|
| 42 |
static int set_hwparams(snd_pcm_t *handle, snd_pcm_hw_params_t *params, unsigned int channels) |
|
42 |
static int set_hwparams(snd_pcm_t *handle, snd_pcm_hw_params_t *params, unsigned int channels) |
| 43 |
{ |
|
43 |
{ |
| 44 |
unsigned int rrate; |
|
44 |
unsigned int rrate; |
| 45 |
snd_pcm_uframes_t size; |
|
45 |
snd_pcm_uframes_t size; |
| 46 |
int err, dir; |
|
46 |
int err, dir; |
| Line 175... |
|
Line 175... |
| 175 |
static void async_capture_callback(snd_async_handler_t *ahandler) |
|
175 |
static void async_capture_callback(snd_async_handler_t *ahandler) |
| 176 |
{ |
|
176 |
{ |
| 177 |
snd_pcm_t *handle = snd_async_handler_get_pcm(ahandler); |
|
177 |
snd_pcm_t *handle = snd_async_handler_get_pcm(ahandler); |
| 178 |
int err; |
|
178 |
int err; |
| 179 |
unsigned int i, n; |
|
179 |
unsigned int i, n; |
| 180 |
short signal[300000]; |
|
180 |
short signal[30000]; |
| 181 |
|
|
181 |
|
| 182 |
/*signal = calloc( (unsigned int) period_size, sizeof(short) ); |
|
182 |
/*signal = calloc( (unsigned int) period_size, sizeof(short) ); |
| 183 |
if (signal = NULL) printf("memory allocation failed");*/ |
|
183 |
if (signal = NULL) printf("memory allocation failed");*/ |
| 184 |
|
|
184 |
|
| 185 |
while (snd_pcm_avail_update(handle) >= period_size) { // read until data is ready in buffer |
|
185 |
while (snd_pcm_avail_update(handle) >= period_size) { // read until data is ready in buffer |
| Line 195... |
|
Line 195... |
| 195 |
} |
|
195 |
} |
| 196 |
|
|
196 |
|
| 197 |
n=0; |
|
197 |
n=0; |
| 198 |
i=0; |
|
198 |
i=0; |
| 199 |
do { |
|
199 |
do { |
| 200 |
inl[n]= signal[i]; |
|
200 |
inl[n]= signal[i]/32768.0; |
| 201 |
inr[n]= signal[i+1]; |
|
201 |
inr[n]= signal[i+1]/32768.0; |
| 202 |
n++; |
|
202 |
n++; |
| 203 |
i+=2; |
|
203 |
i+=2; |
| 204 |
} while (n < period_size); |
|
204 |
} while (n < period_size); |
| 205 |
|
|
205 |
|
| 206 |
fftw_execute(fft_plan_left); |
|
206 |
fftw_execute(fft_plan_left); |
| Line 209... |
|
Line 209... |
| 209 |
for(i=0; i < frequency_bins; i++) spect_avg_left[i] += sqrt( (outl[i][0] * outl[i][0]) + (outl[i][1] * outl[i][1]) ); //acumulate average spectrum |
|
209 |
for(i=0; i < frequency_bins; i++) spect_avg_left[i] += sqrt( (outl[i][0] * outl[i][0]) + (outl[i][1] * outl[i][1]) ); //acumulate average spectrum |
| 210 |
for(i=0; i < frequency_bins; i++) spect_avg_right[i] += sqrt( (outr[i][0] * outr[i][0]) + (outr[i][1] * outr[i][1]) ); //acumulate average spectrum |
|
210 |
for(i=0; i < frequency_bins; i++) spect_avg_right[i] += sqrt( (outr[i][0] * outr[i][0]) + (outr[i][1] * outr[i][1]) ); //acumulate average spectrum |
| 211 |
period++; |
|
211 |
period++; |
| 212 |
} |
|
212 |
} |
| 213 |
|
|
213 |
|
| 214 |
if (period > 100) |
|
214 |
if (period > PERIODS) |
| 215 |
{ |
|
215 |
{ |
| 216 |
for(i=0; i < frequency_bins; i++) spect_avg_left[i] = spect_avg_left[i]/100; |
|
216 |
for(i=0; i < frequency_bins; i++) spect_avg_left[i] = spect_avg_left[i]/PERIODS; // finally average spectrum data |
| 217 |
for(i=0; i < frequency_bins; i++) spect_avg_right[i] = spect_avg_right[i]/100; |
|
217 |
for(i=0; i < frequency_bins; i++) spect_avg_right[i] = spect_avg_right[i]/PERIODS; |
| 218 |
|
|
218 |
|
| 219 |
out=fopen("/tmp/sidspect","w"); |
|
219 |
out=fopen("/tmp/sidspec","w"); |
| 220 |
|
|
220 |
|
| 221 |
for(i=0; i < frequency_bins; i++) |
|
221 |
for(i=0; i < frequency_bins; i++) //write spectrum to file |
| 222 |
{ |
|
222 |
{ |
| 223 |
fprintf(out,"%6f %6f %6f\n",(i+0.5)*df, spect_avg_left[i], spect_avg_right[i]); |
|
223 |
fprintf(out,"%.5e %.5e %.5e\n",(i+0.5)*df, spect_avg_left[i], spect_avg_right[i]); |
| 224 |
spect_avg_left[i]=0; |
|
224 |
spect_avg_left[i]=0; |
| 225 |
spect_avg_right[i]=0; |
|
225 |
spect_avg_right[i]=0; |
| 226 |
} |
|
226 |
} |
| 227 |
fclose(out); |
|
227 |
fclose(out); |
| 228 |
period=0; |
|
228 |
period=0; |
| Line 277... |
|
Line 277... |
| 277 |
exit(EXIT_FAILURE); |
|
277 |
exit(EXIT_FAILURE); |
| 278 |
} |
|
278 |
} |
| 279 |
|
|
279 |
|
| 280 |
// setup fft |
|
280 |
// setup fft |
| 281 |
|
|
281 |
|
| 282 |
df = (double) rate/ (double) frequency_bins * 2.0; |
|
282 |
df = (double) rate/ (double) period_size; |
| 283 |
|
|
283 |
|
| 284 |
inl = fftw_malloc(sizeof(double) * period_size); // period_size); |
|
284 |
inl = fftw_malloc(sizeof(double) * period_size); // period_size); |
| 285 |
outl = fftw_malloc(sizeof(fftw_complex) * frequency_bins); |
|
285 |
outl = fftw_malloc(sizeof(fftw_complex) * frequency_bins); |
| 286 |
|
|
286 |
|
| 287 |
inr = fftw_malloc(sizeof(double) * period_size); // period_size); |
|
287 |
inr = fftw_malloc(sizeof(double) * period_size); // period_size); |