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