src/audio/jack/SDL_jackaudio.c
changeset 12005 94f3f018d3eb
parent 11811 5d94cb6b24d3
child 12503 806492103856
     1.1 --- a/src/audio/jack/SDL_jackaudio.c	Tue May 29 11:18:01 2018 -0700
     1.2 +++ b/src/audio/jack/SDL_jackaudio.c	Fri Jun 01 19:43:53 2018 -0700
     1.3 @@ -44,7 +44,9 @@
     1.4  static jack_nframes_t (*JACK_jack_get_sample_rate) (jack_client_t *);
     1.5  static jack_nframes_t (*JACK_jack_get_buffer_size) (jack_client_t *);
     1.6  static jack_port_t * (*JACK_jack_port_register) (jack_client_t *, const char *, const char *, unsigned long, unsigned long);
     1.7 +static jack_port_t * (*JACK_jack_port_by_name) (jack_client_t *, const char *);
     1.8  static const char * (*JACK_jack_port_name) (const jack_port_t *);
     1.9 +static const char * (*JACK_jack_port_type) (const jack_port_t *);
    1.10  static int (*JACK_jack_connect) (jack_client_t *, const char *, const char *);
    1.11  static int (*JACK_jack_set_process_callback) (jack_client_t *, JackProcessCallback, void *);
    1.12  
    1.13 @@ -135,7 +137,9 @@
    1.14      SDL_JACK_SYM(jack_get_sample_rate);
    1.15      SDL_JACK_SYM(jack_get_buffer_size);
    1.16      SDL_JACK_SYM(jack_port_register);
    1.17 +    SDL_JACK_SYM(jack_port_by_name);
    1.18      SDL_JACK_SYM(jack_port_name);
    1.19 +    SDL_JACK_SYM(jack_port_type);
    1.20      SDL_JACK_SYM(jack_connect);
    1.21      SDL_JACK_SYM(jack_set_process_callback);
    1.22      return 0;
    1.23 @@ -273,10 +277,6 @@
    1.24          SDL_DestroySemaphore(this->hidden->iosem);
    1.25      }
    1.26  
    1.27 -    if (this->hidden->devports) {
    1.28 -        JACK_jack_free(this->hidden->devports);
    1.29 -    }
    1.30 -
    1.31      SDL_free(this->hidden->iobuffer);
    1.32  }
    1.33  
    1.34 @@ -292,9 +292,11 @@
    1.35      const JackProcessCallback callback = iscapture ? jackProcessCaptureCallback : jackProcessPlaybackCallback;
    1.36      const char *sdlportstr = iscapture ? "input" : "output";
    1.37      const char **devports = NULL;
    1.38 +    int *audio_ports;
    1.39      jack_client_t *client = NULL;
    1.40      jack_status_t status;
    1.41      int channels = 0;
    1.42 +    int ports = 0;
    1.43      int i;
    1.44  
    1.45      /* Initialize all variables that we clean on shutdown */
    1.46 @@ -311,15 +313,30 @@
    1.47      }
    1.48  
    1.49      devports = JACK_jack_get_ports(client, NULL, NULL, JackPortIsPhysical | sysportflags);
    1.50 -    this->hidden->devports = devports;
    1.51      if (!devports || !devports[0]) {
    1.52          return SDL_SetError("No physical JACK ports available");
    1.53      }
    1.54  
    1.55 -    while (devports[++channels]) {
    1.56 +    while (devports[++ports]) {
    1.57          /* spin to count devports */
    1.58      }
    1.59  
    1.60 +    /* Filter out non-audio ports */
    1.61 +    audio_ports = SDL_calloc(ports, sizeof *audio_ports);
    1.62 +    for (i = 0; i < ports; i++) {
    1.63 +        const jack_port_t *dport = JACK_jack_port_by_name(client, devports[i]);
    1.64 +        const char *type = JACK_jack_port_type(dport);
    1.65 +        const int len = SDL_strlen(type);
    1.66 +        /* See if type ends with "audio" */
    1.67 +        if (len >= 5 && !SDL_memcmp(type+len-5, "audio", 5)) {
    1.68 +            audio_ports[channels++] = i;
    1.69 +        }
    1.70 +    }
    1.71 +    if (channels == 0) {
    1.72 +        return SDL_SetError("No physical JACK ports available");
    1.73 +    }
    1.74 +
    1.75 +
    1.76      /* !!! FIXME: docs say about buffer size: "This size may change, clients that depend on it must register a bufsize_callback so they will be notified if it does." */
    1.77  
    1.78      /* Jack pretty much demands what it wants. */
    1.79 @@ -368,16 +385,16 @@
    1.80      /* once activated, we can connect all the ports. */
    1.81      for (i = 0; i < channels; i++) {
    1.82          const char *sdlport = JACK_jack_port_name(this->hidden->sdlports[i]);
    1.83 -        const char *srcport = iscapture ? devports[i] : sdlport;
    1.84 -        const char *dstport = iscapture ? sdlport : devports[i];
    1.85 +        const char *srcport = iscapture ? devports[audio_ports[i]] : sdlport;
    1.86 +        const char *dstport = iscapture ? sdlport : devports[audio_ports[i]];
    1.87          if (JACK_jack_connect(client, srcport, dstport) != 0) {
    1.88              return SDL_SetError("Couldn't connect JACK ports: %s => %s", srcport, dstport);
    1.89          }
    1.90      }
    1.91  
    1.92      /* don't need these anymore. */
    1.93 -    this->hidden->devports = NULL;
    1.94      JACK_jack_free(devports);
    1.95 +    SDL_free(audio_ports);
    1.96  
    1.97      /* We're ready to rock and roll. :-) */
    1.98      return 0;