00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <iostream>
00022 #include <unistd.h>
00023 #include <math.h>
00024 #include <stdio.h>
00025 #include <memory.h>
00026 #include <unistd.h>
00027 #include <stdlib.h>
00028 #include <errno.h>
00029 #include <stdarg.h>
00030 #include <signal.h>
00031 #include <sys/types.h>
00032 #include <sys/time.h>
00033 #include <regex.h>
00034 #include <string.h>
00035
00036 #include "JackAlsaDriver.h"
00037 #include "JackEngineControl.h"
00038 #include "JackClientControl.h"
00039 #include "JackPort.h"
00040 #include "JackGraphManager.h"
00041 #include "JackLockedEngine.h"
00042 #include "JackPosixThread.h"
00043 #include "JackCompilerDeps.h"
00044 #include "hammerfall.h"
00045 #include "hdsp.h"
00046 #include "ice1712.h"
00047 #include "usx2y.h"
00048 #include "generic.h"
00049 #include "memops.h"
00050
00051 namespace Jack
00052 {
00053
00054 typedef long AudioDeviceID;
00055
00056 #define jack_get_microseconds GetMicroSeconds
00057
00058
00059 #define XRUN_REPORT_DELAY 0
00060
00061 void
00062 JackAlsaDriver::alsa_driver_release_channel_dependent_memory (alsa_driver_t *driver)
00063 {
00064 bitset_destroy (&driver->channels_done);
00065 bitset_destroy (&driver->channels_not_done);
00066
00067 if (driver->playback_addr) {
00068 free (driver->playback_addr);
00069 driver->playback_addr = 0;
00070 }
00071
00072 if (driver->capture_addr) {
00073 free (driver->capture_addr);
00074 driver->capture_addr = 0;
00075 }
00076
00077 if (driver->playback_interleave_skip) {
00078 free (driver->playback_interleave_skip);
00079 driver->playback_interleave_skip = NULL;
00080 }
00081
00082 if (driver->capture_interleave_skip) {
00083 free (driver->capture_interleave_skip);
00084 driver->capture_interleave_skip = NULL;
00085 }
00086
00087 if (driver->silent) {
00088 free (driver->silent);
00089 driver->silent = 0;
00090 }
00091
00092 if (driver->dither_state) {
00093 free (driver->dither_state);
00094 driver->dither_state = 0;
00095 }
00096 }
00097
00098 int
00099 JackAlsaDriver::alsa_driver_check_capabilities (alsa_driver_t *driver)
00100 {
00101 return 0;
00102 }
00103
00104 int
00105 JackAlsaDriver::alsa_driver_check_card_type (alsa_driver_t *driver)
00106 {
00107 int err;
00108 snd_ctl_card_info_t *card_info;
00109 char * ctl_name;
00110 regex_t expression;
00111
00112 snd_ctl_card_info_alloca (&card_info);
00113
00114 regcomp(&expression, "(plug)?hw:[0-9](,[0-9])?", REG_ICASE | REG_EXTENDED);
00115
00116 if (!regexec(&expression, driver->alsa_name_playback, 0, NULL, 0)) {
00117
00118
00119
00120 char tmp[5];
00121 strncpy(tmp, strstr(driver->alsa_name_playback, "hw"), 4);
00122 tmp[4] = '\0';
00123 jack_log("control device %s", tmp);
00124 ctl_name = strdup(tmp);
00125 } else {
00126 ctl_name = strdup(driver->alsa_name_playback);
00127 }
00128
00129
00130
00131 if ((err = snd_ctl_open (&driver->ctl_handle, ctl_name, 0)) < 0) {
00132 jack_error ("control open \"%s\" (%s)", ctl_name,
00133 snd_strerror(err));
00134 return -1;
00135 }
00136
00137 if ((err = snd_ctl_card_info(driver->ctl_handle, card_info)) < 0) {
00138 jack_error ("control hardware info \"%s\" (%s)",
00139 driver->alsa_name_playback, snd_strerror (err));
00140 snd_ctl_close (driver->ctl_handle);
00141 return -1;
00142 }
00143
00144 driver->alsa_driver = strdup(snd_ctl_card_info_get_driver (card_info));
00145 jack_info("Using ALSA driver %s running on %s", driver->alsa_driver, snd_ctl_card_info_get_longname(card_info));
00146
00147 regfree(&expression);
00148 free(ctl_name);
00149
00150 return alsa_driver_check_capabilities (driver);
00151 }
00152
00153 int
00154 JackAlsaDriver::alsa_driver_hammerfall_hardware (alsa_driver_t *driver)
00155 {
00156 driver->hw = jack_alsa_hammerfall_hw_new (driver);
00157 return 0;
00158 }
00159
00160 int
00161 JackAlsaDriver::alsa_driver_hdsp_hardware (alsa_driver_t *driver)
00162 {
00163 driver->hw = jack_alsa_hdsp_hw_new (driver);
00164 return 0;
00165 }
00166
00167 int
00168 JackAlsaDriver::alsa_driver_ice1712_hardware (alsa_driver_t *driver)
00169 {
00170 driver->hw = jack_alsa_ice1712_hw_new (driver);
00171 return 0;
00172 }
00173
00174 int
00175 JackAlsaDriver::alsa_driver_usx2y_hardware (alsa_driver_t *driver)
00176 {
00177
00178
00179 return 0;
00180 }
00181
00182 int
00183 JackAlsaDriver::alsa_driver_generic_hardware (alsa_driver_t *driver)
00184 {
00185 driver->hw = jack_alsa_generic_hw_new (driver);
00186 return 0;
00187 }
00188
00189 int
00190 JackAlsaDriver::alsa_driver_hw_specific (alsa_driver_t *driver, int hw_monitoring,
00191 int hw_metering)
00192 {
00193 int err;
00194
00195 if (!strcmp(driver->alsa_driver, "RME9652")) {
00196 if ((err = alsa_driver_hammerfall_hardware (driver)) != 0) {
00197 return err;
00198 }
00199 } else if (!strcmp(driver->alsa_driver, "H-DSP")) {
00200 if ((err = alsa_driver_hdsp_hardware (driver)) != 0) {
00201 return err;
00202 }
00203 } else if (!strcmp(driver->alsa_driver, "ICE1712")) {
00204 if ((err = alsa_driver_ice1712_hardware (driver)) != 0) {
00205 return err;
00206 }
00207 }
00208
00209
00210
00211 else {
00212 if ((err = alsa_driver_generic_hardware (driver)) != 0) {
00213 return err;
00214 }
00215 }
00216
00217 if (driver->hw->capabilities & Cap_HardwareMonitoring) {
00218 driver->has_hw_monitoring = TRUE;
00219
00220
00221 driver->hw_monitoring = hw_monitoring;
00222 } else {
00223 driver->has_hw_monitoring = FALSE;
00224 driver->hw_monitoring = FALSE;
00225 }
00226
00227 if (driver->hw->capabilities & Cap_ClockLockReporting) {
00228 driver->has_clock_sync_reporting = TRUE;
00229 } else {
00230 driver->has_clock_sync_reporting = FALSE;
00231 }
00232
00233 if (driver->hw->capabilities & Cap_HardwareMetering) {
00234 driver->has_hw_metering = TRUE;
00235 driver->hw_metering = hw_metering;
00236 } else {
00237 driver->has_hw_metering = FALSE;
00238 driver->hw_metering = FALSE;
00239 }
00240
00241 return 0;
00242 }
00243
00244 void
00245 JackAlsaDriver::alsa_driver_setup_io_function_pointers (alsa_driver_t *driver)
00246 {
00247 if (SND_PCM_FORMAT_FLOAT_LE == driver->playback_sample_format) {
00248 if (driver->playback_interleaved) {
00249 driver->channel_copy = memcpy_interleave_d32_s32;
00250 } else {
00251 driver->channel_copy = memcpy_fake;
00252 }
00253 driver->read_via_copy = sample_move_floatLE_sSs;
00254 driver->write_via_copy = sample_move_dS_floatLE;
00255
00256 return;
00257 }
00258
00259 switch (driver->playback_sample_bytes) {
00260 case 2:
00261 if (driver->playback_interleaved) {
00262 driver->channel_copy = memcpy_interleave_d16_s16;
00263 } else {
00264 driver->channel_copy = memcpy_fake;
00265 }
00266
00267 switch (driver->dither) {
00268 case Rectangular:
00269 jack_log("Rectangular dithering at 16 bits");
00270 driver->write_via_copy = driver->quirk_bswap ?
00271 sample_move_dither_rect_d16_sSs :
00272 sample_move_dither_rect_d16_sS;
00273 break;
00274
00275 case Triangular:
00276 jack_log("Triangular dithering at 16 bits");
00277 driver->write_via_copy = driver->quirk_bswap ?
00278 sample_move_dither_tri_d16_sSs :
00279 sample_move_dither_tri_d16_sS;
00280 break;
00281
00282 case Shaped:
00283 jack_log("Noise-shaped dithering at 16 bits");
00284 driver->write_via_copy = driver->quirk_bswap ?
00285 sample_move_dither_shaped_d16_sSs :
00286 sample_move_dither_shaped_d16_sS;
00287 break;
00288
00289 default:
00290 driver->write_via_copy = driver->quirk_bswap ?
00291 sample_move_d16_sSs : sample_move_d16_sS;
00292 break;
00293 }
00294 break;
00295
00296 case 3:
00297 if (driver->playback_interleaved) {
00298 driver->channel_copy = memcpy_interleave_d24_s24;
00299 } else {
00300 driver->channel_copy = memcpy_fake;
00301 }
00302
00303 switch (driver->dither) {
00304 case Rectangular:
00305 jack_log("Rectangular dithering at 16 bits");
00306 driver->write_via_copy = driver->quirk_bswap ?
00307 sample_move_dither_rect_d24_sSs :
00308 sample_move_dither_rect_d24_sS;
00309 break;
00310
00311 case Triangular:
00312 jack_log("Triangular dithering at 16 bits");
00313 driver->write_via_copy = driver->quirk_bswap ?
00314 sample_move_dither_tri_d24_sSs :
00315 sample_move_dither_tri_d24_sS;
00316 break;
00317
00318 case Shaped:
00319 jack_log("Noise-shaped dithering at 16 bits");
00320 driver->write_via_copy = driver->quirk_bswap ?
00321 sample_move_dither_shaped_d24_sSs :
00322 sample_move_dither_shaped_d24_sS;
00323 break;
00324
00325 default:
00326 driver->write_via_copy = driver->quirk_bswap ?
00327 sample_move_d24_sSs : sample_move_d24_sS;
00328 break;
00329 }
00330 break;
00331
00332 case 4:
00333 if (driver->playback_interleaved) {
00334 driver->channel_copy = memcpy_interleave_d32_s32;
00335 } else {
00336 driver->channel_copy = memcpy_fake;
00337 }
00338
00339 switch (driver->dither) {
00340 case Rectangular:
00341 jack_log("Rectangular dithering at 16 bits");
00342 driver->write_via_copy = driver->quirk_bswap ?
00343 sample_move_dither_rect_d32u24_sSs :
00344 sample_move_dither_rect_d32u24_sS;
00345 break;
00346
00347 case Triangular:
00348 jack_log("Triangular dithering at 16 bits");
00349 driver->write_via_copy = driver->quirk_bswap ?
00350 sample_move_dither_tri_d32u24_sSs :
00351 sample_move_dither_tri_d32u24_sS;
00352 break;
00353
00354 case Shaped:
00355 jack_log("Noise-shaped dithering at 16 bits");
00356 driver->write_via_copy = driver->quirk_bswap ?
00357 sample_move_dither_shaped_d32u24_sSs :
00358 sample_move_dither_shaped_d32u24_sS;
00359 break;
00360
00361 default:
00362 driver->write_via_copy = driver->quirk_bswap ?
00363 sample_move_d32u24_sSs : sample_move_d32u24_sS;
00364 break;
00365 }
00366 break;
00367 }
00368
00369 switch (driver->capture_sample_bytes) {
00370 case 2:
00371 driver->read_via_copy = driver->quirk_bswap ?
00372 sample_move_dS_s16s : sample_move_dS_s16;
00373 break;
00374 case 3:
00375 driver->read_via_copy = driver->quirk_bswap ?
00376 sample_move_dS_s24s : sample_move_dS_s24;
00377 break;
00378 case 4:
00379 driver->read_via_copy = driver->quirk_bswap ?
00380 sample_move_dS_s32u24s : sample_move_dS_s32u24;
00381 break;
00382 }
00383 }
00384
00385 int
00386 JackAlsaDriver::alsa_driver_configure_stream (alsa_driver_t *driver, char *device_name,
00387 const char *stream_name,
00388 snd_pcm_t *handle,
00389 snd_pcm_hw_params_t *hw_params,
00390 snd_pcm_sw_params_t *sw_params,
00391 unsigned int *nperiodsp,
00392 unsigned long *nchns,
00393 unsigned long sample_width)
00394 {
00395 int err, format;
00396 unsigned int frame_rate;
00397 snd_pcm_uframes_t stop_th;
00398 static struct {
00399 char Name[32];
00400 snd_pcm_format_t format;
00401 int swapped;
00402 }
00403 formats[] = {
00404 {"32bit float little-endian", SND_PCM_FORMAT_FLOAT_LE},
00405 {"32bit little-endian", SND_PCM_FORMAT_S32_LE, IS_LE},
00406 {"32bit big-endian", SND_PCM_FORMAT_S32_BE, IS_BE},
00407 {"24bit little-endian", SND_PCM_FORMAT_S24_3LE, IS_LE},
00408 {"24bit big-endian", SND_PCM_FORMAT_S24_3BE, IS_BE},
00409 {"16bit little-endian", SND_PCM_FORMAT_S16_LE, IS_LE},
00410 {"16bit big-endian", SND_PCM_FORMAT_S16_BE, IS_BE},
00411 };
00412 #define NUMFORMATS (sizeof(formats)/sizeof(formats[0]))
00413 #define FIRST_16BIT_FORMAT 5
00414
00415 if ((err = snd_pcm_hw_params_any (handle, hw_params)) < 0) {
00416 jack_error ("ALSA: no playback configurations available (%s)",
00417 snd_strerror (err));
00418 return -1;
00419 }
00420
00421 if ((err = snd_pcm_hw_params_set_periods_integer (handle, hw_params))
00422 < 0) {
00423 jack_error ("ALSA: cannot restrict period size to integral"
00424 " value.");
00425 return -1;
00426 }
00427
00428 if ((err = snd_pcm_hw_params_set_access (handle, hw_params, SND_PCM_ACCESS_MMAP_NONINTERLEAVED)) < 0) {
00429 if ((err = snd_pcm_hw_params_set_access (handle, hw_params, SND_PCM_ACCESS_MMAP_INTERLEAVED)) < 0) {
00430 if ((err = snd_pcm_hw_params_set_access (
00431 handle, hw_params,
00432 SND_PCM_ACCESS_MMAP_COMPLEX)) < 0) {
00433 jack_error ("ALSA: mmap-based access is not possible"
00434 " for the %s "
00435 "stream of this audio interface",
00436 stream_name);
00437 return -1;
00438 }
00439 }
00440 }
00441
00442 format = (sample_width == 4) ? 0 : NUMFORMATS - 1;
00443
00444 while (1) {
00445 if ((err = snd_pcm_hw_params_set_format (
00446 handle, hw_params, formats[format].format)) < 0) {
00447
00448 if ((sample_width == 4
00449 ? format++ >= (int)NUMFORMATS - 1
00450 : format-- <= 0)) {
00451 jack_error ("Sorry. The audio interface \"%s\""
00452 " doesn't support any of the"
00453 " hardware sample formats that"
00454 " JACK's alsa-driver can use.",
00455 device_name);
00456 return -1;
00457 }
00458 } else {
00459 if (formats[format].swapped) {
00460 driver->quirk_bswap = 1;
00461 } else {
00462 driver->quirk_bswap = 0;
00463 }
00464 jack_info ("ALSA: final selected sample format for %s: %s", stream_name, formats[format].Name);
00465 break;
00466 }
00467 }
00468
00469 frame_rate = driver->frame_rate ;
00470 err = snd_pcm_hw_params_set_rate_near (handle, hw_params,
00471 &frame_rate, NULL) ;
00472 driver->frame_rate = frame_rate ;
00473 if (err < 0) {
00474 jack_error ("ALSA: cannot set sample/frame rate to %ld for %s", driver->frame_rate, stream_name);
00475 return -1;
00476 }
00477 if (!*nchns) {
00478
00479
00480 unsigned int channels_max ;
00481 err = snd_pcm_hw_params_get_channels_max (hw_params,
00482 &channels_max);
00483 *nchns = channels_max ;
00484
00485 if (*nchns > 1024) {
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495 jack_error (
00496 "You appear to be using the ALSA software \"plug\" layer, probably\n"
00497 "a result of using the \"default\" ALSA device. This is less\n"
00498 "efficient than it could be. Consider using a hardware device\n"
00499 "instead rather than using the plug layer. Usually the name of the\n"
00500 "hardware device that corresponds to the first sound card is hw:0\n"
00501 );
00502 *nchns = 2;
00503 }
00504 }
00505
00506 if ((err = snd_pcm_hw_params_set_channels (handle, hw_params,
00507 *nchns)) < 0) {
00508 jack_error ("ALSA: cannot set channel count to %u for %s",
00509 *nchns, stream_name);
00510 return -1;
00511 }
00512
00513 if ((err = snd_pcm_hw_params_set_period_size (handle, hw_params,
00514 driver->frames_per_cycle,
00515 0))
00516 < 0) {
00517 jack_error ("ALSA: cannot set period size to %ld frames for %s", driver->frames_per_cycle, stream_name);
00518 return -1;
00519 }
00520
00521 *nperiodsp = driver->user_nperiods;
00522 snd_pcm_hw_params_set_periods_min (handle, hw_params, nperiodsp, NULL);
00523 if (*nperiodsp < driver->user_nperiods)
00524 *nperiodsp = driver->user_nperiods;
00525 if (snd_pcm_hw_params_set_periods_near (handle, hw_params,
00526 nperiodsp, NULL) < 0) {
00527 jack_error ("ALSA: cannot set number of periods to %u for %s",
00528 *nperiodsp, stream_name);
00529 return -1;
00530 }
00531
00532 if (*nperiodsp < driver->user_nperiods) {
00533 jack_error ("ALSA: got smaller periods %u than %u for %s",
00534 *nperiodsp, (unsigned int) driver->user_nperiods,
00535 stream_name);
00536 return -1;
00537 }
00538 jack_info ("ALSA: use %d periods for %s", *nperiodsp, stream_name);
00539
00540
00541
00542
00543
00544
00545
00546
00547 if ((err = snd_pcm_hw_params_set_buffer_size (handle, hw_params,
00548 *nperiodsp *
00549 driver->frames_per_cycle))
00550 < 0) {
00551 jack_error ("ALSA: cannot set buffer length to %ld for %s", *nperiodsp * driver->frames_per_cycle,
00552 stream_name);
00553 return -1;
00554 }
00555
00556 if ((err = snd_pcm_hw_params (handle, hw_params)) < 0) {
00557 jack_error ("ALSA: cannot set hardware parameters for %s",
00558 stream_name);
00559 return -1;
00560 }
00561
00562 snd_pcm_sw_params_current (handle, sw_params);
00563
00564 if ((err = snd_pcm_sw_params_set_start_threshold (handle, sw_params,
00565 0U)) < 0) {
00566 jack_error ("ALSA: cannot set start mode for %s", stream_name);
00567 return -1;
00568 }
00569
00570 stop_th = *nperiodsp * driver->frames_per_cycle;
00571 if (driver->soft_mode) {
00572 stop_th = (snd_pcm_uframes_t) - 1;
00573 }
00574
00575 if ((err = snd_pcm_sw_params_set_stop_threshold (
00576 handle, sw_params, stop_th)) < 0) {
00577 jack_error ("ALSA: cannot set stop mode for %s",
00578 stream_name);
00579 return -1;
00580 }
00581
00582 if ((err = snd_pcm_sw_params_set_silence_threshold (
00583 handle, sw_params, 0)) < 0) {
00584 jack_error ("ALSA: cannot set silence threshold for %s",
00585 stream_name);
00586 return -1;
00587 }
00588
00589 #if 0
00590 fprintf (stderr, "set silence size to %lu * %lu = %lu\n",
00591 driver->frames_per_cycle, *nperiodsp,
00592 driver->frames_per_cycle * *nperiodsp);
00593
00594 if ((err = snd_pcm_sw_params_set_silence_size (
00595 handle, sw_params,
00596 driver->frames_per_cycle * *nperiodsp)) < 0) {
00597 jack_error ("ALSA: cannot set silence size for %s",
00598 stream_name);
00599 return -1;
00600 }
00601 #endif
00602
00603 if (handle == driver->playback_handle)
00604 err = snd_pcm_sw_params_set_avail_min (
00605 handle, sw_params,
00606 driver->frames_per_cycle
00607 * (*nperiodsp - driver->user_nperiods + 1));
00608 else
00609 err = snd_pcm_sw_params_set_avail_min (
00610 handle, sw_params, driver->frames_per_cycle);
00611
00612 if (err < 0) {
00613 jack_error ("ALSA: cannot set avail min for %s", stream_name);
00614 return -1;
00615 }
00616
00617 if ((err = snd_pcm_sw_params (handle, sw_params)) < 0) {
00618 jack_error ("ALSA: cannot set software parameters for %s\n",
00619 stream_name);
00620 return -1;
00621 }
00622
00623 return 0;
00624 }
00625
00626 int
00627 JackAlsaDriver::alsa_driver_set_parameters (alsa_driver_t *driver,
00628 jack_nframes_t frames_per_cycle,
00629 jack_nframes_t user_nperiods,
00630 jack_nframes_t rate)
00631 {
00632 int dir;
00633 snd_pcm_uframes_t p_period_size = 0;
00634 snd_pcm_uframes_t c_period_size = 0;
00635 channel_t chn;
00636 unsigned int pr = 0;
00637 unsigned int cr = 0;
00638 int err;
00639
00640 driver->frame_rate = rate;
00641 driver->frames_per_cycle = frames_per_cycle;
00642 driver->user_nperiods = user_nperiods;
00643
00644
00645
00646
00647
00648
00649
00650 if (driver->capture_handle) {
00651 if (alsa_driver_configure_stream (
00652 driver,
00653 driver->alsa_name_capture,
00654 "capture",
00655 driver->capture_handle,
00656 driver->capture_hw_params,
00657 driver->capture_sw_params,
00658 &driver->capture_nperiods,
00659 (long unsigned int*)&driver->capture_nchannels,
00660 driver->capture_sample_bytes)) {
00661 jack_error ("ALSA: cannot configure capture channel");
00662 return -1;
00663 }
00664 }
00665
00666 if (driver->playback_handle) {
00667 if (alsa_driver_configure_stream (
00668 driver,
00669 driver->alsa_name_playback,
00670 "playback",
00671 driver->playback_handle,
00672 driver->playback_hw_params,
00673 driver->playback_sw_params,
00674 &driver->playback_nperiods,
00675 (long unsigned int*)&driver->playback_nchannels,
00676 driver->playback_sample_bytes)) {
00677 jack_error ("ALSA: cannot configure playback channel");
00678 return -1;
00679 }
00680 }
00681
00682
00683
00684 if (driver->playback_handle) {
00685 snd_pcm_hw_params_get_rate (driver->playback_hw_params,
00686 &pr, &dir);
00687 }
00688
00689 if (driver->capture_handle) {
00690 snd_pcm_hw_params_get_rate (driver->capture_hw_params,
00691 &cr, &dir);
00692 }
00693
00694 if (driver->capture_handle && driver->playback_handle) {
00695 if (cr != pr) {
00696 jack_error ("playback and capture sample rates do "
00697 "not match (%d vs. %d)", pr, cr);
00698 }
00699
00700
00701
00702
00703
00704
00705 if (cr != driver->frame_rate && pr != driver->frame_rate) {
00706 jack_error ("sample rate in use (%d Hz) does not "
00707 "match requested rate (%d Hz)",
00708 cr, driver->frame_rate);
00709 driver->frame_rate = cr;
00710 }
00711
00712 } else if (driver->capture_handle && cr != driver->frame_rate) {
00713 jack_error ("capture sample rate in use (%d Hz) does not "
00714 "match requested rate (%d Hz)",
00715 cr, driver->frame_rate);
00716 driver->frame_rate = cr;
00717 } else if (driver->playback_handle && pr != driver->frame_rate) {
00718 jack_error ("playback sample rate in use (%d Hz) does not "
00719 "match requested rate (%d Hz)",
00720 pr, driver->frame_rate);
00721 driver->frame_rate = pr;
00722 }
00723
00724
00725
00726
00727 if (driver->playback_handle) {
00728 snd_pcm_access_t access;
00729
00730 err = snd_pcm_hw_params_get_period_size (
00731 driver->playback_hw_params, &p_period_size, &dir);
00732 err = snd_pcm_hw_params_get_format (
00733 driver->playback_hw_params,
00734 &(driver->playback_sample_format));
00735 err = snd_pcm_hw_params_get_access (driver->playback_hw_params,
00736 &access);
00737 driver->playback_interleaved =
00738 (access == SND_PCM_ACCESS_MMAP_INTERLEAVED)
00739 || (access == SND_PCM_ACCESS_MMAP_COMPLEX);
00740
00741 if (p_period_size != driver->frames_per_cycle) {
00742
00743
00744
00745
00746
00747
00748 return -1;
00749 }
00750 }
00751
00752 if (driver->capture_handle) {
00753 snd_pcm_access_t access;
00754
00755 err = snd_pcm_hw_params_get_period_size (
00756 driver->capture_hw_params, &c_period_size, &dir);
00757 err = snd_pcm_hw_params_get_format (
00758 driver->capture_hw_params,
00759 &(driver->capture_sample_format));
00760 err = snd_pcm_hw_params_get_access (driver->capture_hw_params,
00761 &access);
00762 driver->capture_interleaved =
00763 (access == SND_PCM_ACCESS_MMAP_INTERLEAVED)
00764 || (access == SND_PCM_ACCESS_MMAP_COMPLEX);
00765
00766
00767 if (c_period_size != driver->frames_per_cycle) {
00768
00769
00770
00771
00772
00773
00774 return -1;
00775 }
00776 }
00777
00778 driver->playback_sample_bytes =
00779 snd_pcm_format_physical_width (driver->playback_sample_format)
00780 / 8;
00781 driver->capture_sample_bytes =
00782 snd_pcm_format_physical_width (driver->capture_sample_format)
00783 / 8;
00784
00785 if (driver->playback_handle) {
00786 switch (driver->playback_sample_format) {
00787 case SND_PCM_FORMAT_FLOAT_LE:
00788 case SND_PCM_FORMAT_S32_LE:
00789 case SND_PCM_FORMAT_S24_3LE:
00790 case SND_PCM_FORMAT_S24_3BE:
00791 case SND_PCM_FORMAT_S16_LE:
00792 case SND_PCM_FORMAT_S32_BE:
00793 case SND_PCM_FORMAT_S16_BE:
00794 break;
00795
00796 default:
00797 jack_error ("programming error: unhandled format "
00798 "type for playback");
00799 exit (1);
00800 }
00801 }
00802
00803 if (driver->capture_handle) {
00804 switch (driver->capture_sample_format) {
00805 case SND_PCM_FORMAT_FLOAT_LE:
00806 case SND_PCM_FORMAT_S32_LE:
00807 case SND_PCM_FORMAT_S24_3LE:
00808 case SND_PCM_FORMAT_S24_3BE:
00809 case SND_PCM_FORMAT_S16_LE:
00810 case SND_PCM_FORMAT_S32_BE:
00811 case SND_PCM_FORMAT_S16_BE:
00812 break;
00813
00814 default:
00815 jack_error ("programming error: unhandled format "
00816 "type for capture");
00817 exit (1);
00818 }
00819 }
00820
00821 if (driver->playback_interleaved) {
00822 const snd_pcm_channel_area_t *my_areas;
00823 snd_pcm_uframes_t offset, frames;
00824 if (snd_pcm_mmap_begin(driver->playback_handle,
00825 &my_areas, &offset, &frames) < 0) {
00826 jack_error ("ALSA: %s: mmap areas info error",
00827 driver->alsa_name_playback);
00828 return -1;
00829 }
00830 driver->interleave_unit =
00831 snd_pcm_format_physical_width (
00832 driver->playback_sample_format) / 8;
00833 } else {
00834 driver->interleave_unit = 0;
00835 }
00836
00837 if (driver->capture_interleaved) {
00838 const snd_pcm_channel_area_t *my_areas;
00839 snd_pcm_uframes_t offset, frames;
00840 if (snd_pcm_mmap_begin(driver->capture_handle,
00841 &my_areas, &offset, &frames) < 0) {
00842 jack_error ("ALSA: %s: mmap areas info error",
00843 driver->alsa_name_capture);
00844 return -1;
00845 }
00846 }
00847
00848 if (driver->playback_nchannels > driver->capture_nchannels) {
00849 driver->max_nchannels = driver->playback_nchannels;
00850 driver->user_nchannels = driver->capture_nchannels;
00851 } else {
00852 driver->max_nchannels = driver->capture_nchannels;
00853 driver->user_nchannels = driver->playback_nchannels;
00854 }
00855
00856 alsa_driver_setup_io_function_pointers (driver);
00857
00858
00859
00860
00861
00862
00863
00864
00865
00866
00867 bitset_create (&driver->channels_done, driver->max_nchannels);
00868 bitset_create (&driver->channels_not_done, driver->max_nchannels);
00869
00870 if (driver->playback_handle) {
00871 driver->playback_addr = (char **)
00872 malloc (sizeof (char *) * driver->playback_nchannels);
00873 memset (driver->playback_addr, 0,
00874 sizeof (char *) * driver->playback_nchannels);
00875 driver->playback_interleave_skip = (unsigned long *)
00876 malloc (sizeof (unsigned long *) * driver->playback_nchannels);
00877 memset (driver->playback_interleave_skip, 0,
00878 sizeof (unsigned long *) * driver->playback_nchannels);
00879 driver->silent = (unsigned long *)
00880 malloc (sizeof (unsigned long)
00881 * driver->playback_nchannels);
00882
00883 for (chn = 0; chn < driver->playback_nchannels; chn++) {
00884 driver->silent[chn] = 0;
00885 }
00886
00887 for (chn = 0; chn < driver->playback_nchannels; chn++) {
00888 bitset_add (driver->channels_done, chn);
00889 }
00890
00891 driver->dither_state = (dither_state_t *)
00892 calloc ( driver->playback_nchannels,
00893 sizeof (dither_state_t));
00894 }
00895
00896 if (driver->capture_handle) {
00897 driver->capture_addr = (char **)
00898 malloc (sizeof (char *) * driver->capture_nchannels);
00899 memset (driver->capture_addr, 0,
00900 sizeof (char *) * driver->capture_nchannels);
00901 driver->capture_interleave_skip = (unsigned long *)
00902 malloc (sizeof (unsigned long *) * driver->capture_nchannels);
00903 memset (driver->capture_interleave_skip, 0,
00904 sizeof (unsigned long *) * driver->capture_nchannels);
00905 }
00906
00907 driver->clock_sync_data = (ClockSyncStatus *)
00908 malloc (sizeof (ClockSyncStatus) * driver->max_nchannels);
00909
00910 driver->period_usecs =
00911 (jack_time_t) floor ((((float) driver->frames_per_cycle) /
00912 driver->frame_rate) * 1000000.0f);
00913 driver->poll_timeout = (int) floor (1.5f * driver->period_usecs);
00914
00915
00916
00917
00918
00919
00920
00921
00922 return 0;
00923 }
00924
00925 int
00926 JackAlsaDriver::alsa_driver_reset_parameters (alsa_driver_t *driver,
00927 jack_nframes_t frames_per_cycle,
00928 jack_nframes_t user_nperiods,
00929 jack_nframes_t rate)
00930 {
00931
00932 alsa_driver_release_channel_dependent_memory (driver);
00933 return alsa_driver_set_parameters (driver,
00934 frames_per_cycle,
00935 user_nperiods, rate);
00936 }
00937
00938 int
00939 JackAlsaDriver::alsa_driver_get_channel_addresses (alsa_driver_t *driver,
00940 snd_pcm_uframes_t *capture_avail,
00941 snd_pcm_uframes_t *playback_avail,
00942 snd_pcm_uframes_t *capture_offset,
00943 snd_pcm_uframes_t *playback_offset)
00944 {
00945 unsigned long err;
00946 channel_t chn;
00947
00948 if (capture_avail) {
00949 if ((err = snd_pcm_mmap_begin (
00950 driver->capture_handle, &driver->capture_areas,
00951 (snd_pcm_uframes_t *) capture_offset,
00952 (snd_pcm_uframes_t *) capture_avail)) < 0) {
00953 jack_error ("ALSA: %s: mmap areas info error",
00954 driver->alsa_name_capture);
00955 return -1;
00956 }
00957
00958 for (chn = 0; chn < driver->capture_nchannels; chn++) {
00959 const snd_pcm_channel_area_t *a =
00960 &driver->capture_areas[chn];
00961 driver->capture_addr[chn] = (char *) a->addr
00962 + ((a->first + a->step * *capture_offset) / 8);
00963 driver->capture_interleave_skip[chn] = (unsigned long ) (a->step / 8);
00964 }
00965 }
00966
00967 if (playback_avail) {
00968 if ((err = snd_pcm_mmap_begin (
00969 driver->playback_handle, &driver->playback_areas,
00970 (snd_pcm_uframes_t *) playback_offset,
00971 (snd_pcm_uframes_t *) playback_avail)) < 0) {
00972 jack_error ("ALSA: %s: mmap areas info error ",
00973 driver->alsa_name_playback);
00974 return -1;
00975 }
00976
00977 for (chn = 0; chn < driver->playback_nchannels; chn++) {
00978 const snd_pcm_channel_area_t *a =
00979 &driver->playback_areas[chn];
00980 driver->playback_addr[chn] = (char *) a->addr
00981 + ((a->first + a->step * *playback_offset) / 8);
00982 driver->playback_interleave_skip[chn] = (unsigned long ) (a->step / 8);
00983 }
00984 }
00985
00986 return 0;
00987 }
00988
00989 int
00990 JackAlsaDriver::alsa_driver_start (alsa_driver_t *driver)
00991 {
00992 int err;
00993 snd_pcm_uframes_t poffset, pavail;
00994 channel_t chn;
00995
00996 driver->poll_last = 0;
00997 driver->poll_next = 0;
00998
00999 if (driver->playback_handle) {
01000 if ((err = snd_pcm_prepare (driver->playback_handle)) < 0) {
01001 jack_error ("ALSA: prepare error for playback on "
01002 "\"%s\" (%s)", driver->alsa_name_playback,
01003 snd_strerror(err));
01004 return -1;
01005 }
01006 }
01007
01008 if ((driver->capture_handle && driver->capture_and_playback_not_synced)
01009 || !driver->playback_handle) {
01010 if ((err = snd_pcm_prepare (driver->capture_handle)) < 0) {
01011 jack_error ("ALSA: prepare error for capture on \"%s\""
01012 " (%s)", driver->alsa_name_capture,
01013 snd_strerror(err));
01014 return -1;
01015 }
01016 }
01017
01018 if (driver->hw_monitoring) {
01019 if (driver->input_monitor_mask || driver->all_monitor_in) {
01020 if (driver->all_monitor_in) {
01021 driver->hw->set_input_monitor_mask (driver->hw, ~0U);
01022 } else {
01023 driver->hw->set_input_monitor_mask (
01024 driver->hw, driver->input_monitor_mask);
01025 }
01026 } else {
01027 driver->hw->set_input_monitor_mask (driver->hw,
01028 driver->input_monitor_mask);
01029 }
01030 }
01031
01032 if (driver->playback_handle) {
01033 driver->playback_nfds =
01034 snd_pcm_poll_descriptors_count (driver->playback_handle);
01035 } else {
01036 driver->playback_nfds = 0;
01037 }
01038
01039 if (driver->capture_handle) {
01040 driver->capture_nfds =
01041 snd_pcm_poll_descriptors_count (driver->capture_handle);
01042 } else {
01043 driver->capture_nfds = 0;
01044 }
01045
01046 if (driver->pfd) {
01047 free (driver->pfd);
01048 }
01049
01050 driver->pfd = (struct pollfd *)
01051 malloc (sizeof (struct pollfd) *
01052 (driver->playback_nfds + driver->capture_nfds + 2));
01053
01054 if (driver->midi && !driver->xrun_recovery)
01055 (driver->midi->start)(driver->midi);
01056
01057 if (driver->playback_handle) {
01058
01059
01060
01061
01062 pavail = snd_pcm_avail_update (driver->playback_handle);
01063
01064 if (pavail !=
01065 driver->frames_per_cycle * driver->playback_nperiods) {
01066 jack_error ("ALSA: full buffer not available at start");
01067 return -1;
01068 }
01069
01070 if (alsa_driver_get_channel_addresses (driver,
01071 0, &pavail, 0, &poffset)) {
01072 return -1;
01073 }
01074
01075
01076
01077
01078
01079
01080
01081
01082
01083
01084 for (chn = 0; chn < driver->playback_nchannels; chn++) {
01085 alsa_driver_silence_on_channel (
01086 driver, chn,
01087 driver->user_nperiods
01088 * driver->frames_per_cycle);
01089 }
01090
01091 snd_pcm_mmap_commit (driver->playback_handle, poffset,
01092 driver->user_nperiods
01093 * driver->frames_per_cycle);
01094
01095 if ((err = snd_pcm_start (driver->playback_handle)) < 0) {
01096 jack_error ("ALSA: could not start playback (%s)",
01097 snd_strerror (err));
01098 return -1;
01099 }
01100 }
01101
01102 if ((driver->capture_handle && driver->capture_and_playback_not_synced)
01103 || !driver->playback_handle) {
01104 if ((err = snd_pcm_start (driver->capture_handle)) < 0) {
01105 jack_error ("ALSA: could not start capture (%s)",
01106 snd_strerror (err));
01107 return -1;
01108 }
01109 }
01110
01111 return 0;
01112 }
01113
01114 int
01115 JackAlsaDriver::alsa_driver_stop (alsa_driver_t *driver)
01116 {
01117 int err;
01118
01119
01120
01121
01122
01123
01124
01125
01126
01127
01128
01129
01130
01131
01132
01133
01134
01135
01136
01137
01138
01139
01140 for (int i = 0; i < fPlaybackChannels; i++) {
01141 jack_default_audio_sample_t* buf =
01142 (jack_default_audio_sample_t*)fGraphManager->GetBuffer(fPlaybackPortList[i], fEngineControl->fBufferSize);
01143 memset (buf, 0, sizeof (jack_default_audio_sample_t) * fEngineControl->fBufferSize);
01144 }
01145
01146 if (driver->playback_handle) {
01147 if ((err = snd_pcm_drop (driver->playback_handle)) < 0) {
01148 jack_error ("ALSA: channel flush for playback "
01149 "failed (%s)", snd_strerror (err));
01150 return -1;
01151 }
01152 }
01153
01154 if (!driver->playback_handle
01155 || driver->capture_and_playback_not_synced) {
01156 if (driver->capture_handle) {
01157 if ((err = snd_pcm_drop (driver->capture_handle)) < 0) {
01158 jack_error ("ALSA: channel flush for "
01159 "capture failed (%s)",
01160 snd_strerror (err));
01161 return -1;
01162 }
01163 }
01164 }
01165
01166 if (driver->hw_monitoring) {
01167 driver->hw->set_input_monitor_mask (driver->hw, 0);
01168 }
01169
01170 if (driver->midi && !driver->xrun_recovery)
01171 (driver->midi->stop)(driver->midi);
01172
01173 return 0;
01174 }
01175
01176 int
01177 JackAlsaDriver::alsa_driver_restart (alsa_driver_t *driver)
01178 {
01179
01180
01181
01182
01183
01184
01185
01186 driver->xrun_recovery = 1;
01187 int res = Stop();
01188 if (!res)
01189 res = Start();
01190 driver->xrun_recovery = 0;
01191 return res;
01192 }
01193
01194 int
01195 JackAlsaDriver::alsa_driver_xrun_recovery (alsa_driver_t *driver, float *delayed_usecs)
01196 {
01197 snd_pcm_status_t *status;
01198 int res;
01199
01200 jack_error("alsa_driver_xrun_recovery");
01201
01202 snd_pcm_status_alloca(&status);
01203
01204 if (driver->capture_handle) {
01205 if ((res = snd_pcm_status(driver->capture_handle, status))
01206 < 0) {
01207 jack_error("status error: %s", snd_strerror(res));
01208 }
01209 } else {
01210 if ((res = snd_pcm_status(driver->playback_handle, status))
01211 < 0) {
01212 jack_error("status error: %s", snd_strerror(res));
01213 }
01214 }
01215
01216 if (snd_pcm_status_get_state(status) == SND_PCM_STATE_XRUN
01217 && driver->process_count > XRUN_REPORT_DELAY) {
01218 struct timeval now, diff, tstamp;
01219 driver->xrun_count++;
01220 snd_pcm_status_get_tstamp(status,&now);
01221 snd_pcm_status_get_trigger_tstamp(status, &tstamp);
01222 timersub(&now, &tstamp, &diff);
01223 *delayed_usecs = diff.tv_sec * 1000000.0 + diff.tv_usec;
01224
01225
01226 jack_error("\n\n**** alsa_pcm: xrun of at least %.3f msecs\n\n", *delayed_usecs / 1000.0);
01227 }
01228
01229 if (alsa_driver_restart (driver)) {
01230 return -1;
01231 }
01232 return 0;
01233 }
01234
01235 void
01236 JackAlsaDriver::alsa_driver_silence_untouched_channels (alsa_driver_t *driver,
01237 jack_nframes_t nframes)
01238 {
01239 channel_t chn;
01240 jack_nframes_t buffer_frames =
01241 driver->frames_per_cycle * driver->playback_nperiods;
01242
01243 for (chn = 0; chn < driver->playback_nchannels; chn++) {
01244 if (bitset_contains (driver->channels_not_done, chn)) {
01245 if (driver->silent[chn] < buffer_frames) {
01246 alsa_driver_silence_on_channel_no_mark (
01247 driver, chn, nframes);
01248 driver->silent[chn] += nframes;
01249 }
01250 }
01251 }
01252 }
01253
01254 jack_nframes_t
01255 JackAlsaDriver::alsa_driver_wait (alsa_driver_t *driver, int extra_fd, int *status, float
01256 *delayed_usecs)
01257 {
01258 snd_pcm_sframes_t avail = 0;
01259 snd_pcm_sframes_t capture_avail = 0;
01260 snd_pcm_sframes_t playback_avail = 0;
01261 int xrun_detected = FALSE;
01262 int need_capture;
01263 int need_playback;
01264 unsigned int i;
01265 jack_time_t poll_enter;
01266 jack_time_t poll_ret = 0;
01267
01268 *status = -1;
01269 *delayed_usecs = 0;
01270
01271 need_capture = driver->capture_handle ? 1 : 0;
01272
01273 if (extra_fd >= 0) {
01274 need_playback = 0;
01275 } else {
01276 need_playback = driver->playback_handle ? 1 : 0;
01277 }
01278
01279
01280
01281
01282 while (need_playback || need_capture) {
01283
01284 unsigned int p_timed_out, c_timed_out;
01285 unsigned int ci = 0;
01286 unsigned int nfds;
01287
01288 nfds = 0;
01289
01290 if (need_playback) {
01291 snd_pcm_poll_descriptors (driver->playback_handle,
01292 &driver->pfd[0],
01293 driver->playback_nfds);
01294 nfds += driver->playback_nfds;
01295 }
01296
01297 if (need_capture) {
01298 snd_pcm_poll_descriptors (driver->capture_handle,
01299 &driver->pfd[nfds],
01300 driver->capture_nfds);
01301 ci = nfds;
01302 nfds += driver->capture_nfds;
01303 }
01304
01305
01306
01307 for (i = 0; i < nfds; i++) {
01308 driver->pfd[i].events |= POLLERR;
01309 }
01310
01311 if (extra_fd >= 0) {
01312 driver->pfd[nfds].fd = extra_fd;
01313 driver->pfd[nfds].events =
01314 POLLIN | POLLERR | POLLHUP | POLLNVAL;
01315 nfds++;
01316 }
01317
01318 poll_enter = jack_get_microseconds ();
01319
01320 if (poll_enter > driver->poll_next) {
01321
01322
01323
01324
01325
01326 driver->poll_next = 0;
01327 driver->poll_late++;
01328 }
01329
01330 if (poll (driver->pfd, nfds, driver->poll_timeout) < 0) {
01331
01332 if (errno == EINTR) {
01333 jack_log("poll interrupt");
01334
01335
01336
01337
01338
01339
01340
01341
01342 *status = -2;
01343 return 0;
01344 }
01345
01346 jack_error ("ALSA: poll call failed (%s)",
01347 strerror (errno));
01348 *status = -3;
01349 return 0;
01350
01351 }
01352
01353 poll_ret = jack_get_microseconds ();
01354
01355 fBeginDateUst = poll_ret;
01356
01357 if (extra_fd < 0) {
01358 if (driver->poll_next && poll_ret > driver->poll_next) {
01359 *delayed_usecs = poll_ret - driver->poll_next;
01360 }
01361 driver->poll_last = poll_ret;
01362 driver->poll_next = poll_ret + driver->period_usecs;
01363
01364
01365
01366
01367
01368
01369
01370 }
01371
01372 #ifdef DEBUG_WAKEUP
01373 fprintf (stderr, "%" PRIu64 ": checked %d fds, %" PRIu64
01374 " usecs since poll entered\n", poll_ret, nfds,
01375 poll_ret - poll_enter);
01376 #endif
01377
01378
01379
01380
01381 if (extra_fd >= 0) {
01382
01383 if (driver->pfd[nfds - 1].revents == 0) {
01384
01385
01386 *status = -4;
01387
01388
01389
01390 return 0;
01391 }
01392
01393
01394
01395 *status = 0;
01396 return (driver->pfd[nfds - 1].revents == POLLIN) ? 0 : -1;
01397 }
01398
01399 p_timed_out = 0;
01400
01401 if (need_playback) {
01402 for (i = 0; i < driver->playback_nfds; i++) {
01403 if (driver->pfd[i].revents & POLLERR) {
01404 xrun_detected = TRUE;
01405 }
01406
01407 if (driver->pfd[i].revents == 0) {
01408 p_timed_out++;
01409 #ifdef DEBUG_WAKEUP
01410
01411 fprintf (stderr, "%" PRIu64
01412 " playback stream timed out\n",
01413 poll_ret);
01414 #endif
01415
01416 }
01417 }
01418
01419 if (p_timed_out == 0) {
01420 need_playback = 0;
01421 #ifdef DEBUG_WAKEUP
01422
01423 fprintf (stderr, "%" PRIu64
01424 " playback stream ready\n",
01425 poll_ret);
01426 #endif
01427
01428 }
01429 }
01430
01431 c_timed_out = 0;
01432
01433 if (need_capture) {
01434 for (i = ci; i < nfds; i++) {
01435 if (driver->pfd[i].revents & POLLERR) {
01436 xrun_detected = TRUE;
01437 }
01438
01439 if (driver->pfd[i].revents == 0) {
01440 c_timed_out++;
01441 #ifdef DEBUG_WAKEUP
01442
01443 fprintf (stderr, "%" PRIu64
01444 " capture stream timed out\n",
01445 poll_ret);
01446 #endif
01447
01448 }
01449 }
01450
01451 if (c_timed_out == 0) {
01452 need_capture = 0;
01453 #ifdef DEBUG_WAKEUP
01454
01455 fprintf (stderr, "%" PRIu64
01456 " capture stream ready\n",
01457 poll_ret);
01458 #endif
01459
01460 }
01461 }
01462
01463 if ((p_timed_out && (p_timed_out == driver->playback_nfds)) &&
01464 (c_timed_out && (c_timed_out == driver->capture_nfds))) {
01465
01466
01467
01468
01469
01470
01471 *status = -5;
01472 return 0;
01473 }
01474
01475 }
01476
01477 if (driver->capture_handle) {
01478 if ((capture_avail = snd_pcm_avail_update (
01479 driver->capture_handle)) < 0) {
01480 if (capture_avail == -EPIPE) {
01481 xrun_detected = TRUE;
01482 } else {
01483 jack_error ("unknown ALSA avail_update return"
01484 " value (%u)", capture_avail);
01485 }
01486 }
01487 } else {
01488
01489 capture_avail = INT_MAX;
01490 }
01491
01492 if (driver->playback_handle) {
01493 if ((playback_avail = snd_pcm_avail_update (
01494 driver->playback_handle)) < 0) {
01495 if (playback_avail == -EPIPE) {
01496 xrun_detected = TRUE;
01497 } else {
01498 jack_error ("unknown ALSA avail_update return"
01499 " value (%u)", playback_avail);
01500 }
01501 }
01502 } else {
01503
01504 playback_avail = INT_MAX;
01505 }
01506
01507 if (xrun_detected) {
01508 *status = alsa_driver_xrun_recovery (driver, delayed_usecs);
01509 return 0;
01510 }
01511
01512 *status = 0;
01513 driver->last_wait_ust = poll_ret;
01514
01515 avail = capture_avail < playback_avail ? capture_avail : playback_avail;
01516
01517 #ifdef DEBUG_WAKEUP
01518
01519 fprintf (stderr, "wakeup complete, avail = %lu, pavail = %lu "
01520 "cavail = %lu\n",
01521 avail, playback_avail, capture_avail);
01522 #endif
01523
01524
01525
01526 bitset_copy (driver->channels_not_done, driver->channels_done);
01527
01528
01529
01530
01531
01532 return avail - (avail % driver->frames_per_cycle);
01533 }
01534
01535 int JackAlsaDriver::SetBufferSize(jack_nframes_t buffer_size)
01536 {
01537 jack_log("JackAlsaDriver::SetBufferSize %ld", buffer_size);
01538 int res = alsa_driver_reset_parameters((alsa_driver_t *)fDriver, buffer_size,
01539 ((alsa_driver_t *)fDriver)->user_nperiods,
01540 ((alsa_driver_t *)fDriver)->frame_rate);
01541
01542 if (res == 0) {
01543 JackAudioDriver::SetBufferSize(buffer_size);
01544 } else {
01545 alsa_driver_reset_parameters((alsa_driver_t *)fDriver, fEngineControl->fBufferSize,
01546 ((alsa_driver_t *)fDriver)->user_nperiods,
01547 ((alsa_driver_t *)fDriver)->frame_rate);
01548 }
01549
01550 return res;
01551 }
01552
01553 int
01554 JackAlsaDriver::alsa_driver_read (alsa_driver_t *driver, jack_nframes_t nframes)
01555 {
01556 snd_pcm_sframes_t contiguous;
01557 snd_pcm_sframes_t nread;
01558 snd_pcm_sframes_t offset;
01559 jack_nframes_t orig_nframes;
01560 jack_default_audio_sample_t* buf;
01561
01562
01563
01564 int err;
01565
01566
01567
01568
01569
01570
01571
01572 if (!driver->capture_handle) {
01573 return 0;
01574 }
01575 if (nframes > driver->frames_per_cycle) {
01576 return -1;
01577 }
01578
01579 if (driver->midi)
01580 (driver->midi->read)(driver->midi, nframes);
01581
01582 nread = 0;
01583 contiguous = 0;
01584 orig_nframes = nframes;
01585
01586 while (nframes) {
01587
01588 contiguous = nframes;
01589
01590 if (alsa_driver_get_channel_addresses (
01591 driver,
01592 (snd_pcm_uframes_t *) &contiguous,
01593 (snd_pcm_uframes_t *) 0,
01594 (snd_pcm_uframes_t *)&offset, 0) < 0) {
01595 return -1;
01596 }
01597
01598
01599 for (int i = 0; i < fCaptureChannels; i++) {
01600 if (fGraphManager->GetConnectionsNum(fCapturePortList[i]) > 0) {
01601 buf = (jack_default_audio_sample_t*)fGraphManager->GetBuffer(fCapturePortList[i], orig_nframes);
01602 alsa_driver_read_from_channel (driver, i, buf + nread, contiguous);
01603 }
01604 }
01605
01606
01607
01608
01609
01610
01611
01612
01613
01614
01615
01616
01617
01618
01619
01620
01621
01622 if ((err = snd_pcm_mmap_commit (driver->capture_handle,
01623 offset, contiguous)) < 0) {
01624
01625
01626
01627 jack_error ("ALSA: could not complete read of %d frames: error = %d", contiguous, err);
01628 return -1;
01629 }
01630
01631 nframes -= contiguous;
01632 nread += contiguous;
01633 }
01634
01635 return 0;
01636 }
01637
01638 int
01639 JackAlsaDriver::alsa_driver_write (alsa_driver_t* driver, jack_nframes_t nframes)
01640 {
01641
01642
01643
01644 jack_default_audio_sample_t* buf;
01645 jack_default_audio_sample_t* monbuf;
01646 jack_nframes_t orig_nframes;
01647 snd_pcm_sframes_t nwritten;
01648 snd_pcm_sframes_t contiguous;
01649 snd_pcm_sframes_t offset;
01650 JackPort* port;
01651
01652 int err;
01653
01654 driver->process_count++;
01655
01656
01657
01658
01659
01660
01661
01662 if (!driver->playback_handle) {
01663 return 0;
01664 }
01665
01666 if (nframes > driver->frames_per_cycle) {
01667 return -1;
01668 }
01669
01670 if (driver->midi)
01671 (driver->midi->write)(driver->midi, nframes);
01672
01673 nwritten = 0;
01674 contiguous = 0;
01675 orig_nframes = nframes;
01676
01677
01678
01679 driver->input_monitor_mask = 0;
01680
01681
01682
01683
01684
01685
01686
01687
01688
01689
01690 for (int i = 0; i < fCaptureChannels; i++) {
01691 port = fGraphManager->GetPort(fCapturePortList[i]);
01692 if (port->MonitoringInput()) {
01693 driver->input_monitor_mask |= (1 << i);
01694 }
01695 }
01696
01697 if (driver->hw_monitoring) {
01698 if ((driver->hw->input_monitor_mask
01699 != driver->input_monitor_mask)
01700 && !driver->all_monitor_in) {
01701 driver->hw->set_input_monitor_mask (
01702 driver->hw, driver->input_monitor_mask);
01703 }
01704 }
01705
01706 while (nframes) {
01707
01708 contiguous = nframes;
01709
01710 if (alsa_driver_get_channel_addresses (
01711 driver,
01712 (snd_pcm_uframes_t *) 0,
01713 (snd_pcm_uframes_t *) &contiguous,
01714 0, (snd_pcm_uframes_t *)&offset) < 0) {
01715 return -1;
01716 }
01717
01718
01719 for (int i = 0; i < fPlaybackChannels; i++) {
01720
01721 if (fGraphManager->GetConnectionsNum(fPlaybackPortList[i]) > 0) {
01722 buf = (jack_default_audio_sample_t*)fGraphManager->GetBuffer(fPlaybackPortList[i], orig_nframes);
01723 alsa_driver_write_to_channel (driver, i, buf + nwritten, contiguous);
01724
01725 if (fWithMonitorPorts && fGraphManager->GetConnectionsNum(fMonitorPortList[i]) > 0) {
01726 monbuf = (jack_default_audio_sample_t*)fGraphManager->GetBuffer(fMonitorPortList[i], orig_nframes);
01727 memcpy(monbuf + nwritten, buf + nwritten, contiguous * sizeof(jack_default_audio_sample_t));
01728 }
01729 }
01730 }
01731
01732
01733
01734
01735
01736
01737
01738
01739
01740
01741
01742
01743
01744
01745
01746
01747
01748
01749
01750
01751
01752
01753
01754
01755
01756
01757
01758 if (!bitset_empty (driver->channels_not_done)) {
01759 alsa_driver_silence_untouched_channels (driver,
01760 contiguous);
01761 }
01762
01763 if ((err = snd_pcm_mmap_commit (driver->playback_handle,
01764 offset, contiguous)) < 0) {
01765
01766
01767
01768 jack_error ("ALSA: could not complete playback of %d frames: error = %d", contiguous, err);
01769 if (err != EPIPE && err != ESTRPIPE)
01770 return -1;
01771 }
01772
01773 nframes -= contiguous;
01774 nwritten += contiguous;
01775 }
01776 return 0;
01777 }
01778
01779 void
01780 JackAlsaDriver::alsa_driver_delete (alsa_driver_t *driver)
01781 {
01782 JSList *node;
01783
01784 if (driver->midi)
01785 (driver->midi->destroy)(driver->midi);
01786
01787 for (node = driver->clock_sync_listeners; node;
01788 node = jack_slist_next (node)) {
01789 free (node->data);
01790 }
01791 jack_slist_free (driver->clock_sync_listeners);
01792
01793 if (driver->ctl_handle) {
01794 snd_ctl_close (driver->ctl_handle);
01795 driver->ctl_handle = 0;
01796 }
01797
01798 if (driver->ctl_handle) {
01799 snd_ctl_close (driver->ctl_handle);
01800 driver->ctl_handle = 0;
01801 }
01802
01803 if (driver->capture_handle) {
01804 snd_pcm_close (driver->capture_handle);
01805 driver->capture_handle = 0;
01806 }
01807
01808 if (driver->playback_handle) {
01809 snd_pcm_close (driver->playback_handle);
01810 driver->capture_handle = 0;
01811 }
01812
01813 if (driver->capture_hw_params) {
01814 snd_pcm_hw_params_free (driver->capture_hw_params);
01815 driver->capture_hw_params = 0;
01816 }
01817
01818 if (driver->playback_hw_params) {
01819 snd_pcm_hw_params_free (driver->playback_hw_params);
01820 driver->playback_hw_params = 0;
01821 }
01822
01823 if (driver->capture_sw_params) {
01824 snd_pcm_sw_params_free (driver->capture_sw_params);
01825 driver->capture_sw_params = 0;
01826 }
01827
01828 if (driver->playback_sw_params) {
01829 snd_pcm_sw_params_free (driver->playback_sw_params);
01830 driver->playback_sw_params = 0;
01831 }
01832
01833 if (driver->pfd) {
01834 free (driver->pfd);
01835 }
01836
01837 if (driver->hw) {
01838 driver->hw->release (driver->hw);
01839 driver->hw = 0;
01840 }
01841 free(driver->alsa_name_playback);
01842 free(driver->alsa_name_capture);
01843 free(driver->alsa_driver);
01844
01845 alsa_driver_release_channel_dependent_memory (driver);
01846 free (driver);
01847 }
01848
01849 jack_driver_t *
01850 JackAlsaDriver::alsa_driver_new (const char *name, char *playback_alsa_device,
01851 char *capture_alsa_device,
01852 jack_client_t *client,
01853 jack_nframes_t frames_per_cycle,
01854 jack_nframes_t user_nperiods,
01855 jack_nframes_t rate,
01856 int hw_monitoring,
01857 int hw_metering,
01858 int capturing,
01859 int playing,
01860 DitherAlgorithm dither,
01861 int soft_mode,
01862 int monitor,
01863 int user_capture_nchnls,
01864 int user_playback_nchnls,
01865 int shorts_first,
01866 jack_nframes_t capture_latency,
01867 jack_nframes_t playback_latency,
01868 alsa_midi_t *midi)
01869 {
01870 int err;
01871
01872 alsa_driver_t *driver;
01873
01874
01875
01876
01877
01878
01879
01880
01881
01882
01883
01884
01885
01886
01887 driver = (alsa_driver_t *) calloc (1, sizeof (alsa_driver_t));
01888
01889 jack_driver_nt_init ((jack_driver_nt_t *) driver);
01890
01891 driver->midi = midi;
01892 driver->xrun_recovery = 0;
01893
01894
01895
01896
01897
01898
01899
01900
01901
01902
01903
01904 driver->playback_handle = NULL;
01905 driver->capture_handle = NULL;
01906 driver->ctl_handle = 0;
01907 driver->hw = 0;
01908 driver->capture_and_playback_not_synced = FALSE;
01909 driver->max_nchannels = 0;
01910 driver->user_nchannels = 0;
01911 driver->playback_nchannels = user_playback_nchnls;
01912 driver->capture_nchannels = user_capture_nchnls;
01913 driver->playback_sample_bytes = (shorts_first ? 2 : 4);
01914 driver->capture_sample_bytes = (shorts_first ? 2 : 4);
01915 driver->capture_frame_latency = capture_latency;
01916 driver->playback_frame_latency = playback_latency;
01917
01918 driver->playback_addr = 0;
01919 driver->capture_addr = 0;
01920 driver->playback_interleave_skip = NULL;
01921 driver->capture_interleave_skip = NULL;
01922
01923 driver->silent = 0;
01924 driver->all_monitor_in = FALSE;
01925 driver->with_monitor_ports = monitor;
01926
01927 driver->clock_mode = ClockMaster;
01928 driver->input_monitor_mask = 0;
01929
01930 driver->capture_ports = 0;
01931 driver->playback_ports = 0;
01932 driver->monitor_ports = 0;
01933
01934 driver->pfd = 0;
01935 driver->playback_nfds = 0;
01936 driver->capture_nfds = 0;
01937
01938 driver->dither = dither;
01939 driver->soft_mode = soft_mode;
01940
01941 pthread_mutex_init (&driver->clock_sync_lock, 0);
01942 driver->clock_sync_listeners = 0;
01943
01944 driver->poll_late = 0;
01945 driver->xrun_count = 0;
01946 driver->process_count = 0;
01947
01948 driver->alsa_name_playback = strdup (playback_alsa_device);
01949 driver->alsa_name_capture = strdup (capture_alsa_device);
01950
01951 if (alsa_driver_check_card_type (driver)) {
01952 alsa_driver_delete (driver);
01953 return NULL;
01954 }
01955
01956 alsa_driver_hw_specific (driver, hw_monitoring, hw_metering);
01957
01958 if (playing) {
01959 if (snd_pcm_open (&driver->playback_handle,
01960 playback_alsa_device,
01961 SND_PCM_STREAM_PLAYBACK,
01962 SND_PCM_NONBLOCK) < 0) {
01963 switch (errno) {
01964 case EBUSY:
01965 jack_error ("the playback device \"%s\" is "
01966 "already in use. Please stop the"
01967 " application using it and "
01968 "run JACK again",
01969 playback_alsa_device);
01970 alsa_driver_delete (driver);
01971 return NULL;
01972 break;
01973
01974 case EPERM:
01975 jack_error ("you do not have permission to open "
01976 "the audio device \"%s\" for playback",
01977 playback_alsa_device);
01978 alsa_driver_delete (driver);
01979 return NULL;
01980 break;
01981 }
01982
01983 driver->playback_handle = NULL;
01984 }
01985
01986 if (driver->playback_handle) {
01987 snd_pcm_nonblock (driver->playback_handle, 0);
01988 }
01989 }
01990
01991 if (capturing) {
01992 if (snd_pcm_open (&driver->capture_handle,
01993 capture_alsa_device,
01994 SND_PCM_STREAM_CAPTURE,
01995 SND_PCM_NONBLOCK) < 0) {
01996 switch (errno) {
01997 case EBUSY:
01998 jack_error ("the capture device \"%s\" is "
01999 "already in use. Please stop the"
02000 " application using it and "
02001 "run JACK again",
02002 capture_alsa_device);
02003 alsa_driver_delete (driver);
02004 return NULL;
02005 break;
02006
02007 case EPERM:
02008 jack_error ("you do not have permission to open "
02009 "the audio device \"%s\" for capture",
02010 capture_alsa_device);
02011 alsa_driver_delete (driver);
02012 return NULL;
02013 break;
02014 }
02015
02016 driver->capture_handle = NULL;
02017 }
02018
02019 if (driver->capture_handle) {
02020 snd_pcm_nonblock (driver->capture_handle, 0);
02021 }
02022 }
02023
02024 if (driver->playback_handle == NULL) {
02025 if (playing) {
02026
02027
02028
02029 jack_error ("ALSA: Cannot open PCM device %s for "
02030 "playback. Falling back to capture-only"
02031 " mode", name);
02032
02033 if (driver->capture_handle == NULL) {
02034
02035 alsa_driver_delete (driver);
02036 return NULL;
02037 }
02038
02039 playing = FALSE;
02040 }
02041 }
02042
02043 if (driver->capture_handle == NULL) {
02044 if (capturing) {
02045
02046
02047
02048 jack_error ("ALSA: Cannot open PCM device %s for "
02049 "capture. Falling back to playback-only"
02050 " mode", name);
02051
02052 if (driver->playback_handle == NULL) {
02053
02054 alsa_driver_delete (driver);
02055 return NULL;
02056 }
02057
02058 capturing = FALSE;
02059 }
02060 }
02061
02062 driver->playback_hw_params = 0;
02063 driver->capture_hw_params = 0;
02064 driver->playback_sw_params = 0;
02065 driver->capture_sw_params = 0;
02066
02067 if (driver->playback_handle) {
02068 if ((err = snd_pcm_hw_params_malloc (
02069 &driver->playback_hw_params)) < 0) {
02070 jack_error ("ALSA: could not allocate playback hw"
02071 " params structure");
02072 alsa_driver_delete (driver);
02073 return NULL;
02074 }
02075
02076 if ((err = snd_pcm_sw_params_malloc (
02077 &driver->playback_sw_params)) < 0) {
02078 jack_error ("ALSA: could not allocate playback sw"
02079 " params structure");
02080 alsa_driver_delete (driver);
02081 return NULL;
02082 }
02083 }
02084
02085 if (driver->capture_handle) {
02086 if ((err = snd_pcm_hw_params_malloc (
02087 &driver->capture_hw_params)) < 0) {
02088 jack_error ("ALSA: could not allocate capture hw"
02089 " params structure");
02090 alsa_driver_delete (driver);
02091 return NULL;
02092 }
02093
02094 if ((err = snd_pcm_sw_params_malloc (
02095 &driver->capture_sw_params)) < 0) {
02096 jack_error ("ALSA: could not allocate capture sw"
02097 " params structure");
02098 alsa_driver_delete (driver);
02099 return NULL;
02100 }
02101 }
02102
02103 if (alsa_driver_set_parameters (driver, frames_per_cycle,
02104 user_nperiods, rate)) {
02105 alsa_driver_delete (driver);
02106 return NULL;
02107 }
02108
02109 driver->capture_and_playback_not_synced = FALSE;
02110
02111 if (driver->capture_handle && driver->playback_handle) {
02112 if (snd_pcm_link (driver->capture_handle,
02113 driver->playback_handle) != 0) {
02114 driver->capture_and_playback_not_synced = TRUE;
02115 }
02116 }
02117
02118 driver->client = client;
02119 return (jack_driver_t *) driver;
02120 }
02121
02122 int JackAlsaDriver::Attach()
02123 {
02124 JackPort* port;
02125 int port_index;
02126 unsigned long port_flags;
02127 char name[JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE];
02128 char alias[JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE];
02129
02130 assert(fCaptureChannels < DRIVER_PORT_NUM);
02131 assert(fPlaybackChannels < DRIVER_PORT_NUM);
02132
02133 port_flags = JackPortIsOutput | JackPortIsPhysical | JackPortIsTerminal;
02134
02135 alsa_driver_t* alsa_driver = (alsa_driver_t*)fDriver;
02136
02137 if (alsa_driver->has_hw_monitoring)
02138 port_flags |= JackPortCanMonitor;
02139
02140
02141 JackAudioDriver::SetBufferSize(alsa_driver->frames_per_cycle);
02142 JackAudioDriver::SetSampleRate(alsa_driver->frame_rate);
02143
02144 jack_log("JackAudioDriver::Attach fBufferSize %ld fSampleRate %ld", fEngineControl->fBufferSize, fEngineControl->fSampleRate);
02145
02146 for (int i = 0; i < fCaptureChannels; i++) {
02147 snprintf(alias, sizeof(alias) - 1, "%s:capture_%u", fAliasName, i + 1);
02148 snprintf(name, sizeof(name) - 1, "%s:capture_%d", fClientControl.fName, i + 1);
02149 if ((port_index = fGraphManager->AllocatePort(fClientControl.fRefNum, name, JACK_DEFAULT_AUDIO_TYPE, (JackPortFlags)port_flags, fEngineControl->fBufferSize)) == NO_PORT) {
02150 jack_error("driver: cannot register port for %s", name);
02151 return -1;
02152 }
02153 port = fGraphManager->GetPort(port_index);
02154 port->SetAlias(alias);
02155 port->SetLatency(alsa_driver->frames_per_cycle + alsa_driver->capture_frame_latency);
02156 fCapturePortList[i] = port_index;
02157 jack_log("JackAudioDriver::Attach fCapturePortList[i] %ld ", port_index);
02158 }
02159
02160 port_flags = JackPortIsInput | JackPortIsPhysical | JackPortIsTerminal;
02161
02162 for (int i = 0; i < fPlaybackChannels; i++) {
02163 snprintf(alias, sizeof(alias) - 1, "%s:playback_%u", fAliasName, i + 1);
02164 snprintf(name, sizeof(name) - 1, "%s:playback_%d", fClientControl.fName, i + 1);
02165 if ((port_index = fGraphManager->AllocatePort(fClientControl.fRefNum, name, JACK_DEFAULT_AUDIO_TYPE, (JackPortFlags)port_flags, fEngineControl->fBufferSize)) == NO_PORT) {
02166 jack_error("driver: cannot register port for %s", name);
02167 return -1;
02168 }
02169 port = fGraphManager->GetPort(port_index);
02170 port->SetAlias(alias);
02171
02172 port->SetLatency((alsa_driver->frames_per_cycle * (alsa_driver->user_nperiods - 1)) +
02173 ((fEngineControl->fSyncMode) ? 0 : fEngineControl->fBufferSize) + alsa_driver->playback_frame_latency);
02174 fPlaybackPortList[i] = port_index;
02175 jack_log("JackAudioDriver::Attach fPlaybackPortList[i] %ld ", port_index);
02176
02177
02178 if (fWithMonitorPorts) {
02179 jack_log("Create monitor port ");
02180 snprintf(name, sizeof(name) - 1, "%s:monitor_%d", fClientControl.fName, i + 1);
02181 if ((port_index = fGraphManager->AllocatePort(fClientControl.fRefNum, name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, fEngineControl->fBufferSize)) == NO_PORT) {
02182 jack_error ("ALSA: cannot register monitor port for %s", name);
02183 } else {
02184 port = fGraphManager->GetPort(port_index);
02185 port->SetLatency(alsa_driver->frames_per_cycle);
02186 fMonitorPortList[i] = port_index;
02187 }
02188 }
02189 }
02190
02191 if (alsa_driver->midi) {
02192 int err = (alsa_driver->midi->attach)(alsa_driver->midi);
02193 if (err)
02194 jack_error ("ALSA: cannot attach MIDI: %d", err);
02195 }
02196
02197 return 0;
02198 }
02199
02200 int JackAlsaDriver::Detach()
02201 {
02202 alsa_driver_t* alsa_driver = (alsa_driver_t*)fDriver;
02203 if (alsa_driver->midi)
02204 (alsa_driver->midi->detach)(alsa_driver->midi);
02205
02206 return JackAudioDriver::Detach();
02207 }
02208
02209 int JackAlsaDriver::Open(jack_nframes_t nframes,
02210 jack_nframes_t user_nperiods,
02211 jack_nframes_t samplerate,
02212 bool hw_monitoring,
02213 bool hw_metering,
02214 bool capturing,
02215 bool playing,
02216 DitherAlgorithm dither,
02217 bool soft_mode,
02218 bool monitor,
02219 int inchannels,
02220 int outchannels,
02221 bool shorts_first,
02222 const char* capture_driver_name,
02223 const char* playback_driver_name,
02224 jack_nframes_t capture_latency,
02225 jack_nframes_t playback_latency,
02226 const char* midi_driver_name)
02227 {
02228
02229 if (JackAudioDriver::Open(nframes, samplerate, capturing, playing,
02230 inchannels, outchannels, monitor, capture_driver_name, playback_driver_name,
02231 capture_latency, playback_latency) != 0) {
02232 return -1;
02233 }
02234
02235 alsa_midi_t *midi = 0;
02236 if (strcmp(midi_driver_name, "seq") == 0)
02237 midi = alsa_seqmidi_new((jack_client_t*)this, 0);
02238 else if (strcmp(midi_driver_name, "raw") == 0)
02239 midi = alsa_rawmidi_new((jack_client_t*)this);
02240
02241 fDriver = alsa_driver_new ("alsa_pcm", (char*)playback_driver_name, (char*)capture_driver_name,
02242 NULL,
02243 nframes,
02244 user_nperiods,
02245 samplerate,
02246 hw_monitoring,
02247 hw_metering,
02248 capturing,
02249 playing,
02250 dither,
02251 soft_mode,
02252 monitor,
02253 inchannels,
02254 outchannels,
02255 shorts_first,
02256 capture_latency,
02257 playback_latency,
02258 midi);
02259 if (fDriver) {
02260
02261 fCaptureChannels = ((alsa_driver_t *)fDriver)->capture_nchannels;
02262 fPlaybackChannels = ((alsa_driver_t *)fDriver)->playback_nchannels;
02263 return 0;
02264 } else {
02265 JackAudioDriver::Close();
02266 return -1;
02267 }
02268 }
02269
02270 int JackAlsaDriver::Close()
02271 {
02272 JackAudioDriver::Close();
02273 alsa_driver_delete((alsa_driver_t*)fDriver);
02274 return 0;
02275 }
02276
02277 int JackAlsaDriver::Start()
02278 {
02279 return alsa_driver_start((alsa_driver_t *)fDriver);
02280 }
02281
02282 int JackAlsaDriver::Stop()
02283 {
02284 return alsa_driver_stop((alsa_driver_t *)fDriver);
02285 }
02286
02287 int JackAlsaDriver::Read()
02288 {
02289
02290 int wait_status;
02291 jack_nframes_t nframes;
02292 fDelayedUsecs = 0.f;
02293
02294 nframes = alsa_driver_wait((alsa_driver_t *)fDriver, -1, &wait_status, &fDelayedUsecs);
02295
02296 if (wait_status < 0)
02297 return -1;
02298
02299 if (nframes == 0) {
02300
02301
02302
02303 jack_log("ALSA XRun");
02304 NotifyXRun(fBeginDateUst, fDelayedUsecs);
02305 return -1;
02306 }
02307
02308 if (nframes != fEngineControl->fBufferSize)
02309 jack_log("JackAlsaDriver::Read nframes = %ld", nframes);
02310
02311
02312 JackDriver::CycleIncTime();
02313
02314 return alsa_driver_read((alsa_driver_t *)fDriver, fEngineControl->fBufferSize);
02315 }
02316
02317 int JackAlsaDriver::Write()
02318 {
02319 return alsa_driver_write((alsa_driver_t *)fDriver, fEngineControl->fBufferSize);
02320 }
02321
02322 void
02323 JackAlsaDriver::jack_driver_init (jack_driver_t *driver)
02324 {
02325 memset (driver, 0, sizeof (*driver));
02326
02327 driver->attach = 0;
02328 driver->detach = 0;
02329 driver->write = 0;
02330 driver->read = 0;
02331 driver->null_cycle = 0;
02332 driver->bufsize = 0;
02333 driver->start = 0;
02334 driver->stop = 0;
02335 }
02336
02337 void
02338 JackAlsaDriver::jack_driver_nt_init (jack_driver_nt_t * driver)
02339 {
02340 memset (driver, 0, sizeof (*driver));
02341
02342 jack_driver_init ((jack_driver_t *) driver);
02343
02344 driver->attach = 0;
02345 driver->detach = 0;
02346 driver->bufsize = 0;
02347 driver->stop = 0;
02348 driver->start = 0;
02349
02350 driver->nt_bufsize = 0;
02351 driver->nt_start = 0;
02352 driver->nt_stop = 0;
02353 driver->nt_attach = 0;
02354 driver->nt_detach = 0;
02355 driver->nt_run_cycle = 0;
02356 }
02357
02358 int JackAlsaDriver::is_realtime() const
02359 {
02360 return fEngineControl->fRealTime;
02361 }
02362
02363 int JackAlsaDriver::create_thread(pthread_t *thread, int priority, int realtime, void *(*start_routine)(void*), void *arg)
02364 {
02365 return JackPosixThread::StartImp(thread, priority, realtime, start_routine, arg);
02366 }
02367
02368 jack_port_id_t JackAlsaDriver::port_register(const char *port_name, const char *port_type, unsigned long flags, unsigned long buffer_size)
02369 {
02370 jack_port_id_t port_index;
02371 int res = fEngine->PortRegister(fClientControl.fRefNum, port_name, port_type, flags, buffer_size, &port_index);
02372 return (res == 0) ? port_index : 0;
02373 }
02374
02375 int JackAlsaDriver::port_unregister(jack_port_id_t port_index)
02376 {
02377 return fEngine->PortUnRegister(fClientControl.fRefNum, port_index);
02378 }
02379
02380 void* JackAlsaDriver::port_get_buffer(int port, jack_nframes_t nframes)
02381 {
02382 return fGraphManager->GetBuffer(port, nframes);
02383 }
02384
02385 int JackAlsaDriver::port_set_alias(int port, const char* name)
02386 {
02387 return fGraphManager->GetPort(port)->SetAlias(name);
02388 }
02389
02390 jack_nframes_t JackAlsaDriver::get_sample_rate() const
02391 {
02392 return fEngineControl->fSampleRate;
02393 }
02394
02395 jack_nframes_t JackAlsaDriver::frame_time() const
02396 {
02397 JackTimer timer;
02398 fEngineControl->ReadFrameTime(&timer);
02399 return timer.Time2Frames(GetMicroSeconds(), fEngineControl->fBufferSize);
02400 }
02401
02402 jack_nframes_t JackAlsaDriver::last_frame_time() const
02403 {
02404 JackTimer timer;
02405 fEngineControl->ReadFrameTime(&timer);
02406 return timer.CurFrame();
02407 }
02408
02409 }
02410
02411
02412 #ifdef __cplusplus
02413 extern "C"
02414 {
02415 #endif
02416
02417 static
02418 void
02419 fill_device(
02420 jack_driver_param_constraint_desc_t ** constraint_ptr_ptr,
02421 uint32_t * array_size_ptr,
02422 const char * device_id,
02423 const char * device_description)
02424 {
02425 jack_driver_param_value_enum_t * possible_value_ptr;
02426
02427
02428
02429 if (*constraint_ptr_ptr == NULL)
02430 {
02431 *constraint_ptr_ptr = (jack_driver_param_constraint_desc_t *)calloc(1, sizeof(jack_driver_param_value_enum_t));
02432 *array_size_ptr = 0;
02433 }
02434
02435 if ((*constraint_ptr_ptr)->constraint.enumeration.count == *array_size_ptr)
02436 {
02437 *array_size_ptr += 10;
02438 (*constraint_ptr_ptr)->constraint.enumeration.possible_values_array =
02439 (jack_driver_param_value_enum_t *)realloc(
02440 (*constraint_ptr_ptr)->constraint.enumeration.possible_values_array,
02441 sizeof(jack_driver_param_value_enum_t) * *array_size_ptr);
02442 }
02443
02444 possible_value_ptr = (*constraint_ptr_ptr)->constraint.enumeration.possible_values_array + (*constraint_ptr_ptr)->constraint.enumeration.count;
02445 (*constraint_ptr_ptr)->constraint.enumeration.count++;
02446 strcpy(possible_value_ptr->value.str, device_id);
02447 strcpy(possible_value_ptr->short_desc, device_description);
02448 }
02449
02450 static
02451 jack_driver_param_constraint_desc_t *
02452 enum_alsa_devices()
02453 {
02454 snd_ctl_t * handle;
02455 snd_ctl_card_info_t * info;
02456 snd_pcm_info_t * pcminfo_capture;
02457 snd_pcm_info_t * pcminfo_playback;
02458 int card_no = -1;
02459 char card_id[JACK_DRIVER_PARAM_STRING_MAX + 1];
02460 char device_id[JACK_DRIVER_PARAM_STRING_MAX + 1];
02461 char description[64];
02462 int device_no;
02463 bool has_capture;
02464 bool has_playback;
02465 jack_driver_param_constraint_desc_t * constraint_ptr;
02466 uint32_t array_size;
02467
02468 snd_ctl_card_info_alloca(&info);
02469 snd_pcm_info_alloca(&pcminfo_capture);
02470 snd_pcm_info_alloca(&pcminfo_playback);
02471
02472 constraint_ptr = NULL;
02473
02474 while(snd_card_next(&card_no) >= 0 && card_no >= 0)
02475 {
02476 sprintf(card_id, "hw:%d", card_no);
02477
02478 if (snd_ctl_open(&handle, card_id, 0) >= 0 &&
02479 snd_ctl_card_info(handle, info) >= 0)
02480 {
02481 fill_device(&constraint_ptr, &array_size, card_id, snd_ctl_card_info_get_name(info));
02482
02483 device_no = -1;
02484
02485 while (snd_ctl_pcm_next_device(handle, &device_no) >= 0 && device_no != -1)
02486 {
02487 sprintf(device_id, "%s,%d", card_id, device_no);
02488
02489 snd_pcm_info_set_device(pcminfo_capture, device_no);
02490 snd_pcm_info_set_subdevice(pcminfo_capture, 0);
02491 snd_pcm_info_set_stream(pcminfo_capture, SND_PCM_STREAM_CAPTURE);
02492 has_capture = snd_ctl_pcm_info(handle, pcminfo_capture) >= 0;
02493
02494 snd_pcm_info_set_device(pcminfo_playback, device_no);
02495 snd_pcm_info_set_subdevice(pcminfo_playback, 0);
02496 snd_pcm_info_set_stream(pcminfo_playback, SND_PCM_STREAM_PLAYBACK);
02497 has_playback = snd_ctl_pcm_info(handle, pcminfo_playback) >= 0;
02498
02499 if (has_capture && has_playback)
02500 {
02501 snprintf(description, sizeof(description),"%s (duplex)", snd_pcm_info_get_name(pcminfo_capture));
02502 }
02503 else if (has_capture)
02504 {
02505 snprintf(description, sizeof(description),"%s (capture)", snd_pcm_info_get_name(pcminfo_capture));
02506 }
02507 else if (has_playback)
02508 {
02509 snprintf(description, sizeof(description),"%s (playback)", snd_pcm_info_get_name(pcminfo_playback));
02510 }
02511 else
02512 {
02513 continue;
02514 }
02515
02516 fill_device(&constraint_ptr, &array_size, device_id, description);
02517 }
02518
02519 snd_ctl_close(handle);
02520 }
02521 }
02522
02523 return constraint_ptr;
02524 }
02525
02526 static
02527 jack_driver_param_constraint_desc_t *
02528 get_midi_driver_constraint()
02529 {
02530 jack_driver_param_constraint_desc_t * constraint_ptr;
02531 jack_driver_param_value_enum_t * possible_value_ptr;
02532
02533
02534
02535 constraint_ptr = (jack_driver_param_constraint_desc_t *)calloc(1, sizeof(jack_driver_param_value_enum_t));
02536 constraint_ptr->flags = JACK_CONSTRAINT_FLAG_STRICT | JACK_CONSTRAINT_FLAG_FAKE_VALUE;
02537
02538 constraint_ptr->constraint.enumeration.possible_values_array = (jack_driver_param_value_enum_t *)malloc(3 * sizeof(jack_driver_param_value_enum_t));
02539 constraint_ptr->constraint.enumeration.count = 3;
02540
02541 possible_value_ptr = constraint_ptr->constraint.enumeration.possible_values_array;
02542
02543 strcpy(possible_value_ptr->value.str, "none");
02544 strcpy(possible_value_ptr->short_desc, "no MIDI driver");
02545
02546 possible_value_ptr++;
02547
02548 strcpy(possible_value_ptr->value.str, "seq");
02549 strcpy(possible_value_ptr->short_desc, "ALSA Sequencer driver");
02550
02551 possible_value_ptr++;
02552
02553 strcpy(possible_value_ptr->value.str, "raw");
02554 strcpy(possible_value_ptr->short_desc, "ALSA RawMIDI driver");
02555
02556 return constraint_ptr;
02557 }
02558
02559 static
02560 jack_driver_param_constraint_desc_t *
02561 get_dither_constraint()
02562 {
02563 jack_driver_param_constraint_desc_t * constraint_ptr;
02564 jack_driver_param_value_enum_t * possible_value_ptr;
02565
02566
02567
02568 constraint_ptr = (jack_driver_param_constraint_desc_t *)calloc(1, sizeof(jack_driver_param_value_enum_t));
02569 constraint_ptr->flags = JACK_CONSTRAINT_FLAG_STRICT | JACK_CONSTRAINT_FLAG_FAKE_VALUE;
02570
02571 constraint_ptr->constraint.enumeration.possible_values_array = (jack_driver_param_value_enum_t *)malloc(4 * sizeof(jack_driver_param_value_enum_t));
02572 constraint_ptr->constraint.enumeration.count = 4;
02573
02574 possible_value_ptr = constraint_ptr->constraint.enumeration.possible_values_array;
02575
02576 possible_value_ptr->value.c = 'n';
02577 strcpy(possible_value_ptr->short_desc, "none");
02578
02579 possible_value_ptr++;
02580
02581 possible_value_ptr->value.c = 'r';
02582 strcpy(possible_value_ptr->short_desc, "rectangular");
02583
02584 possible_value_ptr++;
02585
02586 possible_value_ptr->value.c = 's';
02587 strcpy(possible_value_ptr->short_desc, "shaped");
02588
02589 possible_value_ptr++;
02590
02591 possible_value_ptr->value.c = 't';
02592 strcpy(possible_value_ptr->short_desc, "triangular");
02593
02594 return constraint_ptr;
02595 }
02596
02597 static int
02598 dither_opt (char c, DitherAlgorithm* dither)
02599 {
02600 switch (c) {
02601 case '-':
02602 case 'n':
02603 *dither = None;
02604 break;
02605
02606 case 'r':
02607 *dither = Rectangular;
02608 break;
02609
02610 case 's':
02611 *dither = Shaped;
02612 break;
02613
02614 case 't':
02615 *dither = Triangular;
02616 break;
02617
02618 default:
02619 fprintf (stderr, "ALSA driver: illegal dithering mode %c\n", c);
02620 return -1;
02621 }
02622 return 0;
02623 }
02624
02625 SERVER_EXPORT const jack_driver_desc_t* driver_get_descriptor ()
02626 {
02627 jack_driver_desc_t * desc;
02628 jack_driver_param_desc_t * params;
02629 unsigned int i;
02630
02631 desc = (jack_driver_desc_t*)calloc (1, sizeof (jack_driver_desc_t));
02632
02633 strcpy(desc->name, "alsa");
02634 strcpy(desc->desc, "Linux ALSA API based audio backend");
02635
02636 desc->nparams = 18;
02637 params = (jack_driver_param_desc_t*)calloc (desc->nparams, sizeof (jack_driver_param_desc_t));
02638
02639 i = 0;
02640 strcpy (params[i].name, "capture");
02641 params[i].character = 'C';
02642 params[i].type = JackDriverParamString;
02643 strcpy (params[i].value.str, "none");
02644 strcpy (params[i].short_desc,
02645 "Provide capture ports. Optionally set device");
02646 strcpy (params[i].long_desc, params[i].short_desc);
02647
02648 i++;
02649 strcpy (params[i].name, "playback");
02650 params[i].character = 'P';
02651 params[i].type = JackDriverParamString;
02652 strcpy (params[i].value.str, "none");
02653 strcpy (params[i].short_desc,
02654 "Provide playback ports. Optionally set device");
02655 strcpy (params[i].long_desc, params[i].short_desc);
02656
02657 i++;
02658 strcpy (params[i].name, "device");
02659 params[i].character = 'd';
02660 params[i].type = JackDriverParamString;
02661 strcpy (params[i].value.str, "hw:0");
02662 strcpy (params[i].short_desc, "ALSA device name");
02663 strcpy (params[i].long_desc, params[i].short_desc);
02664 params[i].constraint = enum_alsa_devices();
02665
02666 i++;
02667 strcpy (params[i].name, "rate");
02668 params[i].character = 'r';
02669 params[i].type = JackDriverParamUInt;
02670 params[i].value.ui = 48000U;
02671 strcpy (params[i].short_desc, "Sample rate");
02672 strcpy (params[i].long_desc, params[i].short_desc);
02673
02674 i++;
02675 strcpy (params[i].name, "period");
02676 params[i].character = 'p';
02677 params[i].type = JackDriverParamUInt;
02678 params[i].value.ui = 1024U;
02679 strcpy (params[i].short_desc, "Frames per period");
02680 strcpy (params[i].long_desc, params[i].short_desc);
02681
02682 i++;
02683 strcpy (params[i].name, "nperiods");
02684 params[i].character = 'n';
02685 params[i].type = JackDriverParamUInt;
02686 params[i].value.ui = 2U;
02687 strcpy (params[i].short_desc, "Number of periods of playback latency");
02688 strcpy (params[i].long_desc, params[i].short_desc);
02689
02690 i++;
02691 strcpy (params[i].name, "hwmon");
02692 params[i].character = 'H';
02693 params[i].type = JackDriverParamBool;
02694 params[i].value.i = 0;
02695 strcpy (params[i].short_desc, "Hardware monitoring, if available");
02696 strcpy (params[i].long_desc, params[i].short_desc);
02697
02698 i++;
02699 strcpy (params[i].name, "hwmeter");
02700 params[i].character = 'M';
02701 params[i].type = JackDriverParamBool;
02702 params[i].value.i = 0;
02703 strcpy (params[i].short_desc, "Hardware metering, if available");
02704 strcpy (params[i].long_desc, params[i].short_desc);
02705
02706 i++;
02707 strcpy (params[i].name, "duplex");
02708 params[i].character = 'D';
02709 params[i].type = JackDriverParamBool;
02710 params[i].value.i = 1;
02711 strcpy (params[i].short_desc,
02712 "Provide both capture and playback ports");
02713 strcpy (params[i].long_desc, params[i].short_desc);
02714
02715 i++;
02716 strcpy (params[i].name, "softmode");
02717 params[i].character = 's';
02718 params[i].type = JackDriverParamBool;
02719 params[i].value.i = 0;
02720 strcpy (params[i].short_desc, "Soft-mode, no xrun handling");
02721 strcpy (params[i].long_desc, params[i].short_desc);
02722
02723 i++;
02724 strcpy (params[i].name, "monitor");
02725 params[i].character = 'm';
02726 params[i].type = JackDriverParamBool;
02727 params[i].value.i = 0;
02728 strcpy (params[i].short_desc, "Provide monitor ports for the output");
02729 strcpy (params[i].long_desc, params[i].short_desc);
02730
02731 i++;
02732 strcpy (params[i].name, "dither");
02733 params[i].character = 'z';
02734 params[i].type = JackDriverParamChar;
02735 params[i].value.c = 'n';
02736 strcpy (params[i].short_desc, "Dithering mode");
02737 strcpy (params[i].long_desc,
02738 "Dithering mode:\n"
02739 " n - none\n"
02740 " r - rectangular\n"
02741 " s - shaped\n"
02742 " t - triangular");
02743 params[i].constraint = get_dither_constraint();
02744
02745 i++;
02746 strcpy (params[i].name, "inchannels");
02747 params[i].character = 'i';
02748 params[i].type = JackDriverParamUInt;
02749 params[i].value.i = 0;
02750 strcpy (params[i].short_desc,
02751 "Number of capture channels (defaults to hardware max)");
02752 strcpy (params[i].long_desc, params[i].short_desc);
02753
02754 i++;
02755 strcpy (params[i].name, "outchannels");
02756 params[i].character = 'o';
02757 params[i].type = JackDriverParamUInt;
02758 params[i].value.i = 0;
02759 strcpy (params[i].short_desc,
02760 "Number of playback channels (defaults to hardware max)");
02761 strcpy (params[i].long_desc, params[i].short_desc);
02762
02763 i++;
02764 strcpy (params[i].name, "shorts");
02765 params[i].character = 'S';
02766 params[i].type = JackDriverParamBool;
02767 params[i].value.i = FALSE;
02768 strcpy (params[i].short_desc, "Try 16-bit samples before 32-bit");
02769 strcpy (params[i].long_desc, params[i].short_desc);
02770
02771 i++;
02772 strcpy (params[i].name, "input-latency");
02773 params[i].character = 'I';
02774 params[i].type = JackDriverParamUInt;
02775 params[i].value.i = 0;
02776 strcpy (params[i].short_desc, "Extra input latency (frames)");
02777 strcpy (params[i].long_desc, params[i].short_desc);
02778
02779 i++;
02780 strcpy (params[i].name, "output-latency");
02781 params[i].character = 'O';
02782 params[i].type = JackDriverParamUInt;
02783 params[i].value.i = 0;
02784 strcpy (params[i].short_desc, "Extra output latency (frames)");
02785 strcpy (params[i].long_desc, params[i].short_desc);
02786
02787 i++;
02788 strcpy (params[i].name, "midi-driver");
02789 params[i].character = 'X';
02790 params[i].type = JackDriverParamString;
02791 strcpy (params[i].value.str, "none");
02792 strcpy (params[i].short_desc, "ALSA MIDI driver name (seq|raw)");
02793 strcpy (params[i].long_desc,
02794 "ALSA MIDI driver:\n"
02795 " none - no MIDI driver\n"
02796 " seq - ALSA Sequencer driver\n"
02797 " raw - ALSA RawMIDI driver\n");
02798 params[i].constraint = get_midi_driver_constraint();
02799
02800 desc->params = params;
02801 return desc;
02802 }
02803
02804 SERVER_EXPORT Jack::JackDriverClientInterface* driver_initialize(Jack::JackLockedEngine* engine, Jack::JackSynchro* table, const JSList* params)
02805 {
02806 jack_nframes_t srate = 48000;
02807 jack_nframes_t frames_per_interrupt = 1024;
02808 unsigned long user_nperiods = 2;
02809 const char *playback_pcm_name = "hw:0";
02810 const char *capture_pcm_name = "hw:0";
02811 int hw_monitoring = FALSE;
02812 int hw_metering = FALSE;
02813 int capture = FALSE;
02814 int playback = FALSE;
02815 int soft_mode = FALSE;
02816 int monitor = FALSE;
02817 DitherAlgorithm dither = None;
02818 int user_capture_nchnls = 0;
02819 int user_playback_nchnls = 0;
02820 int shorts_first = FALSE;
02821 jack_nframes_t systemic_input_latency = 0;
02822 jack_nframes_t systemic_output_latency = 0;
02823 const JSList * node;
02824 const jack_driver_param_t * param;
02825 const char *midi_driver = "none";
02826
02827 for (node = params; node; node = jack_slist_next (node)) {
02828 param = (const jack_driver_param_t *) node->data;
02829
02830 switch (param->character) {
02831
02832 case 'C':
02833 capture = TRUE;
02834 if (strcmp (param->value.str, "none") != 0) {
02835 capture_pcm_name = strdup (param->value.str);
02836 jack_log("capture device %s", capture_pcm_name);
02837 }
02838 break;
02839
02840 case 'P':
02841 playback = TRUE;
02842 if (strcmp (param->value.str, "none") != 0) {
02843 playback_pcm_name = strdup (param->value.str);
02844 jack_log("playback device %s", playback_pcm_name);
02845 }
02846 break;
02847
02848 case 'D':
02849 playback = TRUE;
02850 capture = TRUE;
02851 break;
02852
02853 case 'd':
02854 playback_pcm_name = strdup (param->value.str);
02855 capture_pcm_name = strdup (param->value.str);
02856 jack_log("playback device %s", playback_pcm_name);
02857 jack_log("capture device %s", capture_pcm_name);
02858 break;
02859
02860 case 'H':
02861 hw_monitoring = param->value.i;
02862 break;
02863
02864 case 'm':
02865 monitor = param->value.i;
02866 break;
02867
02868 case 'M':
02869 hw_metering = param->value.i;
02870 break;
02871
02872 case 'r':
02873 srate = param->value.ui;
02874 jack_log("apparent rate = %d", srate);
02875 break;
02876
02877 case 'p':
02878 frames_per_interrupt = param->value.ui;
02879 jack_log("frames per period = %d", frames_per_interrupt);
02880 break;
02881
02882 case 'n':
02883 user_nperiods = param->value.ui;
02884 if (user_nperiods < 2)
02885 user_nperiods = 2;
02886 break;
02887
02888 case 's':
02889 soft_mode = param->value.i;
02890 break;
02891
02892 case 'z':
02893 if (dither_opt (param->value.c, &dither)) {
02894 return NULL;
02895 }
02896 break;
02897
02898 case 'i':
02899 user_capture_nchnls = param->value.ui;
02900 break;
02901
02902 case 'o':
02903 user_playback_nchnls = param->value.ui;
02904 break;
02905
02906 case 'S':
02907 shorts_first = param->value.i;
02908 break;
02909
02910 case 'I':
02911 systemic_input_latency = param->value.ui;
02912 break;
02913
02914 case 'O':
02915 systemic_output_latency = param->value.ui;
02916 break;
02917
02918 case 'X':
02919 midi_driver = strdup(param->value.str);
02920 break;
02921 }
02922 }
02923
02924
02925 if (!capture && !playback) {
02926 capture = TRUE;
02927 playback = TRUE;
02928 }
02929
02930 Jack::JackAlsaDriver* alsa_driver = new Jack::JackAlsaDriver("system", "alsa_pcm", engine, table);
02931 Jack::JackDriverClientInterface* threaded_driver = new Jack::JackThreadedDriver(alsa_driver);
02932
02933 if (alsa_driver->Open(frames_per_interrupt, user_nperiods, srate, hw_monitoring, hw_metering, capture, playback, dither, soft_mode, monitor,
02934 user_capture_nchnls, user_playback_nchnls, shorts_first, capture_pcm_name, playback_pcm_name,
02935 systemic_input_latency, systemic_output_latency, midi_driver) == 0) {
02936 return threaded_driver;
02937 } else {
02938 delete threaded_driver;
02939 return NULL;
02940 }
02941 }
02942
02943 #ifdef __cplusplus
02944 }
02945 #endif
02946
02947