Subversion Repositories svnkaklik

Rev

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

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