Jack2 1.9.6

JackAlsaDriver.cpp

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