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