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

Generated on Wed Jan 10 11:42:43 2007 for Jackdmp by  doxygen 1.4.5