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