jack1 codebase
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

738 lines
21KB

  1. /** @file simple_client.c
  2. *
  3. * @brief This simple client demonstrates the basic features of JACK
  4. * as they would be used by many applications.
  5. */
  6. #define _ISOC99_SOURCE 1
  7. #define _XOPEN_SOURCE 600
  8. #include <stdio.h>
  9. #include <errno.h>
  10. #include <unistd.h>
  11. #include <stdlib.h>
  12. #include <string.h>
  13. #include <alloca.h>
  14. #include <math.h>
  15. #include <jack/jack.h>
  16. #include <jack/jslist.h>
  17. #include "alsa/asoundlib.h"
  18. #include <samplerate.h>
  19. #define SAMPLE_16BIT_SCALING 32767.0f
  20. #define SAMPLE_16BIT_MAX 32767
  21. #define SAMPLE_16BIT_MIN -32767
  22. #define NORMALIZED_FLOAT_MIN -1.0f
  23. #define NORMALIZED_FLOAT_MAX 1.0f
  24. #define f_round(f) lrintf(f)
  25. #define float_16(s, d)\
  26. if ((s) <= NORMALIZED_FLOAT_MIN) {\
  27. (d) = SAMPLE_16BIT_MIN;\
  28. } else if ((s) >= NORMALIZED_FLOAT_MAX) {\
  29. (d) = SAMPLE_16BIT_MAX;\
  30. } else {\
  31. (d) = f_round ((s) * SAMPLE_16BIT_SCALING);\
  32. }
  33. #define OFF_D_SIZE 256
  34. typedef signed short ALSASAMPLE;
  35. // Here are the lists of the jack ports...
  36. JSList *capture_ports = NULL;
  37. JSList *capture_srcs = NULL;
  38. JSList *playback_ports = NULL;
  39. JSList *playback_srcs = NULL;
  40. jack_client_t *client;
  41. // TODO: make the sample format configurable soon...
  42. snd_pcm_format_t format = SND_PCM_FORMAT_S16; /* sample format */
  43. snd_pcm_t *alsa_handle;
  44. int jack_sample_rate;
  45. int jack_buffer_size;
  46. double current_resample_factor = 1.0;
  47. double resample_mean = 1.0;
  48. double old_offset = 0.0;
  49. double offset_differential_array[OFF_D_SIZE];
  50. double offset_array[OFF_D_SIZE];
  51. int offset_differential_index = 0;
  52. double old_resample_factor = 1.0;
  53. double old_old_resample_factor = 1.0;
  54. double dd_resample_factor = 0.0;
  55. double offset_integral = 0;
  56. // ------------------------------------------------------ commandline parameters
  57. int sample_rate = 0; /* stream rate */
  58. int num_channels = 2; /* count of channels */
  59. int period_size = 1024;
  60. int num_periods = 2;
  61. int target_delay = 0; /* the delay which the program should try to approach. */
  62. int max_diff = 0; /* the diff value, when a hard readpointer skip should occur */
  63. int catch_factor = 1000;
  64. int catch_factor2 = 10000;
  65. int good_window=0;
  66. int verbose = 0;
  67. int instrument = 0;
  68. // Debug stuff:
  69. volatile float output_resampling_factor = 1.0;
  70. volatile int output_new_delay = 0;
  71. volatile float output_offset = 0.0;
  72. volatile float output_integral = 0.0;
  73. volatile float output_diff = 0.0;
  74. snd_pcm_uframes_t real_buffer_size;
  75. snd_pcm_uframes_t real_period_size;
  76. // Alsa stuff... i dont want to touch this bullshit in the next years.... please...
  77. static int xrun_recovery(snd_pcm_t *handle, int err) {
  78. printf( "xrun !!!.... %d\n", err );
  79. if (err == -EPIPE) { /* under-run */
  80. err = snd_pcm_prepare(handle);
  81. if (err < 0)
  82. printf("Can't recovery from underrun, prepare failed: %s\n", snd_strerror(err));
  83. return 0;
  84. } else if (err == -EAGAIN) {
  85. while ((err = snd_pcm_resume(handle)) == -EAGAIN)
  86. usleep(100); /* wait until the suspend flag is released */
  87. if (err < 0) {
  88. err = snd_pcm_prepare(handle);
  89. if (err < 0)
  90. printf("Can't recovery from suspend, prepare failed: %s\n", snd_strerror(err));
  91. }
  92. return 0;
  93. }
  94. return err;
  95. }
  96. static int set_hwparams(snd_pcm_t *handle, snd_pcm_hw_params_t *params, snd_pcm_access_t access, int rate, int channels, int period, int nperiods ) {
  97. int err, dir=0;
  98. unsigned int buffer_time;
  99. unsigned int period_time;
  100. unsigned int rrate;
  101. /* choose all parameters */
  102. err = snd_pcm_hw_params_any(handle, params);
  103. if (err < 0) {
  104. printf("Broken configuration for playback: no configurations available: %s\n", snd_strerror(err));
  105. return err;
  106. }
  107. /* set the interleaved read/write format */
  108. err = snd_pcm_hw_params_set_access(handle, params, access);
  109. if (err < 0) {
  110. printf("Access type not available for playback: %s\n", snd_strerror(err));
  111. return err;
  112. }
  113. /* set the sample format */
  114. err = snd_pcm_hw_params_set_format(handle, params, format);
  115. if (err < 0) {
  116. printf("Sample format not available for playback: %s\n", snd_strerror(err));
  117. return err;
  118. }
  119. /* set the count of channels */
  120. err = snd_pcm_hw_params_set_channels(handle, params, channels);
  121. if (err < 0) {
  122. printf("Channels count (%i) not available for record: %s\n", channels, snd_strerror(err));
  123. return err;
  124. }
  125. /* set the stream rate */
  126. rrate = rate;
  127. err = snd_pcm_hw_params_set_rate_near(handle, params, &rrate, 0);
  128. if (err < 0) {
  129. printf("Rate %iHz not available for playback: %s\n", rate, snd_strerror(err));
  130. return err;
  131. }
  132. if (rrate != rate) {
  133. printf("Rate doesn't match (requested %iHz, get %iHz)\n", rate, rrate);
  134. return -EINVAL;
  135. }
  136. /* set the buffer time */
  137. buffer_time = 1000000*period*nperiods/rate;
  138. err = snd_pcm_hw_params_set_buffer_time_near(handle, params, &buffer_time, &dir);
  139. if (err < 0) {
  140. printf("Unable to set buffer time %i for playback: %s\n", 1000000*period*nperiods/rate, snd_strerror(err));
  141. return err;
  142. }
  143. err = snd_pcm_hw_params_get_buffer_size( params, &real_buffer_size );
  144. if (err < 0) {
  145. printf("Unable to get buffer size back: %s\n", snd_strerror(err));
  146. return err;
  147. }
  148. if( real_buffer_size != nperiods * period ) {
  149. printf( "WARNING: buffer size does not match: (requested %d, got %d)\n", nperiods * period, (int) real_buffer_size );
  150. }
  151. /* set the period time */
  152. period_time = 1000000*period/rate;
  153. err = snd_pcm_hw_params_set_period_time_near(handle, params, &period_time, &dir);
  154. if (err < 0) {
  155. printf("Unable to set period time %i for playback: %s\n", 1000000*period/rate, snd_strerror(err));
  156. return err;
  157. }
  158. err = snd_pcm_hw_params_get_period_size(params, &real_period_size, NULL );
  159. if (err < 0) {
  160. printf("Unable to get period size back: %s\n", snd_strerror(err));
  161. return err;
  162. }
  163. if( real_period_size != period ) {
  164. printf( "WARNING: period size does not match: (requested %i, got %i)\n", period, (int)real_period_size );
  165. }
  166. /* write the parameters to device */
  167. err = snd_pcm_hw_params(handle, params);
  168. if (err < 0) {
  169. printf("Unable to set hw params for playback: %s\n", snd_strerror(err));
  170. return err;
  171. }
  172. return 0;
  173. }
  174. static int set_swparams(snd_pcm_t *handle, snd_pcm_sw_params_t *swparams, int period, int nperiods) {
  175. int err;
  176. /* get the current swparams */
  177. err = snd_pcm_sw_params_current(handle, swparams);
  178. if (err < 0) {
  179. printf("Unable to determine current swparams for capture: %s\n", snd_strerror(err));
  180. return err;
  181. }
  182. /* start the transfer when the buffer is full */
  183. err = snd_pcm_sw_params_set_start_threshold(handle, swparams, period );
  184. if (err < 0) {
  185. printf("Unable to set start threshold mode for capture: %s\n", snd_strerror(err));
  186. return err;
  187. }
  188. err = snd_pcm_sw_params_set_stop_threshold(handle, swparams, -1 );
  189. if (err < 0) {
  190. printf("Unable to set start threshold mode for capture: %s\n", snd_strerror(err));
  191. return err;
  192. }
  193. /* allow the transfer when at least period_size samples can be processed */
  194. err = snd_pcm_sw_params_set_avail_min(handle, swparams, 1 );
  195. if (err < 0) {
  196. printf("Unable to set avail min for capture: %s\n", snd_strerror(err));
  197. return err;
  198. }
  199. /* align all transfers to 1 sample */
  200. err = snd_pcm_sw_params_set_xfer_align(handle, swparams, 1);
  201. if (err < 0) {
  202. printf("Unable to set transfer align for capture: %s\n", snd_strerror(err));
  203. return err;
  204. }
  205. /* write the parameters to the playback device */
  206. err = snd_pcm_sw_params(handle, swparams);
  207. if (err < 0) {
  208. printf("Unable to set sw params for capture: %s\n", snd_strerror(err));
  209. return err;
  210. }
  211. return 0;
  212. }
  213. // ok... i only need this function to communicate with the alsa bloat api...
  214. static snd_pcm_t *open_audiofd( char *device_name, int capture, int rate, int channels, int period, int nperiods ) {
  215. int err;
  216. snd_pcm_t *handle;
  217. snd_pcm_hw_params_t *hwparams;
  218. snd_pcm_sw_params_t *swparams;
  219. snd_pcm_hw_params_alloca(&hwparams);
  220. snd_pcm_sw_params_alloca(&swparams);
  221. if ((err = snd_pcm_open(&(handle), device_name, capture ? SND_PCM_STREAM_CAPTURE : SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK )) < 0) {
  222. printf("Capture open error: %s\n", snd_strerror(err));
  223. return NULL;
  224. }
  225. if ((err = set_hwparams(handle, hwparams,SND_PCM_ACCESS_RW_INTERLEAVED, rate, channels, period, nperiods )) < 0) {
  226. printf("Setting of hwparams failed: %s\n", snd_strerror(err));
  227. return NULL;
  228. }
  229. if ((err = set_swparams(handle, swparams, period, nperiods)) < 0) {
  230. printf("Setting of swparams failed: %s\n", snd_strerror(err));
  231. return NULL;
  232. }
  233. //snd_pcm_start( handle );
  234. //snd_pcm_wait( handle, 200 );
  235. int num_null_samples = nperiods * period * channels;
  236. ALSASAMPLE *tmp = alloca( num_null_samples * sizeof( ALSASAMPLE ) );
  237. memset( tmp, 0, num_null_samples * sizeof( ALSASAMPLE ) );
  238. snd_pcm_writei( handle, tmp, num_null_samples );
  239. return handle;
  240. }
  241. double hann( double x )
  242. {
  243. return 0.5 * (1.0 - cos( 2*M_PI * x ) );
  244. }
  245. int jumped = 0;
  246. int delay_offset = 0;
  247. /**
  248. * The process callback for this JACK application.
  249. * It is called by JACK at the appropriate times.
  250. */
  251. int process (jack_nframes_t nframes, void *arg) {
  252. ALSASAMPLE *outbuf;
  253. float *floatbuf, *resampbuf;
  254. int rlen;
  255. int err;
  256. snd_pcm_sframes_t delay = target_delay;
  257. snd_pcm_delay( alsa_handle, &delay );
  258. //delay -= jack_frames_since_cycle_start( client );
  259. // Do it the hard way.
  260. // this is for compensating xruns etc...
  261. if( delay > (target_delay+max_diff) ) {
  262. snd_pcm_rewind( alsa_handle, delay - target_delay );
  263. output_new_delay = (int) delay;
  264. delay = target_delay;
  265. //current_resample_factor = (double) sample_rate / (double) jack_sample_rate;
  266. current_resample_factor = resample_mean;
  267. jumped = 3;
  268. }
  269. if( delay < (target_delay-max_diff) ) {
  270. ALSASAMPLE *tmp = alloca( (target_delay-delay) * sizeof( ALSASAMPLE ) * num_channels );
  271. memset( tmp, 0, sizeof( ALSASAMPLE ) * num_channels * (target_delay-delay) );
  272. snd_pcm_writei( alsa_handle, tmp, target_delay-delay );
  273. output_new_delay = (int) delay;
  274. delay = target_delay;
  275. //current_resample_factor = (double) sample_rate / (double) jack_sample_rate;
  276. current_resample_factor = resample_mean;
  277. jumped = 3;
  278. }
  279. /* ok... now we should have target_delay +- max_diff on the alsa side.
  280. *
  281. * calculate the number of frames, we want to get.
  282. */
  283. double offset = delay - target_delay;
  284. #if 0
  285. double request_samples = nframes * current_resample_factor; //== alsa_samples;
  286. double frlen = request_samples - offset;
  287. // Calculate the added resampling factor, which would move us straight to target delay.
  288. double compute_factor = frlen / (double) nframes;
  289. // Now calculate the diff_value, which we want to add to current_resample_factor
  290. // here are the coefficients of the dll.
  291. double diff_value = pow(current_resample_factor - compute_factor, 3) / (double) catch_factor;
  292. diff_value += pow(current_resample_factor - compute_factor, 1) / (double) catch_factor2;
  293. #endif
  294. //smooth_offset_differential = 0.999 * smooth_offset_differential + 0.001 * (offset - old_offset);
  295. offset_array[offset_differential_index% OFF_D_SIZE ] = offset;
  296. if( jumped==0 ) //fabs(offset-old_offset) < 10.0 )
  297. offset_differential_array[(offset_differential_index++) % OFF_D_SIZE ] = offset-old_offset;
  298. else
  299. {
  300. jumped--;
  301. offset_differential_array[(offset_differential_index++) % OFF_D_SIZE ] = 0.0;
  302. }
  303. int i;
  304. double smooth_offset_differential = 0.0;
  305. for( i=0; i<OFF_D_SIZE; i++ )
  306. smooth_offset_differential +=
  307. offset_differential_array[ (i + offset_differential_index-1) % OFF_D_SIZE] * hann( (double) i / ((double) OFF_D_SIZE - 1.0) );
  308. smooth_offset_differential /= (double) OFF_D_SIZE;
  309. double smooth_offset = 0.0;
  310. for( i=0; i<OFF_D_SIZE; i++ )
  311. smooth_offset +=
  312. offset_array[ (i + offset_differential_index-1) % OFF_D_SIZE] * hann( (double) i / ((double) OFF_D_SIZE - 1.0) );
  313. smooth_offset /= (double) OFF_D_SIZE;
  314. ////////////////////////
  315. dd_resample_factor = 0.9999 * dd_resample_factor + 0.0001 * smooth_offset;
  316. //smooth_offset_differential = dd_resample_factor;
  317. ///////////////////////////////////
  318. old_offset = offset;
  319. offset_integral += smooth_offset;
  320. // Clamp offset.
  321. if( fabs( smooth_offset ) < 15.0 )
  322. smooth_offset = 0.0;
  323. current_resample_factor = 1.0 - smooth_offset / (double) catch_factor - offset_integral / (double) catch_factor / (double)catch_factor2;
  324. current_resample_factor = floor( current_resample_factor * 50000 + 0.5 ) / 50000;
  325. //current_resample_factor -= offset_integral / (double) nframes / (double)10000000 / (double) catch_factor;
  326. //current_resample_factor -= pow(smooth_offset/ (double) nframes, 3) / (double) catch_factor;
  327. //current_resample_factor -= dd_resample_factor/(double)nframes * 5.0;
  328. // Dampening:
  329. // use hysteresis, only do it once offset was more than 150 off,
  330. // and now came into 50samples window.
  331. // Also only damp when current_resample_factor is more than 0.01% off.
  332. #if 0
  333. if( good_window ) {
  334. if( (offset > max_diff*2/4) || (offset < -max_diff*2/4) ) {
  335. good_window = 0;
  336. }
  337. } else {
  338. if( (offset < 20) && (offset > -20) ) {
  339. if( 0.0001 < fabs( current_resample_factor - resample_mean ) )
  340. //current_resample_factor = ((double) sample_rate / (double) jack_sample_rate);
  341. current_resample_factor = resample_mean;
  342. good_window = 1;
  343. }
  344. }
  345. #endif
  346. // Output "instrumentatio" gonna change that to real instrumentation in a few.
  347. output_resampling_factor = (float) current_resample_factor;
  348. output_diff = (float) smooth_offset;
  349. output_integral = (float) offset_integral;
  350. output_offset = (float) offset;
  351. // Clamp a bit.
  352. if( current_resample_factor < 0.25 ) current_resample_factor = 0.25;
  353. if( current_resample_factor > 4 ) current_resample_factor = 4;
  354. // Now Calculate how many samples we need.
  355. rlen = ceil( ((double)nframes) * current_resample_factor )+2;
  356. assert( rlen > 10 );
  357. // Calculate resample_mean so we can init ourselves to saner values.
  358. resample_mean = 0.9999 * resample_mean + 0.0001 * current_resample_factor;
  359. /*
  360. * now this should do it...
  361. */
  362. outbuf = alloca( rlen * sizeof( ALSASAMPLE ) * num_channels );
  363. floatbuf = alloca( rlen * sizeof( float ) );
  364. resampbuf = alloca( nframes * sizeof( float ) );
  365. /*
  366. * render jack ports to the outbuf...
  367. */
  368. int chn = 0;
  369. JSList *node = playback_ports;
  370. JSList *src_node = playback_srcs;
  371. SRC_DATA src;
  372. while ( node != NULL)
  373. {
  374. int i;
  375. jack_port_t *port = (jack_port_t *) node->data;
  376. float *buf = jack_port_get_buffer (port, nframes);
  377. SRC_STATE *src_state = src_node->data;
  378. src.data_in = buf;
  379. src.input_frames = nframes;
  380. src.data_out = resampbuf;
  381. src.output_frames = rlen;
  382. src.end_of_input = 0;
  383. src.src_ratio = current_resample_factor;
  384. src_process( src_state, &src );
  385. for (i=0; i < rlen; i++) {
  386. float_16( resampbuf[i], outbuf[chn+ i*num_channels] );
  387. }
  388. src_node = jack_slist_next (src_node);
  389. node = jack_slist_next (node);
  390. chn++;
  391. }
  392. // now write the output...
  393. delay_offset += (nframes-src.output_frames_gen);
  394. again:
  395. err = snd_pcm_writei(alsa_handle, outbuf, src.output_frames_gen);
  396. //err = snd_pcm_writei(alsa_handle, outbuf, src.output_frames_gen);
  397. if( err < 0 ) {
  398. printf( "err = %d\n", err );
  399. if (xrun_recovery(alsa_handle, err) < 0) {
  400. printf("Write error: %s\n", snd_strerror(err));
  401. exit(EXIT_FAILURE);
  402. }
  403. goto again;
  404. }
  405. return 0;
  406. }
  407. /**
  408. * Allocate the necessary jack ports...
  409. */
  410. void alloc_ports( int n_capture, int n_playback ) {
  411. int port_flags = JackPortIsOutput;
  412. int chn;
  413. jack_port_t *port;
  414. char buf[32];
  415. capture_ports = NULL;
  416. for (chn = 0; chn < n_capture; chn++)
  417. {
  418. snprintf (buf, sizeof(buf) - 1, "capture_%u", chn+1);
  419. port = jack_port_register (client, buf,
  420. JACK_DEFAULT_AUDIO_TYPE,
  421. port_flags, 0);
  422. if (!port)
  423. {
  424. printf( "jacknet_client: cannot register port for %s", buf);
  425. break;
  426. }
  427. capture_srcs = jack_slist_append( capture_srcs, src_new( SRC_SINC_FASTEST, 1, NULL ) );
  428. capture_ports = jack_slist_append (capture_ports, port);
  429. }
  430. port_flags = JackPortIsInput;
  431. playback_ports = NULL;
  432. for (chn = 0; chn < n_playback; chn++)
  433. {
  434. snprintf (buf, sizeof(buf) - 1, "playback_%u", chn+1);
  435. port = jack_port_register (client, buf,
  436. JACK_DEFAULT_AUDIO_TYPE,
  437. port_flags, 0);
  438. if (!port)
  439. {
  440. printf( "jacknet_client: cannot register port for %s", buf);
  441. break;
  442. }
  443. playback_srcs = jack_slist_append( playback_srcs, src_new( SRC_SINC_FASTEST, 1, NULL ) );
  444. playback_ports = jack_slist_append (playback_ports, port);
  445. }
  446. }
  447. /**
  448. * This is the shutdown callback for this JACK application.
  449. * It is called by JACK if the server ever shuts down or
  450. * decides to disconnect the client.
  451. */
  452. void jack_shutdown (void *arg) {
  453. exit (1);
  454. }
  455. /**
  456. * be user friendly.
  457. * be user friendly.
  458. * be user friendly.
  459. */
  460. void printUsage() {
  461. fprintf(stderr, "usage: alsa_out [options]\n"
  462. "\n"
  463. " -j <jack name> - reports a different name to jack\n"
  464. " -d <alsa_device> \n"
  465. " -c <channels> \n"
  466. " -p <period_size> \n"
  467. " -n <num_period> \n"
  468. " -r <sample_rate> \n"
  469. " -m <max_diff> \n"
  470. " -t <target_delay> \n"
  471. " -f <catch_factor> \n"
  472. " -i turns on instrumentation\n"
  473. " -v turns on printouts\n"
  474. "\n");
  475. }
  476. /**
  477. * the main function....
  478. */
  479. int main (int argc, char *argv[]) {
  480. char jack_name[30] = "alsa_out";
  481. char alsa_device[30] = "hw:0";
  482. extern char *optarg;
  483. extern int optind, optopt;
  484. int errflg=0;
  485. int c;
  486. while ((c = getopt(argc, argv, "ivj:r:c:p:n:d:m:t:f:F:")) != -1) {
  487. switch(c) {
  488. case 'j':
  489. strcpy(jack_name,optarg);
  490. break;
  491. case 'r':
  492. sample_rate = atoi(optarg);
  493. break;
  494. case 'c':
  495. num_channels = atoi(optarg);
  496. break;
  497. case 'p':
  498. period_size = atoi(optarg);
  499. break;
  500. case 'n':
  501. num_periods = atoi(optarg);
  502. break;
  503. case 'd':
  504. strcpy(alsa_device,optarg);
  505. break;
  506. case 't':
  507. target_delay = atoi(optarg);
  508. break;
  509. case 'm':
  510. max_diff = atoi(optarg);
  511. break;
  512. case 'f':
  513. catch_factor = atoi(optarg);
  514. break;
  515. case 'F':
  516. catch_factor2 = atoi(optarg);
  517. break;
  518. case 'v':
  519. verbose = 1;
  520. break;
  521. case 'i':
  522. instrument = 1;
  523. break;
  524. case ':':
  525. fprintf(stderr,
  526. "Option -%c requires an operand\n", optopt);
  527. errflg++;
  528. break;
  529. case '?':
  530. fprintf(stderr,
  531. "Unrecognized option: -%c\n", optopt);
  532. errflg++;
  533. }
  534. }
  535. if (errflg) {
  536. printUsage();
  537. exit(2);
  538. }
  539. if ((client = jack_client_new (jack_name)) == 0) {
  540. fprintf (stderr, "jack server not running?\n");
  541. return 1;
  542. }
  543. /* tell the JACK server to call `process()' whenever
  544. there is work to be done.
  545. */
  546. jack_set_process_callback (client, process, 0);
  547. /* tell the JACK server to call `jack_shutdown()' if
  548. it ever shuts down, either entirely, or if it
  549. just decides to stop calling us.
  550. */
  551. jack_on_shutdown (client, jack_shutdown, 0);
  552. // alloc input ports, which are blasted out to alsa...
  553. alloc_ports( 0, num_channels );
  554. // get jack sample_rate
  555. jack_sample_rate = jack_get_sample_rate( client );
  556. if( !sample_rate )
  557. sample_rate = jack_sample_rate;
  558. current_resample_factor = (double) sample_rate / (double) jack_sample_rate;
  559. resample_mean = current_resample_factor;
  560. int i;
  561. for( i=0; i<OFF_D_SIZE; i++ )
  562. offset_differential_array[i] = 0.0;
  563. for( i=0; i<OFF_D_SIZE; i++ )
  564. offset_array[i] = 0.0;
  565. jack_buffer_size = jack_get_buffer_size( client );
  566. // Setup target delay and max_diff for the normal user, who does not play with them...
  567. if( !target_delay )
  568. target_delay = (num_periods*period_size / 2) - jack_buffer_size;
  569. if( !max_diff )
  570. max_diff = period_size / 2;
  571. if( max_diff > target_delay ) {
  572. fprintf( stderr, "target_delay (%d) cant be smaller than max_diff(%d)\n", target_delay, max_diff );
  573. exit(20);
  574. }
  575. if( (target_delay+max_diff) > (num_periods*period_size) ) {
  576. fprintf( stderr, "target_delay+max_diff (%d) cant be bigger than buffersize(%d)\n", target_delay+max_diff, num_periods*period_size );
  577. exit(20);
  578. }
  579. // now open the alsa fd...
  580. alsa_handle = open_audiofd( alsa_device, 0, sample_rate, num_channels, period_size, num_periods);
  581. if( alsa_handle < 0 )
  582. exit(20);
  583. /* tell the JACK server that we are ready to roll */
  584. if (jack_activate (client)) {
  585. fprintf (stderr, "cannot activate client");
  586. return 1;
  587. }
  588. if( verbose ) {
  589. while(1) {
  590. usleep(500000);
  591. if( output_new_delay ) {
  592. printf( "delay = %d\n", output_new_delay );
  593. output_new_delay = 0;
  594. }
  595. printf( "res: %f, \tdiff = %f, \toffset = %f \n", output_resampling_factor, output_diff, output_offset );
  596. }
  597. } else if( instrument ) {
  598. printf( "# n\tresamp\tdiff\toffseti\tintegral\n");
  599. int n=0;
  600. while(1) {
  601. usleep(1000);
  602. printf( "%d\t%f\t%f\t%f\t%f\n", n++, output_resampling_factor, output_diff, output_offset, output_integral );
  603. }
  604. } else {
  605. while(1) sleep(10);
  606. }
  607. jack_client_close (client);
  608. exit (0);
  609. }