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

Generated on Thu Feb 14 11:16:01 2008 for Jackdmp by  doxygen 1.5.1