| 558 | kaklik | 1 | ///////////////////////////////////////////////////////////////////////////////////
 | 
        
           |  |  | 2 | //                        A small demo of sonar.
 | 
        
           |  |  | 3 | // Program allow distance measuring.
 | 
        
           |  |  | 4 | // Uses cross-correlation algorithm to find echos
 | 
        
           |  |  | 5 | //
 | 
        
           |  |  | 6 | // Author: kaklik  (kaklik@mlab.cz)
 | 
        
           |  |  | 7 | //
 | 
        
           |  |  | 8 | ///////////////////////////////////////////////////////////////////////////////////
 | 
        
           |  |  | 9 |   | 
        
           |  |  | 10 | #include <stdio.h>
 | 
        
           |  |  | 11 | #include <stdlib.h>
 | 
        
           |  |  | 12 | #include <string.h>
 | 
        
           |  |  | 13 | #include <sched.h>
 | 
        
           |  |  | 14 | #include <errno.h>
 | 
        
           |  |  | 15 | #include <getopt.h>
 | 
        
           |  |  | 16 | #include <alsa/asoundlib.h>
 | 
        
           |  |  | 17 | #include <sys/time.h>
 | 
        
           |  |  | 18 | #include <math.h>
 | 
        
           |  |  | 19 |   | 
        
           |  |  | 20 | static char *device = "plughw:0,0";			/* playback device */
 | 
        
           |  |  | 21 | static snd_pcm_format_t format = SND_PCM_FORMAT_S16;	/* sample format */
 | 
        
           |  |  | 22 | static unsigned int rate = 98000;			/* stream rate */
 | 
        
           |  |  | 23 | static unsigned int buffer_time = 500000;		/* ring buffer length in us */
 | 
        
           |  |  | 24 | static unsigned int period_time = 100000;		/* period time in us */
 | 
        
           |  |  | 25 | static int resample = 1;				/* enable alsa-lib resampling */
 | 
        
           |  |  | 26 | static int period_event = 0;				/* produce poll event after each period */
 | 
        
           |  |  | 27 |   | 
        
           |  |  | 28 | #define SOUND_SPEED	340
 | 
        
           |  |  | 29 | #define SIGNAL_SAMPLES 100000
 | 
        
           |  |  | 30 | #define CHIRP_OFFSET	0 
 | 
        
           |  |  | 31 |   | 
        
           |  |  | 32 | unsigned int chirp_size;
 | 
        
           |  |  | 33 |   | 
        
           |  |  | 34 | int period=0;
 | 
        
           |  |  | 35 | int cperiod=0;
 | 
        
           |  |  | 36 | int chirp[100000];
 | 
        
           |  |  | 37 | short signal[1000000];		// record 6s of input samples
 | 
        
           |  |  | 38 |   | 
        
           |  |  | 39 | static snd_pcm_sframes_t buffer_size;	// size of buffer at sound card
 | 
        
           |  |  | 40 | static snd_pcm_sframes_t period_size;	//samples per frame
 | 
        
           |  |  | 41 | static snd_output_t *output = NULL;
 | 
        
           |  |  | 42 |   | 
        
           |  |  | 43 | static int set_hwparams(snd_pcm_t *handle, snd_pcm_hw_params_t *params, unsigned int channels)
 | 
        
           |  |  | 44 | {
 | 
        
           |  |  | 45 | 	unsigned int rrate;
 | 
        
           |  |  | 46 | 	snd_pcm_uframes_t size;
 | 
        
           |  |  | 47 | 	int err, dir;
 | 
        
           |  |  | 48 |   | 
        
           |  |  | 49 | 	/* choose all parameters */
 | 
        
           |  |  | 50 | 	err = snd_pcm_hw_params_any(handle, params);
 | 
        
           |  |  | 51 | 	if (err < 0) {
 | 
        
           |  |  | 52 | 		printf("Broken configuration for playback: no configurations available: %s\n", snd_strerror(err));
 | 
        
           |  |  | 53 | 		return err;
 | 
        
           |  |  | 54 | 	}
 | 
        
           |  |  | 55 | 	/* set hardware resampling */
 | 
        
           |  |  | 56 | 	err = snd_pcm_hw_params_set_rate_resample(handle, params, resample);
 | 
        
           |  |  | 57 | 	if (err < 0) {
 | 
        
           |  |  | 58 | 		printf("Resampling setup failed for playback: %s\n", snd_strerror(err));
 | 
        
           |  |  | 59 | 		return err;
 | 
        
           |  |  | 60 | 	}
 | 
        
           |  |  | 61 | 	/* set the interleaved read/write format */
 | 
        
           |  |  | 62 | 	err = snd_pcm_hw_params_set_access(handle, params, SND_PCM_ACCESS_RW_INTERLEAVED);
 | 
        
           |  |  | 63 | 	if (err < 0) {
 | 
        
           |  |  | 64 | 		printf("Access type not available for playback: %s\n", snd_strerror(err));
 | 
        
           |  |  | 65 | 		return err;
 | 
        
           |  |  | 66 | 	}
 | 
        
           |  |  | 67 | 	/* set the sample format */
 | 
        
           |  |  | 68 | 	err = snd_pcm_hw_params_set_format(handle, params, format);
 | 
        
           |  |  | 69 | 	if (err < 0) {
 | 
        
           |  |  | 70 | 		printf("Sample format not available for playback: %s\n", snd_strerror(err));
 | 
        
           |  |  | 71 | 		return err;
 | 
        
           |  |  | 72 | 	}
 | 
        
           |  |  | 73 | 	/* set the count of channels */
 | 
        
           |  |  | 74 | 	err = snd_pcm_hw_params_set_channels(handle, params, channels);
 | 
        
           |  |  | 75 | 	if (err < 0) {
 | 
        
           |  |  | 76 | 		printf("Channels count (%i) not available for playbacks: %s\n", channels, snd_strerror(err));
 | 
        
           |  |  | 77 | 		return err;
 | 
        
           |  |  | 78 | 	}
 | 
        
           |  |  | 79 | 	/* set the stream rate */
 | 
        
           |  |  | 80 | 	rrate = rate;
 | 
        
           |  |  | 81 | 	err = snd_pcm_hw_params_set_rate_near(handle, params, &rrate, 0);
 | 
        
           |  |  | 82 | 	if (err < 0) {
 | 
        
           |  |  | 83 | 		printf("Rate %iHz not available for playback: %s\n", rate, snd_strerror(err));
 | 
        
           |  |  | 84 | 		return err;
 | 
        
           |  |  | 85 | 	}
 | 
        
           |  |  | 86 | 	if (rrate != rate) {
 | 
        
           |  |  | 87 | 		printf("Rate doesn't match (requested %iHz, get %iHz)\n", rate, err);
 | 
        
           |  |  | 88 | 		return -EINVAL;
 | 
        
           |  |  | 89 | 	}
 | 
        
           |  |  | 90 | 	else printf("Rate set to %i Hz\n", rate, err); 
 | 
        
           |  |  | 91 | 	/* set the buffer time */
 | 
        
           |  |  | 92 | 	err = snd_pcm_hw_params_set_buffer_time_near(handle, params, &buffer_time, &dir);
 | 
        
           |  |  | 93 | 	if (err < 0) {
 | 
        
           |  |  | 94 | 		printf("Unable to set buffer time %i for playback: %s\n", buffer_time, snd_strerror(err));
 | 
        
           |  |  | 95 | 		return err;
 | 
        
           |  |  | 96 | 	}
 | 
        
           |  |  | 97 | 	err = snd_pcm_hw_params_get_buffer_size(params, &size);
 | 
        
           |  |  | 98 | 	if (err < 0) {
 | 
        
           |  |  | 99 | 		printf("Unable to get buffer size for playback: %s\n", snd_strerror(err));
 | 
        
           |  |  | 100 | 		return err;
 | 
        
           |  |  | 101 | 	}
 | 
        
           |  |  | 102 | 	buffer_size = size;
 | 
        
           |  |  | 103 | 	/* set the period time */
 | 
        
           |  |  | 104 | 	err = snd_pcm_hw_params_set_period_time_near(handle, params, &period_time, &dir);
 | 
        
           |  |  | 105 | 	if (err < 0) {
 | 
        
           |  |  | 106 | 		printf("Unable to set period time %i for playback: %s\n", period_time, snd_strerror(err));
 | 
        
           |  |  | 107 | 		return err;
 | 
        
           |  |  | 108 | 	}
 | 
        
           |  |  | 109 | 	err = snd_pcm_hw_params_get_period_size(params, &size, &dir);
 | 
        
           |  |  | 110 | 	if (err < 0) {
 | 
        
           |  |  | 111 | 		printf("Unable to get period size for playback: %s\n", snd_strerror(err));
 | 
        
           |  |  | 112 | 		return err;
 | 
        
           |  |  | 113 | 	}
 | 
        
           |  |  | 114 | 	period_size = size;
 | 
        
           |  |  | 115 | 	/* write the parameters to device */
 | 
        
           |  |  | 116 | 	err = snd_pcm_hw_params(handle, params);
 | 
        
           |  |  | 117 | 	if (err < 0) {
 | 
        
           |  |  | 118 | 		printf("Unable to set hw params for playback: %s\n", snd_strerror(err));
 | 
        
           |  |  | 119 | 		return err;
 | 
        
           |  |  | 120 | 	}
 | 
        
           |  |  | 121 | 	return 0;
 | 
        
           |  |  | 122 | }
 | 
        
           |  |  | 123 |   | 
        
           |  |  | 124 | static int set_swparams(snd_pcm_t *handle, snd_pcm_sw_params_t *swparams)
 | 
        
           |  |  | 125 | {
 | 
        
           |  |  | 126 | 	int err;
 | 
        
           |  |  | 127 |   | 
        
           |  |  | 128 | 	/* get the current swparams */
 | 
        
           |  |  | 129 | 	err = snd_pcm_sw_params_current(handle, swparams);
 | 
        
           |  |  | 130 | 	if (err < 0) {
 | 
        
           |  |  | 131 | 		printf("Unable to determine current swparams for playback: %s\n", snd_strerror(err));
 | 
        
           |  |  | 132 | 		return err;
 | 
        
           |  |  | 133 | 	}
 | 
        
           |  |  | 134 | 	/* start the transfer when the buffer is almost full: */
 | 
        
           |  |  | 135 | 	/* (buffer_size / avail_min) * avail_min */
 | 
        
           |  |  | 136 | 	err = snd_pcm_sw_params_set_start_threshold(handle, swparams, (buffer_size / period_size) * period_size);
 | 
        
           |  |  | 137 | 	if (err < 0) {
 | 
        
           |  |  | 138 | 		printf("Unable to set start threshold mode for playback: %s\n", snd_strerror(err));
 | 
        
           |  |  | 139 | 		return err;
 | 
        
           |  |  | 140 | 	}
 | 
        
           |  |  | 141 | 	/* allow the transfer when at least period_size samples can be processed */
 | 
        
           |  |  | 142 | 	/* or disable this mechanism when period event is enabled (aka interrupt like style processing) */
 | 
        
           |  |  | 143 | 	err = snd_pcm_sw_params_set_avail_min(handle, swparams, period_event ? buffer_size : period_size);
 | 
        
           |  |  | 144 | 	if (err < 0) {
 | 
        
           |  |  | 145 | 		printf("Unable to set avail min for playback: %s\n", snd_strerror(err));
 | 
        
           |  |  | 146 | 		return err;
 | 
        
           |  |  | 147 | 	}
 | 
        
           |  |  | 148 | 	/* enable period events when requested */
 | 
        
           |  |  | 149 | 	if (period_event) {
 | 
        
           |  |  | 150 | 		err = snd_pcm_sw_params_set_period_event(handle, swparams, 1);
 | 
        
           |  |  | 151 | 		if (err < 0) {
 | 
        
           |  |  | 152 | 			printf("Unable to set period event: %s\n", snd_strerror(err));
 | 
        
           |  |  | 153 | 			return err;
 | 
        
           |  |  | 154 | 		}
 | 
        
           |  |  | 155 | 	}
 | 
        
           |  |  | 156 | 	/* write the parameters to the playback device */
 | 
        
           |  |  | 157 | 	err = snd_pcm_sw_params(handle, swparams);
 | 
        
           |  |  | 158 | 	if (err < 0) {
 | 
        
           |  |  | 159 | 		printf("Unable to set sw params for playback: %s\n", snd_strerror(err));
 | 
        
           |  |  | 160 | 		return err;
 | 
        
           |  |  | 161 | 	}
 | 
        
           |  |  | 162 | 	return 0;
 | 
        
           |  |  | 163 | }
 | 
        
           |  |  | 164 |   | 
        
           |  |  | 165 | struct async_private_data {
 | 
        
           |  |  | 166 | 	signed short *samples;
 | 
        
           |  |  | 167 | 	snd_pcm_channel_area_t *areas;
 | 
        
           |  |  | 168 | 	unsigned int period;
 | 
        
           |  |  | 169 | };
 | 
        
           |  |  | 170 |   | 
        
           |  |  | 171 |   | 
        
           |  |  | 172 | ////// SIGNAL GENERATION STUFF
 | 
        
           |  |  | 173 | /*int linear_chirp(int *pole, int delka_pole){  // vygeneruje linearni chirp a vzorky ulozi do pole
 | 
        
           |  |  | 174 |   | 
        
           |  |  | 175 | static const float f0 = 0.0001;
 | 
        
           |  |  | 176 | static const float k = 0.00001;
 | 
        
           |  |  | 177 |   | 
        
           |  |  | 178 | int t;
 | 
        
           |  |  | 179 |   | 
        
           |  |  | 180 | //  if((spozdeni+delka) < delka_pole)
 | 
        
           |  |  | 181 |     for(t=0;t < delka_pole;t++) pole[t] = round ( 10000*sin(2*M_PI*(t+faze)*(f0+(k/2)*(t+faze))) );
 | 
        
           |  |  | 182 |     faze +=t;
 | 
        
           |  |  | 183 | //  else return 0;
 | 
        
           |  |  | 184 |   | 
        
           |  |  | 185 | }*/
 | 
        
           |  |  | 186 |   | 
        
           |  |  | 187 | // vygeneruje linearni chirp a vzorky ulozi do pole
 | 
        
           |  |  | 188 | unsigned int linear_windowed_chirp(unsigned int *pole, unsigned int delka_pole,unsigned int offset)
 | 
        
           |  |  | 189 | {
 | 
        
           |  |  | 190 | unsigned int maxval = (1 << (snd_pcm_format_width(format) - 1)) - 1;
 | 
        
           |  |  | 191 |   | 
        
           | 560 | kaklik | 192 | static const float f0 = 1000;		//starting frequency
 | 
        
           |  |  | 193 | static const float fmax = 7000;		//ending frequency
 | 
        
           | 558 | kaklik | 194 | static const float Tw = 0.002;
 | 
        
           |  |  | 195 | static float k;
 | 
        
           |  |  | 196 |   | 
        
           |  |  | 197 | unsigned int n=0;
 | 
        
           |  |  | 198 | double t;
 | 
        
           |  |  | 199 | unsigned int perioda;
 | 
        
           |  |  | 200 |   | 
        
           |  |  | 201 |   k=2*(fmax-f0)/Tw;
 | 
        
           |  |  | 202 |   perioda = rate*Tw; 
 | 
        
           |  |  | 203 |   | 
        
           |  |  | 204 |   for(n=0;n<=perioda;n++){
 | 
        
           |  |  | 205 |      t = (double) n/ (double)rate;
 | 
        
           |  |  | 206 |      pole[n+offset] = (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))) );
 | 
        
           |  |  | 207 |   }
 | 
        
           |  |  | 208 |   return (perioda+offset);
 | 
        
           |  |  | 209 | }
 | 
        
           |  |  | 210 |   | 
        
           |  |  | 211 | // generate sine samples and store
 | 
        
           |  |  | 212 | int sine(unsigned int *pole, unsigned int delka_pole)
 | 
        
           |  |  | 213 | {
 | 
        
           |  |  | 214 | unsigned int maxval = (1 << (snd_pcm_format_width(format) - 1)) - 1;
 | 
        
           |  |  | 215 | unsigned int n;
 | 
        
           |  |  | 216 | double t;
 | 
        
           |  |  | 217 |   | 
        
           |  |  | 218 |   for(n=0;n < delka_pole;n++){
 | 
        
           |  |  | 219 |     t = 440.0 * (double) n/ (double)rate;
 | 
        
           |  |  | 220 |     pole[n] = (short) floor(maxval*sin(2*M_PI*t));
 | 
        
           |  |  | 221 |   }
 | 
        
           |  |  | 222 | }
 | 
        
           |  |  | 223 | //// generate simple sine ping
 | 
        
           |  |  | 224 | unsigned int sine_ping(unsigned int *pole, unsigned int delka_pole,unsigned int offset, double frequency)
 | 
        
           |  |  | 225 | {
 | 
        
           |  |  | 226 | unsigned int maxval = (1 << (snd_pcm_format_width(format) - 1)) - 1;
 | 
        
           |  |  | 227 | unsigned int n;
 | 
        
           |  |  | 228 | double t;
 | 
        
           |  |  | 229 |   | 
        
           |  |  | 230 |   for(n=0;n < delka_pole;n++){
 | 
        
           |  |  | 231 |     t = frequency * (double) n/ (double)rate;
 | 
        
           |  |  | 232 |     pole[n] = (short) floor(maxval*sin(2*M_PI*t));
 | 
        
           |  |  | 233 |   }
 | 
        
           |  |  | 234 | }
 | 
        
           |  |  | 235 |   | 
        
           |  |  | 236 | /////////// CALL BACK STUFF ///////////////////
 | 
        
           |  |  | 237 | static void async_playback_callback(snd_async_handler_t *ahandler)
 | 
        
           |  |  | 238 | {
 | 
        
           |  |  | 239 | 	snd_pcm_t *handle = snd_async_handler_get_pcm(ahandler);
 | 
        
           |  |  | 240 | 	snd_pcm_sframes_t avail;
 | 
        
           |  |  | 241 | 	int err;
 | 
        
           |  |  | 242 |   | 
        
           |  |  | 243 | 	avail = snd_pcm_avail_update(handle);
 | 
        
           |  |  | 244 | 	while ((avail >= period_size) && ((period*period_size) < chirp_size) ) {
 | 
        
           |  |  | 245 |   | 
        
           |  |  | 246 | 		err = snd_pcm_writei(handle, (chirp+period*period_size), period_size);
 | 
        
           |  |  | 247 | 		if (err < 0) {
 | 
        
           |  |  | 248 | 			printf("Write error: %s\n", snd_strerror(err));
 | 
        
           |  |  | 249 | 			exit(EXIT_FAILURE);
 | 
        
           |  |  | 250 | 		}
 | 
        
           |  |  | 251 | 		if (err != period_size) {
 | 
        
           |  |  | 252 | 			printf("Write error: written %i expected %li\n", err, period_size);
 | 
        
           |  |  | 253 | 			exit(EXIT_FAILURE);
 | 
        
           |  |  | 254 | 		}
 | 
        
           |  |  | 255 | 		avail = snd_pcm_avail_update(handle);
 | 
        
           |  |  | 256 | 		period++;
 | 
        
           |  |  | 257 | 	}
 | 
        
           |  |  | 258 | }
 | 
        
           |  |  | 259 |   | 
        
           |  |  | 260 | static void async_capture_callback(snd_async_handler_t *ahandler)
 | 
        
           |  |  | 261 | {
 | 
        
           |  |  | 262 | 	snd_pcm_t *handle = snd_async_handler_get_pcm(ahandler);
 | 
        
           |  |  | 263 | 	snd_pcm_sframes_t avail;
 | 
        
           |  |  | 264 | 	int err;
 | 
        
           |  |  | 265 |   | 
        
           |  |  | 266 | 	avail = snd_pcm_avail_update(handle);
 | 
        
           |  |  | 267 | 	while ((avail >= period_size) /*&& ((period*period_size) < (CHIRP_SIZE-100))*/ ) {  // segmentation fault checking disabled
 | 
        
           |  |  | 268 |   | 
        
           |  |  | 269 | 		err = snd_pcm_readi(handle, (signal+cperiod*period_size), period_size);
 | 
        
           |  |  | 270 | 		if (err < 0) {
 | 
        
           |  |  | 271 | 			printf("Read error: %s\n", snd_strerror(err));
 | 
        
           |  |  | 272 | 			exit(EXIT_FAILURE);
 | 
        
           |  |  | 273 | 		}
 | 
        
           |  |  | 274 | 		if (err != period_size) {
 | 
        
           |  |  | 275 | 			printf("Read error: red %i expected %li\n", err, period_size);
 | 
        
           |  |  | 276 | 			exit(EXIT_FAILURE);
 | 
        
           |  |  | 277 | 		}
 | 
        
           |  |  | 278 | 		avail = snd_pcm_avail_update(handle);
 | 
        
           |  |  | 279 | 		cperiod++;
 | 
        
           |  |  | 280 | 	}
 | 
        
           |  |  | 281 | }
 | 
        
           |  |  | 282 |   | 
        
           |  |  | 283 |   | 
        
           |  |  | 284 | int main(int argc, char *argv[])
 | 
        
           |  |  | 285 | {
 | 
        
           |  |  | 286 | 	snd_pcm_t *playback_handle, *capture_handle;
 | 
        
           |  |  | 287 | 	int err;
 | 
        
           |  |  | 288 | 	snd_pcm_hw_params_t *hwparams;
 | 
        
           |  |  | 289 | 	snd_pcm_sw_params_t *swparams;
 | 
        
           |  |  | 290 | 	signed short *frame;  // pointer to array of samples
 | 
        
           |  |  | 291 | 	unsigned int chn;
 | 
        
           |  |  | 292 | 	snd_pcm_channel_area_t *areas;
 | 
        
           |  |  | 293 |   | 
        
           |  |  | 294 | 	struct async_private_data data;
 | 
        
           |  |  | 295 | 	snd_async_handler_t *chandler, *phandler;
 | 
        
           |  |  | 296 | 	int count;
 | 
        
           |  |  | 297 | 	unsigned int i,j,m,n;
 | 
        
           |  |  | 298 | 	unsigned int delay[10];	//store delay of signifed correlation
 | 
        
           |  |  | 299 |   	long int l,r;  // store correlation at strict time
 | 
        
           |  |  | 300 | 	long int correlationl[SIGNAL_SAMPLES]; //array to store correlation curve
 | 
        
           |  |  | 301 | 	long int correlationr[SIGNAL_SAMPLES]; //array to store correlation curve
 | 
        
           |  |  | 302 | 	int L_signal[SIGNAL_SAMPLES];
 | 
        
           |  |  | 303 | 	int R_signal[SIGNAL_SAMPLES];
 | 
        
           |  |  | 304 |   | 
        
           |  |  | 305 | 	FILE *out;
 | 
        
           |  |  | 306 |   | 
        
           |  |  | 307 | 	snd_pcm_hw_params_alloca(&hwparams);
 | 
        
           |  |  | 308 | 	snd_pcm_sw_params_alloca(&swparams);
 | 
        
           |  |  | 309 |   | 
        
           |  |  | 310 | 	printf("Simple PC sonar ver. 000000001 starting work.. \n");
 | 
        
           |  |  | 311 |   | 
        
           |  |  | 312 | //open and set playback device
 | 
        
           |  |  | 313 | 	if ((err = snd_pcm_open(&playback_handle, device, SND_PCM_STREAM_PLAYBACK, 0)) < 0) {
 | 
        
           |  |  | 314 | 		printf("Playback open error: %s\n", snd_strerror(err));
 | 
        
           |  |  | 315 | 		return 0;
 | 
        
           |  |  | 316 | 	}
 | 
        
           |  |  | 317 |   | 
        
           |  |  | 318 | 	if ((err = set_hwparams(playback_handle, hwparams, 1)) < 0) {
 | 
        
           |  |  | 319 | 		printf("Setting of hwparams failed: %s\n", snd_strerror(err));
 | 
        
           |  |  | 320 | 		exit(EXIT_FAILURE);
 | 
        
           |  |  | 321 | 	}
 | 
        
           |  |  | 322 | 	if ((err = set_swparams(playback_handle, swparams)) < 0) {
 | 
        
           |  |  | 323 | 		printf("Setting of swparams failed: %s\n", snd_strerror(err));
 | 
        
           |  |  | 324 | 		exit(EXIT_FAILURE);
 | 
        
           |  |  | 325 | 	}
 | 
        
           |  |  | 326 |   | 
        
           |  |  | 327 | //open and set capture device
 | 
        
           |  |  | 328 | 	if ((err = snd_pcm_open(&capture_handle, device, SND_PCM_STREAM_CAPTURE, 0)) < 0) {
 | 
        
           |  |  | 329 | 		printf("Playback open error: %s\n", snd_strerror(err));
 | 
        
           |  |  | 330 | 		return 0;
 | 
        
           |  |  | 331 | 	}
 | 
        
           |  |  | 332 |   | 
        
           |  |  | 333 | 	if ((err = set_hwparams(capture_handle, hwparams, 2)) < 0) {
 | 
        
           |  |  | 334 | 		printf("Setting of hwparams failed: %s\n", snd_strerror(err));
 | 
        
           |  |  | 335 | 		exit(EXIT_FAILURE);
 | 
        
           |  |  | 336 | 	}
 | 
        
           |  |  | 337 | 	if ((err = set_swparams(capture_handle, swparams)) < 0) {
 | 
        
           |  |  | 338 | 		printf("Setting of swparams failed: %s\n", snd_strerror(err));
 | 
        
           |  |  | 339 | 		exit(EXIT_FAILURE);
 | 
        
           |  |  | 340 | 	}
 | 
        
           |  |  | 341 |   | 
        
           | 560 | kaklik | 342 | // generate ping pattern
 | 
        
           | 558 | kaklik | 343 |   | 
        
           |  |  | 344 |         chirp_size=linear_windowed_chirp(chirp,1000000, CHIRP_OFFSET);
 | 
        
           |  |  | 345 |   | 
        
           | 560 | kaklik | 346 | // register playback callback 
 | 
        
           | 558 | kaklik | 347 | 	err = snd_async_add_pcm_handler(&phandler, playback_handle, async_playback_callback, &data); // fill by dummy &data
 | 
        
           |  |  | 348 | 	if (err < 0) {
 | 
        
           |  |  | 349 | 		printf("Unable to register async handler\n");
 | 
        
           |  |  | 350 | 		exit(EXIT_FAILURE);
 | 
        
           |  |  | 351 | 	}
 | 
        
           |  |  | 352 |   | 
        
           | 560 | kaklik | 353 | 	if ((err = snd_pcm_prepare (playback_handle)) < 0) {
 | 
        
           |  |  | 354 | 		fprintf (stderr, "cannot prepare audio interface for use (%s)\n",
 | 
        
           |  |  | 355 | 			 snd_strerror (err));
 | 
        
           |  |  | 356 | 		exit (1);
 | 
        
           |  |  | 357 | 	}
 | 
        
           |  |  | 358 |   | 
        
           |  |  | 359 | /*	for (period = 0; period < 2; period++) {
 | 
        
           |  |  | 360 |   | 
        
           | 558 | kaklik | 361 | 		err = snd_pcm_writei(playback_handle, (chirp+period*period_size), period_size);
 | 
        
           |  |  | 362 | 		if (err < 0) {
 | 
        
           |  |  | 363 | 			printf("Initial write error: %s\n", snd_strerror(err));
 | 
        
           |  |  | 364 | 			exit(EXIT_FAILURE);
 | 
        
           |  |  | 365 | 		}
 | 
        
           |  |  | 366 | 		if (err != period_size) {
 | 
        
           |  |  | 367 | 			printf("Initial write error: written %i expected %li\n", err, period_size);
 | 
        
           |  |  | 368 | 			exit(EXIT_FAILURE);
 | 
        
           |  |  | 369 | 		}
 | 
        
           | 560 | kaklik | 370 | 	}*/
 | 
        
           | 558 | kaklik | 371 |   | 
        
           |  |  | 372 | // register capture callback 
 | 
        
           |  |  | 373 | 	err = snd_async_add_pcm_handler(&chandler, capture_handle, async_capture_callback, &data); // fill by dummy &data
 | 
        
           |  |  | 374 | 	if (err < 0) {
 | 
        
           |  |  | 375 | 		printf("Unable to register async handler\n");
 | 
        
           |  |  | 376 | 		exit(EXIT_FAILURE);
 | 
        
           |  |  | 377 | 	}
 | 
        
           |  |  | 378 |   | 
        
           |  |  | 379 |         snd_pcm_link(capture_handle,playback_handle); //link capture and playback together
 | 
        
           |  |  | 380 |   | 
        
           |  |  | 381 | //start sream
 | 
        
           |  |  | 382 | 	if ((err = snd_pcm_prepare (capture_handle)) < 0) {
 | 
        
           |  |  | 383 | 		fprintf (stderr, "cannot prepare audio interface for use (%s)\n",
 | 
        
           |  |  | 384 | 			 snd_strerror (err));
 | 
        
           |  |  | 385 | 		exit (1);
 | 
        
           |  |  | 386 | 	}
 | 
        
           |  |  | 387 |   | 
        
           |  |  | 388 | 	err = snd_pcm_start(capture_handle);
 | 
        
           |  |  | 389 | 	if (err < 0) {
 | 
        
           |  |  | 390 | 			printf("Start error: %s\n", snd_strerror(err));
 | 
        
           |  |  | 391 | 			exit(EXIT_FAILURE);
 | 
        
           |  |  | 392 | 	}
 | 
        
           |  |  | 393 |   | 
        
           |  |  | 394 | //wait until all samples aren't transmitted
 | 
        
           |  |  | 395 | 	printf("Waiting for transmitt all samples\n");
 | 
        
           |  |  | 396 | 	while(cperiod<10) {
 | 
        
           |  |  | 397 | 		sleep(1);
 | 
        
           |  |  | 398 | 		printf(".");
 | 
        
           |  |  | 399 | 	}	
 | 
        
           |  |  | 400 |   | 
        
           |  |  | 401 | ////   stop audio??
 | 
        
           |  |  | 402 |   | 
        
           |  |  | 403 |   | 
        
           |  |  | 404 | 	j=0;
 | 
        
           |  |  | 405 | 	for(i=0;i < SIGNAL_SAMPLES;i++){
 | 
        
           |  |  | 406 | 	  L_signal[i]=signal[j];
 | 
        
           |  |  | 407 | 	  R_signal[i]=signal[j+1];
 | 
        
           |  |  | 408 | 	  j+=2;
 | 
        
           |  |  | 409 | 	}
 | 
        
           |  |  | 410 |   | 
        
           |  |  | 411 | //        linear_windowed_chirp(L_signal,1000000, 1000);
 | 
        
           |  |  | 412 |   | 
        
           |  |  | 413 | 	printf("\nData transmitted... \ncorrelating...\n");
 | 
        
           |  |  | 414 | 	for(n=0; n < (SIGNAL_SAMPLES - chirp_size);n++){
 | 
        
           |  |  | 415 | 	  l=0;
 | 
        
           |  |  | 416 |           r=0;
 | 
        
           |  |  | 417 | 	  for(m=CHIRP_OFFSET;m < chirp_size;m++)
 | 
        
           |  |  | 418 |           {
 | 
        
           |  |  | 419 |             l += chirp[m]*L_signal[m+n];	// correlate with left channel
 | 
        
           |  |  | 420 |             r += chirp[m]*R_signal[m+n];	// correlate with right channel
 | 
        
           |  |  | 421 |           }
 | 
        
           |  |  | 422 | 	  correlationl[n]=l;
 | 
        
           |  |  | 423 | 	  correlationr[n]=r;
 | 
        
           |  |  | 424 | 	}
 | 
        
           |  |  | 425 |   | 
        
           |  |  | 426 | 	printf("\nSearching echos...\n");
 | 
        
           |  |  | 427 | 	r=0;
 | 
        
           |  |  | 428 | 	l=0;
 | 
        
           |  |  | 429 | 	for(n=0; n < (SIGNAL_SAMPLES - chirp_size);n++){			//najde nejvetsi korelace
 | 
        
           |  |  | 430 | 	  if (l < correlationl[n]){
 | 
        
           |  |  | 431 | 	  delay[1] = n;
 | 
        
           |  |  | 432 | 	  l = correlationl[n];
 | 
        
           |  |  | 433 | 	  }
 | 
        
           |  |  | 434 | 	  if (r < correlationr[n]){
 | 
        
           |  |  | 435 | 	  delay[2] = n;
 | 
        
           |  |  | 436 | 	  r = correlationr[n];
 | 
        
           |  |  | 437 | 	  }
 | 
        
           |  |  | 438 | 	}
 | 
        
           |  |  | 439 |   | 
        
           | 560 | kaklik | 440 |   out=fopen("/tmp/sonar.txt","w");
 | 
        
           | 558 | kaklik | 441 |   j=0;
 | 
        
           |  |  | 442 |   for(i=0;i<=100000;i++){
 | 
        
           |  |  | 443 |     fprintf(out,"%6d %6d %6d %6d %9ld %9ld\n",i,chirp[i],L_signal[i],R_signal[i],correlationl[i], correlationr[i]);
 | 
        
           |  |  | 444 |     j+=2;
 | 
        
           |  |  | 445 |   }
 | 
        
           |  |  | 446 |   fclose(out);
 | 
        
           |  |  | 447 |   | 
        
           |  |  | 448 | 	printf("\nEcho zacina na: %d vzorku.\n", delay[1]);
 | 
        
           |  |  | 449 | 	printf("Casove na: %f s\n", ((float)delay[1]/rate));
 | 
        
           |  |  | 450 | 	printf("vzdalenost: %f m\n", (SOUND_SPEED*(float)delay[1]/rate));
 | 
        
           |  |  | 451 |   | 
        
           |  |  | 452 | 	snd_pcm_close(playback_handle);
 | 
        
           |  |  | 453 | 	snd_pcm_close(capture_handle); 
 | 
        
           |  |  | 454 | 	return 0;
 | 
        
           |  |  | 455 | }
 | 
        
           |  |  | 456 |   |