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