jack: Move jack_client_t into the audio device instead a global variable.
authorRyan C. Gordon <icculus@icculus.org>
Fri, 09 Jun 2017 00:14:50 -0400
changeset 110834ca078346f4f
parent 11082 54d6e338db26
child 11084 5da1c02714b0
jack: Move jack_client_t into the audio device instead a global variable.
src/audio/jack/SDL_jackaudio.c
src/audio/jack/SDL_jackaudio.h
     1.1 --- a/src/audio/jack/SDL_jackaudio.c	Thu Jun 08 22:20:49 2017 -0400
     1.2 +++ b/src/audio/jack/SDL_jackaudio.c	Fri Jun 09 00:14:50 2017 -0400
     1.3 @@ -1,6 +1,6 @@
     1.4  /*
     1.5    Simple DirectMedia Layer
     1.6 -  Copyright (C) 1997-2016 Sam Lantinga <slouken@libsdl.org>
     1.7 +  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
     1.8  
     1.9    This software is provided 'as-is', without any express or implied
    1.10    warranty.  In no event will the authors be held liable for any damages
    1.11 @@ -36,6 +36,7 @@
    1.12  static int (*JACK_jack_client_close) (jack_client_t *);
    1.13  static void (*JACK_jack_on_shutdown) (jack_client_t *, JackShutdownCallback, void *);
    1.14  static int (*JACK_jack_activate) (jack_client_t *);
    1.15 +static int (*JACK_jack_deactivate) (jack_client_t *);
    1.16  static void * (*JACK_jack_port_get_buffer) (jack_port_t *, jack_nframes_t);
    1.17  static int (*JACK_jack_port_unregister) (jack_client_t *, jack_port_t *);
    1.18  static void (*JACK_jack_free) (void *);
    1.19 @@ -126,6 +127,7 @@
    1.20      SDL_JACK_SYM(jack_client_close);
    1.21      SDL_JACK_SYM(jack_on_shutdown);
    1.22      SDL_JACK_SYM(jack_activate);
    1.23 +    SDL_JACK_SYM(jack_deactivate);
    1.24      SDL_JACK_SYM(jack_port_get_buffer);
    1.25      SDL_JACK_SYM(jack_port_unregister);
    1.26      SDL_JACK_SYM(jack_free);
    1.27 @@ -140,49 +142,14 @@
    1.28  }
    1.29  
    1.30  
    1.31 -static jack_client_t *JACK_client = NULL;
    1.32 -
    1.33  static void
    1.34 -DisconnectFromJackServer(void)
    1.35 +jackShutdownCallback(void *arg)  /* JACK went away; device is lost. */
    1.36  {
    1.37 -    if (JACK_client) {
    1.38 -        JACK_jack_client_close(JACK_client);
    1.39 -        JACK_client = NULL;
    1.40 -    }
    1.41 +    SDL_AudioDevice *this = (SDL_AudioDevice *) arg;
    1.42 +    SDL_OpenedAudioDeviceDisconnected(this);
    1.43 +    SDL_SemPost(this->hidden->iosem);  /* unblock the SDL thread. */
    1.44  }
    1.45  
    1.46 -static void
    1.47 -jackShutdownCallback(void *arg)
    1.48 -{
    1.49 -    /* !!! FIXME: alert SDL that _every_ open device is lost here */
    1.50 -    fprintf(stderr, "SDL JACK FIXME: shutdown callback fired! All audio devices are lost!\n");
    1.51 -    fflush(stderr);
    1.52 -// !!! FIXME: need to put the client (and callback) in the SDL device    SDL_SemPost(this->hidden->iosem);  /* unblock the SDL thread. */
    1.53 -}
    1.54 -
    1.55 -static int
    1.56 -ConnectToJackServer(void)
    1.57 -{
    1.58 -    /* !!! FIXME: we _still_ need an API to specify an app name */
    1.59 -    jack_status_t status;
    1.60 -    JACK_client = JACK_jack_client_open("SDL", JackNoStartServer, &status, NULL);
    1.61 -    if (JACK_client == NULL) {
    1.62 -        return -1;
    1.63 -    }
    1.64 -
    1.65 -    JACK_jack_on_shutdown(JACK_client, jackShutdownCallback, NULL);
    1.66 -
    1.67 -#if 0  // !!! FIXME: we need to move JACK_client into the SDL audio device.
    1.68 -    if (JACK_jack_activate(JACK_client) != 0) {
    1.69 -        DisconnectFromJackServer();
    1.70 -        return -1;
    1.71 -    }
    1.72 -#endif
    1.73 -
    1.74 -    return 0;
    1.75 -}
    1.76 -
    1.77 -
    1.78  // !!! FIXME: implement and register these!
    1.79  //typedef int(* JackSampleRateCallback)(jack_nframes_t nframes, void *arg)
    1.80  //typedef int(* JackBufferSizeCallback)(jack_nframes_t nframes, void *arg)
    1.81 @@ -256,13 +223,19 @@
    1.82  static void
    1.83  JACK_CloseDevice(_THIS)
    1.84  {
    1.85 -    if (this->hidden->sdlports) {
    1.86 -        const int channels = this->spec.channels;
    1.87 -        int i;
    1.88 -        for (i = 0; i < channels; i++) {
    1.89 -            JACK_jack_port_unregister(JACK_client, this->hidden->sdlports[i]);
    1.90 +    if (this->hidden->client) {
    1.91 +        JACK_jack_deactivate(this->hidden->client);
    1.92 +
    1.93 +        if (this->hidden->sdlports) {
    1.94 +            const int channels = this->spec.channels;
    1.95 +            int i;
    1.96 +            for (i = 0; i < channels; i++) {
    1.97 +                JACK_jack_port_unregister(this->hidden->client, this->hidden->sdlports[i]);
    1.98 +            }
    1.99 +            SDL_free(this->hidden->sdlports);
   1.100          }
   1.101 -        SDL_free(this->hidden->sdlports);
   1.102 +
   1.103 +        JACK_jack_client_close(this->hidden->client);
   1.104      }
   1.105  
   1.106      if (this->hidden->iosem) {
   1.107 @@ -287,6 +260,8 @@
   1.108      const unsigned long sdlportflags = iscapture ? JackPortIsInput : JackPortIsOutput;
   1.109      const char *sdlportstr = iscapture ? "input" : "output";
   1.110      const char **devports = NULL;
   1.111 +    jack_client_t *client = NULL;
   1.112 +    jack_status_t status;
   1.113      int channels = 0;
   1.114      int i;
   1.115  
   1.116 @@ -296,7 +271,14 @@
   1.117          return SDL_OutOfMemory();
   1.118      }
   1.119  
   1.120 -    devports = JACK_jack_get_ports(JACK_client, NULL, NULL, JackPortIsPhysical | sysportflags);
   1.121 +    /* !!! FIXME: we _still_ need an API to specify an app name */
   1.122 +    client = JACK_jack_client_open("SDL", JackNoStartServer, &status, NULL);
   1.123 +    this->hidden->client = client;
   1.124 +    if (client == NULL) {
   1.125 +        return SDL_SetError("Can't open JACK client");
   1.126 +    }
   1.127 +
   1.128 +    devports = JACK_jack_get_ports(client, NULL, NULL, JackPortIsPhysical | sysportflags);
   1.129      this->hidden->devports = devports;
   1.130      if (!devports || !devports[0]) {
   1.131          return SDL_SetError("No physical JACK ports available");
   1.132 @@ -310,9 +292,9 @@
   1.133  
   1.134      /* Jack pretty much demands what it wants. */
   1.135      this->spec.format = AUDIO_F32SYS;
   1.136 -    this->spec.freq = JACK_jack_get_sample_rate(JACK_client);
   1.137 +    this->spec.freq = JACK_jack_get_sample_rate(client);
   1.138      this->spec.channels = channels;
   1.139 -    this->spec.samples = JACK_jack_get_buffer_size(JACK_client);
   1.140 +    this->spec.samples = JACK_jack_get_buffer_size(client);
   1.141  
   1.142      SDL_CalculateAudioSpec(&this->spec);
   1.143  
   1.144 @@ -332,21 +314,23 @@
   1.145          return SDL_OutOfMemory();
   1.146      }
   1.147  
   1.148 -    if (JACK_jack_set_process_callback(JACK_client, jackProcessPlaybackCallback, this) != 0) {
   1.149 -        return SDL_SetError("JACK: Couldn't set process callback");
   1.150 -    }
   1.151 -
   1.152      for (i = 0; i < channels; i++) {
   1.153          char portname[32];
   1.154          SDL_snprintf(portname, sizeof (portname), "sdl_jack_%s_%d", sdlportstr, i);
   1.155 -        this->hidden->sdlports[i] = JACK_jack_port_register(JACK_client, portname, JACK_DEFAULT_AUDIO_TYPE, sdlportflags, 0);
   1.156 +        this->hidden->sdlports[i] = JACK_jack_port_register(client, portname, JACK_DEFAULT_AUDIO_TYPE, sdlportflags, 0);
   1.157          if (this->hidden->sdlports[i] == NULL) {
   1.158              return SDL_SetError("jack_port_register failed");
   1.159          }
   1.160      }
   1.161  
   1.162 -    if (JACK_jack_activate(JACK_client) != 0) {
   1.163 -        return SDL_SetError("jack_activate failed");
   1.164 +    if (JACK_jack_set_process_callback(client, jackProcessPlaybackCallback, this) != 0) {
   1.165 +        return SDL_SetError("JACK: Couldn't set process callback");
   1.166 +    }
   1.167 +
   1.168 +    JACK_jack_on_shutdown(client, jackShutdownCallback, this);
   1.169 +
   1.170 +    if (JACK_jack_activate(client) != 0) {
   1.171 +        return SDL_SetError("Failed to activate JACK client");
   1.172      }
   1.173  
   1.174      /* once activated, we can connect all the ports. */
   1.175 @@ -356,7 +340,7 @@
   1.176          const char *sdlport = JACK_jack_port_name(this->hidden->sdlports[i]);
   1.177          const char *srcport = iscapture ? devports[i] : sdlport;
   1.178          const char *dstport = iscapture ? sdlport : devports[i];
   1.179 -        if (JACK_jack_connect(JACK_client, srcport, dstport) != 0) {
   1.180 +        if (JACK_jack_connect(client, srcport, dstport) != 0) {
   1.181              return SDL_SetError("Couldn't connect JACK ports: %s => %s", srcport, dstport);
   1.182          }
   1.183      }
   1.184 @@ -372,7 +356,6 @@
   1.185  static void
   1.186  JACK_Deinitialize(void)
   1.187  {
   1.188 -    DisconnectFromJackServer();
   1.189      UnloadJackLibrary();
   1.190  }
   1.191  
   1.192 @@ -381,11 +364,15 @@
   1.193  {
   1.194      if (LoadJackLibrary() < 0) {
   1.195          return 0;
   1.196 -    }
   1.197 -
   1.198 -    if (ConnectToJackServer() < 0) {
   1.199 -        UnloadJackLibrary();
   1.200 -        return 0;
   1.201 +    } else {
   1.202 +        /* Make sure a JACK server is running and available. */
   1.203 +        jack_status_t status;
   1.204 +        jack_client_t *client = JACK_jack_client_open("SDL", JackNoStartServer, &status, NULL);
   1.205 +        if (client == NULL) {
   1.206 +            UnloadJackLibrary();
   1.207 +            return 0;
   1.208 +        }
   1.209 +        JACK_jack_client_close(client);
   1.210      }
   1.211  
   1.212      /* Set the function pointers */
     2.1 --- a/src/audio/jack/SDL_jackaudio.h	Thu Jun 08 22:20:49 2017 -0400
     2.2 +++ b/src/audio/jack/SDL_jackaudio.h	Fri Jun 09 00:14:50 2017 -0400
     2.3 @@ -1,6 +1,6 @@
     2.4  /*
     2.5    Simple DirectMedia Layer
     2.6 -  Copyright (C) 1997-2016 Sam Lantinga <slouken@libsdl.org>
     2.7 +  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
     2.8  
     2.9    This software is provided 'as-is', without any express or implied
    2.10    warranty.  In no event will the authors be held liable for any damages
    2.11 @@ -30,6 +30,7 @@
    2.12  
    2.13  struct SDL_PrivateAudioData
    2.14  {
    2.15 +    jack_client_t *client;
    2.16      SDL_sem *iosem;
    2.17      float *iobuffer;
    2.18      const char **devports;