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

Generated for Jack2 by doxygen 1.7.3