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