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