Subversion Repositories svnkaklik

Rev

Rev 565 | Go to most recent revision | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log

Rev 565 Rev 623
1
///////////////////////////////////////////////////////////////////////////////////
1
///////////////////////////////////////////////////////////////////////////////////
2
//                        A small demo of sonar.
2
//                        A small demo of sonar.
3
// Program allow distance measuring.
3
// Program allow distance measuring.
4
// Uses cross-correlation algorithm to find echos
4
// Uses cross-correlation algorithm to find echos
5
//
5
//
6
// Author: kaklik  (kaklik@mlab.cz)
6
// Author: kaklik  (kaklik@mlab.cz)
7
//
7
//
8
///////////////////////////////////////////////////////////////////////////////////
8
///////////////////////////////////////////////////////////////////////////////////
9
 
9
 
10
#include <stdio.h>
10
#include <stdio.h>
11
#include <stdlib.h>
11
#include <stdlib.h>
12
#include <string.h>
12
#include <string.h>
13
#include <sched.h>
13
#include <sched.h>
14
#include <errno.h>
14
#include <errno.h>
15
#include <getopt.h>
15
#include <getopt.h>
16
#include <alsa/asoundlib.h>
16
#include <alsa/asoundlib.h>
17
#include <sys/time.h>
17
#include <sys/time.h>
18
#include <math.h>
18
#include <math.h>
19
#include <fftw3.h>
19
#include <fftw3.h>
20
 
20
 
21
#define SOUND_SPEED	340.0	// sound speed in air in metrs per second
21
#define SOUND_SPEED	340.0	// sound speed in air in metrs per second
22
#define MAX_RANGE	10.0	// maximal working radius in meters
22
#define MAX_RANGE	10.0	// maximal working radius in meters
23
 
23
 
24
static char *device = "plughw:0,0";			/* playback device */
24
static char *device = "plughw:0,0";			/* playback device */
25
static snd_pcm_format_t format = SND_PCM_FORMAT_S16;	/* sample format */
25
static snd_pcm_format_t format = SND_PCM_FORMAT_S16;	/* sample format */
26
static unsigned int rate = 96000;			/* stream rate */
26
static unsigned int rate = 96000;			/* stream rate */
27
static unsigned int buffer_time = 2 * (MAX_RANGE / SOUND_SPEED * 1e6);		/* ring buffer length in us */
27
static unsigned int buffer_time = 2 * (MAX_RANGE / SOUND_SPEED * 1e6);		/* ring buffer length in us */
28
static unsigned int period_time = MAX_RANGE / SOUND_SPEED * 1e6;		/* period time in us */
28
static unsigned int period_time = MAX_RANGE / SOUND_SPEED * 1e6;		/* period time in us */
29
static int resample = 1;				/* enable alsa-lib resampling */
29
static int resample = 1;				/* enable alsa-lib resampling */
30
 
30
 
31
unsigned int chirp_size;
31
unsigned int chirp_size;
32
 
32
 
33
static snd_pcm_sframes_t buffer_size;	// size of buffer at sound card
33
static snd_pcm_sframes_t buffer_size;	// size of buffer at sound card
34
static snd_pcm_sframes_t period_size;	//samples per frame
34
static snd_pcm_sframes_t period_size;	//samples per frame
35
static snd_output_t *output = NULL;
35
static snd_output_t *output = NULL;
36
 
36
 
37
static int set_hwparams(snd_pcm_t *handle, snd_pcm_hw_params_t *params, unsigned int channels)
37
static int set_hwparams(snd_pcm_t *handle, snd_pcm_hw_params_t *params, unsigned int channels)
38
{
38
{
39
    unsigned int rrate;
39
    unsigned int rrate;
40
    snd_pcm_uframes_t size;
40
    snd_pcm_uframes_t size;
41
    int err, dir;
41
    int err, dir;
42
 
42
 
43
    /* choose all parameters */
43
    /* choose all parameters */
44
    err = snd_pcm_hw_params_any(handle, params);
44
    err = snd_pcm_hw_params_any(handle, params);
45
    if (err < 0)
45
    if (err < 0)
46
    {
46
    {
47
        printf("Broken configuration for playback: no configurations available: %s\n", snd_strerror(err));
47
        printf("Broken configuration for playback: no configurations available: %s\n", snd_strerror(err));
48
        return err;
48
        return err;
49
    }
49
    }
50
    /* set hardware resampling */
50
    /* set hardware resampling */
51
    err = snd_pcm_hw_params_set_rate_resample(handle, params, resample);
51
    err = snd_pcm_hw_params_set_rate_resample(handle, params, resample);
52
    if (err < 0)
52
    if (err < 0)
53
    {
53
    {
54
        printf("Resampling setup failed for playback: %s\n", snd_strerror(err));
54
        printf("Resampling setup failed for playback: %s\n", snd_strerror(err));
55
        return err;
55
        return err;
56
    }
56
    }
57
    /* set the interleaved read/write format */
57
    /* set the interleaved read/write format */
58
    err = snd_pcm_hw_params_set_access(handle, params, SND_PCM_ACCESS_RW_INTERLEAVED);
58
    err = snd_pcm_hw_params_set_access(handle, params, SND_PCM_ACCESS_RW_INTERLEAVED);
59
    if (err < 0)
59
    if (err < 0)
60
    {
60
    {
61
        printf("Access type not available for playback: %s\n", snd_strerror(err));
61
        printf("Access type not available for playback: %s\n", snd_strerror(err));
62
        return err;
62
        return err;
63
    }
63
    }
64
    /* set the sample format */
64
    /* set the sample format */
65
    err = snd_pcm_hw_params_set_format(handle, params, format);
65
    err = snd_pcm_hw_params_set_format(handle, params, format);
66
    if (err < 0)
66
    if (err < 0)
67
    {
67
    {
68
        printf("Sample format not available for playback: %s\n", snd_strerror(err));
68
        printf("Sample format not available for playback: %s\n", snd_strerror(err));
69
        return err;
69
        return err;
70
    }
70
    }
71
    /* set the count of channels */
71
    /* set the count of channels */
72
    err = snd_pcm_hw_params_set_channels(handle, params, channels);
72
    err = snd_pcm_hw_params_set_channels(handle, params, channels);
73
    if (err < 0)
73
    if (err < 0)
74
    {
74
    {
75
        printf("Channels count (%i) not available for playbacks: %s\n", channels, snd_strerror(err));
75
        printf("Channels count (%i) not available for playbacks: %s\n", channels, snd_strerror(err));
76
        return err;
76
        return err;
77
    }
77
    }
78
    /* set the stream rate */
78
    /* set the stream rate */
79
    rrate = rate;
79
    rrate = rate;
80
    err = snd_pcm_hw_params_set_rate_near(handle, params, &rrate, 0);
80
    err = snd_pcm_hw_params_set_rate_near(handle, params, &rrate, 0);
81
    if (err < 0)
81
    if (err < 0)
82
    {
82
    {
83
        printf("Rate %iHz not available for playback: %s\n", rate, snd_strerror(err));
83
        printf("Rate %iHz not available for playback: %s\n", rate, snd_strerror(err));
84
        return err;
84
        return err;
85
    }
85
    }
86
    if (rrate != rate)
86
    if (rrate != rate)
87
    {
87
    {
88
        printf("Rate doesn't match (requested %iHz, get %iHz)\n", rate, err);
88
        printf("Rate doesn't match (requested %iHz, get %iHz)\n", rate, err);
89
        return -EINVAL;
89
        return -EINVAL;
90
    }
90
    }
91
    else printf("Rate set to %i Hz\n", rate, err);
91
    else printf("Rate set to %i Hz\n", rate, err);
92
    /* set the buffer time */
92
    /* set the buffer time */
93
    err = snd_pcm_hw_params_set_buffer_time_near(handle, params, &buffer_time, &dir);
93
    err = snd_pcm_hw_params_set_buffer_time_near(handle, params, &buffer_time, &dir);
94
    if (err < 0)
94
    if (err < 0)
95
    {
95
    {
96
        printf("Unable to set buffer time %i for playback: %s\n", buffer_time, snd_strerror(err));
96
        printf("Unable to set buffer time %i for playback: %s\n", buffer_time, snd_strerror(err));
97
        return err;
97
        return err;
98
    }
98
    }
99
    err = snd_pcm_hw_params_get_buffer_size(params, &size);
99
    err = snd_pcm_hw_params_get_buffer_size(params, &size);
100
    if (err < 0)
100
    if (err < 0)
101
    {
101
    {
102
        printf("Unable to get buffer size for playback: %s\n", snd_strerror(err));
102
        printf("Unable to get buffer size for playback: %s\n", snd_strerror(err));
103
        return err;
103
        return err;
104
    }
104
    }
105
    buffer_size = size;
105
    buffer_size = size;
106
    printf("Bufffer size set to:  %d  Requested buffer time: %ld \n", (int) buffer_size, (long) buffer_time);
106
    printf("Bufffer size set to:  %d  Requested buffer time: %ld \n", (int) buffer_size, (long) buffer_time);
107
 
107
 
108
 
108
 
109
    /// set the period time
109
    /// set the period time
110
    err = snd_pcm_hw_params_set_period_time_near(handle, params, &period_time, &dir);
110
    err = snd_pcm_hw_params_set_period_time_near(handle, params, &period_time, &dir);
111
    if (err < 0)
111
    if (err < 0)
112
    {
112
    {
113
        printf("Unable to set period time %i for playback: %s\n", period_time, snd_strerror(err));
113
        printf("Unable to set period time %i for playback: %s\n", period_time, snd_strerror(err));
114
        return err;
114
        return err;
115
    }
115
    }
116
 
116
 
117
    err = snd_pcm_hw_params_get_period_size(params, &size, &dir);
117
    err = snd_pcm_hw_params_get_period_size(params, &size, &dir);
118
    if (err < 0)
118
    if (err < 0)
119
    {
119
    {
120
        printf("Unable to get period size for playback: %s\n", snd_strerror(err));
120
        printf("Unable to get period size for playback: %s\n", snd_strerror(err));
121
        return err;
121
        return err;
122
    }
122
    }
123
    period_size = size;
123
    period_size = size;
124
    printf("Period size set to:  %d Requested period time: %ld \n", (int) period_size, (long) period_time);
124
    printf("Period size set to:  %d Requested period time: %ld \n", (int) period_size, (long) period_time);
125
 
125
 
126
    /* write the parameters to device */
126
    /* write the parameters to device */
127
    err = snd_pcm_hw_params(handle, params);
127
    err = snd_pcm_hw_params(handle, params);
128
    if (err < 0)
128
    if (err < 0)
129
    {
129
    {
130
        printf("Unable to set hw params for playback: %s\n", snd_strerror(err));
130
        printf("Unable to set hw params for playback: %s\n", snd_strerror(err));
131
        return err;
131
        return err;
132
    }
132
    }
133
    return 0;
133
    return 0;
134
}
134
}
135
 
135
 
136
static int set_swparams(snd_pcm_t *handle, snd_pcm_sw_params_t *swparams)
136
static int set_swparams(snd_pcm_t *handle, snd_pcm_sw_params_t *swparams)
137
{
137
{
138
    int err;
138
    int err;
139
 
139
 
140
    /* get the current swparams */
140
    /* get the current swparams */
141
    err = snd_pcm_sw_params_current(handle, swparams);
141
    err = snd_pcm_sw_params_current(handle, swparams);
142
    if (err < 0)
142
    if (err < 0)
143
    {
143
    {
144
        printf("Unable to determine current swparams for playback: %s\n", snd_strerror(err));
144
        printf("Unable to determine current swparams for playback: %s\n", snd_strerror(err));
145
        return err;
145
        return err;
146
    }
146
    }
147
    // start the transfer when the buffer is almost full: never fou our case
147
    // start the transfer when the buffer is almost full: never fou our case
148
    err = snd_pcm_sw_params_set_start_threshold(handle, swparams, 2 * buffer_size);
148
    err = snd_pcm_sw_params_set_start_threshold(handle, swparams, 2 * buffer_size);
149
    if (err < 0)
149
    if (err < 0)
150
    {
150
    {
151
        printf("Unable to set start threshold mode for playback: %s\n", snd_strerror(err));
151
        printf("Unable to set start threshold mode for playback: %s\n", snd_strerror(err));
152
        return err;
152
        return err;
153
    }
153
    }
154
 
154
 
155
    err = snd_pcm_sw_params_set_period_event(handle, swparams, 1);
155
    err = snd_pcm_sw_params_set_period_event(handle, swparams, 1);
156
    if (err < 0)
156
    if (err < 0)
157
    {
157
    {
158
        printf("Unable to set period event: %s\n", snd_strerror(err));
158
        printf("Unable to set period event: %s\n", snd_strerror(err));
159
        return err;
159
        return err;
160
    }
160
    }
161
 
161
 
162
    /* write the parameters to the playback device */
162
    /* write the parameters to the playback device */
163
    err = snd_pcm_sw_params(handle, swparams);
163
    err = snd_pcm_sw_params(handle, swparams);
164
    if (err < 0)
164
    if (err < 0)
165
    {
165
    {
166
        printf("Unable to set sw params for playback: %s\n", snd_strerror(err));
166
        printf("Unable to set sw params for playback: %s\n", snd_strerror(err));
167
        return err;
167
        return err;
168
    }
168
    }
169
    return 0;
169
    return 0;
170
}
170
}
171
 
171
 
172
////// SIGNAL GENERATION STUFF
172
////// SIGNAL GENERATION STUFF
173
unsigned int linear_windowed_chirp(short *pole)
173
unsigned int linear_windowed_chirp(short *pole)
174
{
174
{
175
    unsigned int maxval = (1 << (snd_pcm_format_width(format) - 1)) - 1;
175
    unsigned int maxval = (1 << (snd_pcm_format_width(format) - 1)) - 1;
176
 
176
 
177
    static const float f0 = 5000;		//starting frequency
177
    static const float f0 = 5000;		//starting frequency
178
    static const float fmax = 10000;		//ending frequency
178
    static const float fmax = 10000;		//ending frequency
179
    static const float Tw = 0.0015;
179
    static const float Tw = 0.0015;
180
    static float k;
180
    static float k;
181
 
181
 
182
    unsigned int n=0;
182
    unsigned int n=0;
183
    double t;
183
    double t;
184
    unsigned int chirp_samples;		// number of samples per period
184
    unsigned int chirp_samples;		// number of samples per period
185
 
185
 
186
    k=2*(fmax-f0)/Tw;
186
    k=2*(fmax-f0)/Tw;
187
    chirp_samples = ceil(rate*Tw);
187
    chirp_samples = ceil(rate*Tw);
188
 
188
 
189
    for (n=0;n<=chirp_samples;n++)
189
    for (n=0;n<=chirp_samples;n++)
190
    {
190
    {
191
        t = (double) n / (double)rate;
191
        t = (double) n / (double)rate;
192
        pole[n] = (short) floor( (0.35875 - 0.48829*cos(2*M_PI*t*1/Tw) + 0.14128*cos(2*M_PI*2*t*1/Tw) - 0.01168*cos(2*M_PI*3*t*1/Tw))*maxval*sin(2*M_PI*(t)*(f0+(k/2)*(t))) );
192
        pole[n] = (short) floor( (0.35875 - 0.48829*cos(2*M_PI*t*1/Tw) + 0.14128*cos(2*M_PI*2*t*1/Tw) - 0.01168*cos(2*M_PI*3*t*1/Tw))*maxval*sin(2*M_PI*(t)*(f0+(k/2)*(t))) );
193
    }
193
    }
194
    return (chirp_samples);
194
    return (chirp_samples);
195
}
195
}
196
 
196
 
197
int main(int argc, char *argv[])
197
int main(int argc, char *argv[])
198
{
198
{
199
    snd_pcm_t *playback_handle, *capture_handle;
199
    snd_pcm_t *playback_handle, *capture_handle;
200
    int err;
200
    int err;
201
    snd_pcm_hw_params_t *hwparams;
201
    snd_pcm_hw_params_t *hwparams;
202
    snd_pcm_sw_params_t *swparams;
202
    snd_pcm_sw_params_t *swparams;
203
 
203
 
204
    long int *correlationl, *correlationr;
204
    long int *correlationl, *correlationr;
205
    int *L_signal, *R_signal;
205
    int *L_signal, *R_signal;
206
    short *chirp, *signal;
206
    short *chirp, *signal;
207
    float *chirp_spect, *echo_spect;
207
    float *chirp_spect, *lecho_spect, *recho_spect;
208
    unsigned int i,j,m,n;
208
    unsigned int i,j,m,n;
209
    unsigned int delayl[10],delayr[10];	//store delay of signifed correlation
209
    unsigned int delayl[10],delayr[10];	//store delay of signifed correlation
210
    long int l,r;  // store correlation at strict time
210
    long int l,r;  // store correlation at strict time
211
    double df;	//frequency resolution 
211
    double df;	//frequency resolution 
212
    unsigned int frequency_bins; // number of output frequency bins 
212
    unsigned int frequency_bins; // number of output frequency bins 
213
 
213
 
214
    double *inchirp;
214
    double *inchirp;
215
    fftw_complex *outchirp;
215
    fftw_complex *outchirp;
216
    fftw_plan fft_plan_chirp;
216
    fftw_plan fft_plan_chirp;
217
 
217
 
218
    FILE *out;
218
    FILE *out;
219
 
219
 
220
    snd_pcm_hw_params_alloca(&hwparams);
220
    snd_pcm_hw_params_alloca(&hwparams);
221
    snd_pcm_sw_params_alloca(&swparams);
221
    snd_pcm_sw_params_alloca(&swparams);
222
 
222
 
223
    printf("Simple PC sonar ver. 000000001 starting work.. \n");
223
    printf("Simple PC sonar ver. 000000001 starting work.. \n");
224
 
224
 
225
//open and set playback device
225
//open and set playback device
226
    if ((err = snd_pcm_open(&playback_handle, device, SND_PCM_STREAM_PLAYBACK, 0)) < 0)
226
    if ((err = snd_pcm_open(&playback_handle, device, SND_PCM_STREAM_PLAYBACK, 0)) < 0)
227
    {
227
    {
228
        printf("Playback open error: %s\n", snd_strerror(err));
228
        printf("Playback open error: %s\n", snd_strerror(err));
229
        return 0;
229
        return 0;
230
    }
230
    }
231
 
231
 
232
    if ((err = set_hwparams(playback_handle, hwparams, 1)) < 0)
232
    if ((err = set_hwparams(playback_handle, hwparams, 1)) < 0)
233
    {
233
    {
234
        printf("Setting of hwparams failed: %s\n", snd_strerror(err));
234
        printf("Setting of hwparams failed: %s\n", snd_strerror(err));
235
        exit(EXIT_FAILURE);
235
        exit(EXIT_FAILURE);
236
    }
236
    }
237
    if ((err = set_swparams(playback_handle, swparams)) < 0)
237
    if ((err = set_swparams(playback_handle, swparams)) < 0)
238
    {
238
    {
239
        printf("Setting of swparams failed: %s\n", snd_strerror(err));
239
        printf("Setting of swparams failed: %s\n", snd_strerror(err));
240
        exit(EXIT_FAILURE);
240
        exit(EXIT_FAILURE);
241
    }
241
    }
242
 
242
 
243
//open and set capture device
243
//open and set capture device
244
    if ((err = snd_pcm_open(&capture_handle, device, SND_PCM_STREAM_CAPTURE, 0)) < 0)
244
    if ((err = snd_pcm_open(&capture_handle, device, SND_PCM_STREAM_CAPTURE, 0)) < 0)
245
    {
245
    {
246
        printf("Playback open error: %s\n", snd_strerror(err));
246
        printf("Playback open error: %s\n", snd_strerror(err));
247
        return 0;
247
        return 0;
248
    }
248
    }
249
 
249
 
250
    if ((err = set_hwparams(capture_handle, hwparams, 2)) < 0)
250
    if ((err = set_hwparams(capture_handle, hwparams, 2)) < 0)
251
    {
251
    {
252
        printf("Setting of hwparams failed: %s\n", snd_strerror(err));
252
        printf("Setting of hwparams failed: %s\n", snd_strerror(err));
253
        exit(EXIT_FAILURE);
253
        exit(EXIT_FAILURE);
254
    }
254
    }
255
    if ((err = set_swparams(capture_handle, swparams)) < 0)
255
    if ((err = set_swparams(capture_handle, swparams)) < 0)
256
    {
256
    {
257
        printf("Setting of swparams failed: %s\n", snd_strerror(err));
257
        printf("Setting of swparams failed: %s\n", snd_strerror(err));
258
        exit(EXIT_FAILURE);
258
        exit(EXIT_FAILURE);
259
    }
259
    }
260
 
260
 
261
    /*    err = snd_pcm_link( capture_handle, playback_handle); //link capture and playback together
261
    /*    err = snd_pcm_link( capture_handle, playback_handle); //link capture and playback together
262
        if (err < 0)
262
        if (err < 0)
263
        {
263
        {
264
            printf("Device linking error: %s\n", snd_strerror(err));
264
            printf("Device linking error: %s\n", snd_strerror(err));
265
            exit(EXIT_FAILURE);
265
            exit(EXIT_FAILURE);
266
        }*/
266
        }*/
267
 
267
 
268
    correlationl = malloc(period_size * sizeof(long int)); //array to store correlation curve
268
    correlationl = malloc(period_size * sizeof(long int)); //array to store correlation curve
269
    correlationr = malloc(period_size * sizeof(long int)); //array to store correlation curve
269
    correlationr = malloc(period_size * sizeof(long int)); //array to store correlation curve
270
    L_signal = malloc(period_size * sizeof(int));
270
    L_signal = malloc(period_size * sizeof(int));
271
    R_signal = malloc(period_size * sizeof(int));
271
    R_signal = malloc(period_size * sizeof(int));
272
    chirp = calloc(2*period_size, sizeof(short));
272
    chirp = calloc(2*period_size, sizeof(short));
273
    signal = malloc(2*period_size * sizeof(short));
273
    signal = malloc(2*period_size * sizeof(short));
274
 
274
 
275
// generate ping pattern
275
// generate ping pattern
276
    chirp_size = linear_windowed_chirp(chirp);
276
    chirp_size = linear_windowed_chirp(chirp);
277
 
277
 
278
    frequency_bins = chirp_size / 2 + 1;
278
    frequency_bins = chirp_size / 2 + 1;
279
    df = (double) rate / (double) chirp_size;
279
    df = (double) rate / (double) chirp_size;
280
    chirp_spect = malloc(frequency_bins * sizeof(float));
280
    chirp_spect = malloc(frequency_bins * sizeof(float));
-
 
281
    lecho_spect = malloc(frequency_bins * sizeof(float));
281
    echo_spect = malloc(frequency_bins * sizeof(float));
282
    recho_spect = malloc(frequency_bins * sizeof(float));
282
 
283
 
283
    inchirp = fftw_malloc(sizeof(double) * chirp_size); 		// allocate input array for FFT
284
    inchirp = fftw_malloc(sizeof(double) * chirp_size); 		// allocate input array for FFT
284
    outchirp = fftw_malloc(sizeof(fftw_complex) * frequency_bins);
285
    outchirp = fftw_malloc(sizeof(fftw_complex) * frequency_bins);
285
 
286
 
286
    fft_plan_chirp = fftw_plan_dft_r2c_1d(chirp_size, inchirp, outchirp, FFTW_ESTIMATE);
287
    fft_plan_chirp = fftw_plan_dft_r2c_1d(chirp_size, inchirp, outchirp, FFTW_ESTIMATE);
287
 
288
 
288
    printf("compute chirp spectrum\n");
289
    printf("compute chirp spectrum\n");
289
    for(i=0; i < chirp_size; i++) inchirp[i] = chirp[i];
290
    for(i=0; i < chirp_size; i++) inchirp[i] = chirp[i];
290
    fftw_execute(fft_plan_chirp);
291
    fftw_execute(fft_plan_chirp);
291
    for(i=0; i < frequency_bins; i++) chirp_spect[i] = sqrt( outchirp[i][0] * outchirp[i][0] + outchirp[i][1] * outchirp[i][1] );
292
    for(i=0; i < frequency_bins; i++) chirp_spect[i] = sqrt( outchirp[i][0] * outchirp[i][0] + outchirp[i][1] * outchirp[i][1] );
292
 
293
 
293
// write chirp data to souncard buffer
294
// write chirp data to souncard buffer
294
    err = snd_pcm_writei(playback_handle, chirp, period_size);
295
    err = snd_pcm_writei(playback_handle, chirp, period_size);
295
    if (err < 0)
296
    if (err < 0)
296
    {
297
    {
297
        printf("Initial write error: %s\n", snd_strerror(err));
298
        printf("Initial write error: %s\n", snd_strerror(err));
298
        exit(EXIT_FAILURE);
299
        exit(EXIT_FAILURE);
299
    }
300
    }
300
 
301
 
301
//start sream
302
//start sream
302
    err = snd_pcm_start(playback_handle);
303
    err = snd_pcm_start(playback_handle);
303
    if (err < 0)
304
    if (err < 0)
304
    {
305
    {
305
        printf("Start error: %s\n", snd_strerror(err));
306
        printf("Start error: %s\n", snd_strerror(err));
306
        exit(EXIT_FAILURE);
307
        exit(EXIT_FAILURE);
307
    }
308
    }
308
 
309
 
309
    err = snd_pcm_start(capture_handle);
310
    err = snd_pcm_start(capture_handle);
310
    if (err < 0)
311
    if (err < 0)
311
    {
312
    {
312
        printf("Start error: %s\n", snd_strerror(err));
313
        printf("Start error: %s\n", snd_strerror(err));
313
        exit(EXIT_FAILURE);
314
        exit(EXIT_FAILURE);
314
    }
315
    }
315
    else printf("Waiting for transmitt all samples\n");
316
    else printf("Waiting for transmitt all samples\n");
316
//--------------
317
//--------------
317
 
318
 
318
    while ( snd_pcm_avail_update(capture_handle) < period_size)			// wait for one period of data
319
    while ( snd_pcm_avail_update(capture_handle) < period_size)			// wait for one period of data
319
    {
320
    {
320
        usleep(1000);
321
        usleep(1000);
321
        printf(".");
322
        printf(".");
322
    }
323
    }
323
 
324
 
324
    err = snd_pcm_drop(playback_handle);		// stop audio stream
325
    err = snd_pcm_drop(playback_handle);		// stop audio stream
325
    err = snd_pcm_drain(capture_handle);
326
    err = snd_pcm_drain(capture_handle);
326
    if (err < 0)
327
    if (err < 0)
327
    {
328
    {
328
        printf("Stop error: %s\n", snd_strerror(err));
329
        printf("Stop error: %s\n", snd_strerror(err));
329
        exit(EXIT_FAILURE);
330
        exit(EXIT_FAILURE);
330
    }
331
    }
331
 
332
 
332
    err = snd_pcm_readi(capture_handle, signal, period_size);		//read period from audio buffer
333
    err = snd_pcm_readi(capture_handle, signal, period_size);		//read period from audio buffer
333
    if (err < 0)
334
    if (err < 0)
334
    {
335
    {
335
        printf("Read error: %s\n", snd_strerror(err));
336
        printf("Read error: %s\n", snd_strerror(err));
336
        exit(EXIT_FAILURE);
337
        exit(EXIT_FAILURE);
337
    }
338
    }
338
 
339
 
339
    j=0;
340
    j=0;
340
    for (i=0;i < period_size;i++)		// separe inretleaved samples to two arrays
341
    for (i=0;i < period_size;i++)		// separe inretleaved samples to two arrays
341
    {
342
    {
342
        L_signal[i]=signal[j];
343
        L_signal[i]=signal[j];
343
        R_signal[i]=signal[j+1];
344
        R_signal[i]=signal[j+1];
344
        j+=2;
345
        j+=2;
345
    }
346
    }
346
 
347
 
347
    printf("\nData transmitted \ncorrelating\n");
348
    printf("\nData transmitted \ncorrelating\n");
348
    for (n=0; n < (period_size - chirp_size - 1); n++)
349
    for (n=0; n < (period_size - chirp_size - 1); n++)
349
    {
350
    {
350
        l=0;
351
        l=0;
351
        r=0;
352
        r=0;
352
        for ( m = 0; m < chirp_size;m++)
353
        for ( m = 0; m < chirp_size;m++)
353
        {
354
        {
354
            l += chirp[m]*L_signal[m+n];	// correlate with left channel
355
            l += chirp[m]*L_signal[m+n];	// correlate with left channel
355
            r += chirp[m]*R_signal[m+n];	// correlate with right channel
356
            r += chirp[m]*R_signal[m+n];	// correlate with right channel
356
        }
357
        }
357
        correlationl[n]=abs(l);
358
        correlationl[n]=abs(l);
358
        correlationr[n]=abs(r);
359
        correlationr[n]=abs(r);
359
    }
360
    }
360
 
361
 
361
    printf("Searching echos\n");
362
    printf("Searching echos\n");
362
    r=0;
363
    r=0;
363
    l=0;
364
    l=0;
364
    for (n=0; n < period_size;n++) 			//najde nejvetsi korelace
365
    for (n=0; n < period_size;n++) 			//najde nejvetsi korelace
365
    {
366
    {
366
        if (l < correlationl[n])
367
        if (l < correlationl[n])
367
        {
368
        {
368
            delayl[1] = n;
369
            delayl[1] = n;
369
            l = correlationl[n];
370
            l = correlationl[n];
370
        }
371
        }
371
        if (r < correlationr[n])
372
        if (r < correlationr[n])
372
        {
373
        {
373
            delayr[1] = n;
374
            delayr[1] = n;
374
            r = correlationr[n];
375
            r = correlationr[n];
375
        }
376
        }
376
    }
377
    }
377
 
378
 
378
    for(i=delayl[1]; i < delayl[1] + chirp_size; i++) inchirp[i-delayl[1]] = L_signal[i];
379
    for(i=delayl[1]; i < delayl[1] + chirp_size; i++) inchirp[i-delayl[1]] = L_signal[i];
379
    fftw_execute(fft_plan_chirp);
380
    fftw_execute(fft_plan_chirp);
380
    for(i=0; i < frequency_bins; i++) echo_spect[i] = sqrt(outchirp[i][0] * outchirp[i][0] + outchirp[i][1] * outchirp[i][1]);
381
    for(i=0; i < frequency_bins; i++) lecho_spect[i] = sqrt(outchirp[i][0] * outchirp[i][0] + outchirp[i][1] * outchirp[i][1]);
-
 
382
 
-
 
383
    for(i=delayr[1]; i < delayr[1] + chirp_size; i++) inchirp[i-delayr[1]] = R_signal[i];
-
 
384
    fftw_execute(fft_plan_chirp);
-
 
385
    for(i=0; i < frequency_bins; i++) recho_spect[i] = sqrt(outchirp[i][0] * outchirp[i][0] + outchirp[i][1] * outchirp[i][1]);
381
 
386
 
382
    printf("Writing output files\n");
387
    printf("Writing output files\n");
383
    out=fopen("/tmp/sonar.txt","w");
388
    out=fopen("/tmp/sonar.txt","w");
384
    for (i=0; i <= (period_size - 1); i++)
389
    for (i=0; i <= (period_size - 1); i++)
385
    {
390
    {
386
        fprintf(out,"%2.3f %6d %6d %9ld %9ld\n",SOUND_SPEED * (float) i / rate,L_signal[i],R_signal[i],correlationl[i], correlationr[i]);
391
        fprintf(out,"%2.3f %6d %6d %9ld %9ld\n",SOUND_SPEED * (float) i / rate,L_signal[i],R_signal[i],correlationl[i], correlationr[i]);
387
    }
392
    }
388
    fclose(out);
393
    fclose(out);
389
 
394
 
390
    out=fopen("/tmp/chirp.txt","w");
395
    out=fopen("/tmp/chirp.txt","w");
391
    for (i=0; i <= (chirp_size - 1); i++)
396
    for (i=0; i <= (chirp_size - 1); i++)
392
    {
397
    {
393
        fprintf(out,"%6d %6d\n", i, chirp[i]);
398
        fprintf(out,"%6d %6d\n", i, chirp[i]);
394
    }
399
    }
395
    fclose(out);
400
    fclose(out);
396
 
401
 
397
    out=fopen("/tmp/echo.txt","w");
402
    out=fopen("/tmp/echo.txt","w");
398
    for(i=delayl[1]; i < delayl[1] + chirp_size; i++) fprintf(out,"%6d %6d\n", i-delayl[1], L_signal[i]);
403
    for(i=0; i < chirp_size; i++) fprintf(out,"%6d %6d %6d\n", i, L_signal[i + delayl[1]], R_signal[i + delayr[1]]);
399
    fclose(out);
404
    fclose(out);
400
 
405
 
401
    out=fopen("/tmp/spektra.txt","w");
406
    out=fopen("/tmp/spektra.txt","w");
402
    for (i=0; i < frequency_bins; i++)
407
    for (i=0; i < frequency_bins; i++)
403
    {
408
    {
404
        fprintf(out,"%4.3f %4.3f %4.3f\n", (i+0.5) * df, chirp_spect[i], echo_spect[i]);
409
        fprintf(out,"%4.3f %4.3f %4.3f %4.3f\n", (i+0.5) * df, chirp_spect[i], lecho_spect[i], recho_spect[i]);
405
    }
410
    }
406
    fclose(out);
411
    fclose(out);
407
 
412
 
408
    printf("Echo zacina na: %d vzorku.\n", delayl[1]);
413
    printf("Echo zacina na: %d vzorku.\n", delayl[1]);
409
    printf("Casove na: %f s\n", ((float)delayl[1]/rate));
414
    printf("Casove na: %f s\n", ((float)delayl[1]/rate));
410
    printf("vzdalenost: %f m\n", (SOUND_SPEED*(float)delayl[1]/rate));
415
    printf("vzdalenost: %f m\n", (SOUND_SPEED*(float)delayl[1]/rate));
411
 
416
 
412
    free(correlationl);
417
    free(correlationl);
413
    free(correlationr);
418
    free(correlationr);
414
    free(L_signal);
419
    free(L_signal);
415
    free(R_signal);
420
    free(R_signal);
416
    free(chirp);
421
    free(chirp);
417
    free(signal);
422
    free(signal);
418
 
423
 
419
    snd_pcm_close(playback_handle);
424
    snd_pcm_close(playback_handle);
420
    snd_pcm_close(capture_handle);
425
    snd_pcm_close(capture_handle);
421
    return 0;
426
    return 0;
422
}
427
}
423
 
428