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