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