src/audio/jack/SDL_jackaudio.c
changeset 12005 94f3f018d3eb
parent 11811 5d94cb6b24d3
child 12503 806492103856
equal deleted inserted replaced
12004:757d81897470 12005:94f3f018d3eb
    42 static void (*JACK_jack_free) (void *);
    42 static void (*JACK_jack_free) (void *);
    43 static const char ** (*JACK_jack_get_ports) (jack_client_t *, const char *, const char *, unsigned long);
    43 static const char ** (*JACK_jack_get_ports) (jack_client_t *, const char *, const char *, unsigned long);
    44 static jack_nframes_t (*JACK_jack_get_sample_rate) (jack_client_t *);
    44 static jack_nframes_t (*JACK_jack_get_sample_rate) (jack_client_t *);
    45 static jack_nframes_t (*JACK_jack_get_buffer_size) (jack_client_t *);
    45 static jack_nframes_t (*JACK_jack_get_buffer_size) (jack_client_t *);
    46 static jack_port_t * (*JACK_jack_port_register) (jack_client_t *, const char *, const char *, unsigned long, unsigned long);
    46 static jack_port_t * (*JACK_jack_port_register) (jack_client_t *, const char *, const char *, unsigned long, unsigned long);
       
    47 static jack_port_t * (*JACK_jack_port_by_name) (jack_client_t *, const char *);
    47 static const char * (*JACK_jack_port_name) (const jack_port_t *);
    48 static const char * (*JACK_jack_port_name) (const jack_port_t *);
       
    49 static const char * (*JACK_jack_port_type) (const jack_port_t *);
    48 static int (*JACK_jack_connect) (jack_client_t *, const char *, const char *);
    50 static int (*JACK_jack_connect) (jack_client_t *, const char *, const char *);
    49 static int (*JACK_jack_set_process_callback) (jack_client_t *, JackProcessCallback, void *);
    51 static int (*JACK_jack_set_process_callback) (jack_client_t *, JackProcessCallback, void *);
    50 
    52 
    51 static int load_jack_syms(void);
    53 static int load_jack_syms(void);
    52 
    54 
   133     SDL_JACK_SYM(jack_free);
   135     SDL_JACK_SYM(jack_free);
   134     SDL_JACK_SYM(jack_get_ports);
   136     SDL_JACK_SYM(jack_get_ports);
   135     SDL_JACK_SYM(jack_get_sample_rate);
   137     SDL_JACK_SYM(jack_get_sample_rate);
   136     SDL_JACK_SYM(jack_get_buffer_size);
   138     SDL_JACK_SYM(jack_get_buffer_size);
   137     SDL_JACK_SYM(jack_port_register);
   139     SDL_JACK_SYM(jack_port_register);
       
   140     SDL_JACK_SYM(jack_port_by_name);
   138     SDL_JACK_SYM(jack_port_name);
   141     SDL_JACK_SYM(jack_port_name);
       
   142     SDL_JACK_SYM(jack_port_type);
   139     SDL_JACK_SYM(jack_connect);
   143     SDL_JACK_SYM(jack_connect);
   140     SDL_JACK_SYM(jack_set_process_callback);
   144     SDL_JACK_SYM(jack_set_process_callback);
   141     return 0;
   145     return 0;
   142 }
   146 }
   143 
   147 
   271 
   275 
   272     if (this->hidden->iosem) {
   276     if (this->hidden->iosem) {
   273         SDL_DestroySemaphore(this->hidden->iosem);
   277         SDL_DestroySemaphore(this->hidden->iosem);
   274     }
   278     }
   275 
   279 
   276     if (this->hidden->devports) {
       
   277         JACK_jack_free(this->hidden->devports);
       
   278     }
       
   279 
       
   280     SDL_free(this->hidden->iobuffer);
   280     SDL_free(this->hidden->iobuffer);
   281 }
   281 }
   282 
   282 
   283 static int
   283 static int
   284 JACK_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
   284 JACK_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
   290     const unsigned long sysportflags = iscapture ? JackPortIsOutput : JackPortIsInput;
   290     const unsigned long sysportflags = iscapture ? JackPortIsOutput : JackPortIsInput;
   291     const unsigned long sdlportflags = iscapture ? JackPortIsInput : JackPortIsOutput;
   291     const unsigned long sdlportflags = iscapture ? JackPortIsInput : JackPortIsOutput;
   292     const JackProcessCallback callback = iscapture ? jackProcessCaptureCallback : jackProcessPlaybackCallback;
   292     const JackProcessCallback callback = iscapture ? jackProcessCaptureCallback : jackProcessPlaybackCallback;
   293     const char *sdlportstr = iscapture ? "input" : "output";
   293     const char *sdlportstr = iscapture ? "input" : "output";
   294     const char **devports = NULL;
   294     const char **devports = NULL;
       
   295     int *audio_ports;
   295     jack_client_t *client = NULL;
   296     jack_client_t *client = NULL;
   296     jack_status_t status;
   297     jack_status_t status;
   297     int channels = 0;
   298     int channels = 0;
       
   299     int ports = 0;
   298     int i;
   300     int i;
   299 
   301 
   300     /* Initialize all variables that we clean on shutdown */
   302     /* Initialize all variables that we clean on shutdown */
   301     this->hidden = (struct SDL_PrivateAudioData *) SDL_calloc(1, sizeof (*this->hidden));
   303     this->hidden = (struct SDL_PrivateAudioData *) SDL_calloc(1, sizeof (*this->hidden));
   302     if (this->hidden == NULL) {
   304     if (this->hidden == NULL) {
   309     if (client == NULL) {
   311     if (client == NULL) {
   310         return SDL_SetError("Can't open JACK client");
   312         return SDL_SetError("Can't open JACK client");
   311     }
   313     }
   312 
   314 
   313     devports = JACK_jack_get_ports(client, NULL, NULL, JackPortIsPhysical | sysportflags);
   315     devports = JACK_jack_get_ports(client, NULL, NULL, JackPortIsPhysical | sysportflags);
   314     this->hidden->devports = devports;
       
   315     if (!devports || !devports[0]) {
   316     if (!devports || !devports[0]) {
   316         return SDL_SetError("No physical JACK ports available");
   317         return SDL_SetError("No physical JACK ports available");
   317     }
   318     }
   318 
   319 
   319     while (devports[++channels]) {
   320     while (devports[++ports]) {
   320         /* spin to count devports */
   321         /* spin to count devports */
   321     }
   322     }
       
   323 
       
   324     /* Filter out non-audio ports */
       
   325     audio_ports = SDL_calloc(ports, sizeof *audio_ports);
       
   326     for (i = 0; i < ports; i++) {
       
   327         const jack_port_t *dport = JACK_jack_port_by_name(client, devports[i]);
       
   328         const char *type = JACK_jack_port_type(dport);
       
   329         const int len = SDL_strlen(type);
       
   330         /* See if type ends with "audio" */
       
   331         if (len >= 5 && !SDL_memcmp(type+len-5, "audio", 5)) {
       
   332             audio_ports[channels++] = i;
       
   333         }
       
   334     }
       
   335     if (channels == 0) {
       
   336         return SDL_SetError("No physical JACK ports available");
       
   337     }
       
   338 
   322 
   339 
   323     /* !!! 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." */
   340     /* !!! 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." */
   324 
   341 
   325     /* Jack pretty much demands what it wants. */
   342     /* Jack pretty much demands what it wants. */
   326     this->spec.format = AUDIO_F32SYS;
   343     this->spec.format = AUDIO_F32SYS;
   366     }
   383     }
   367 
   384 
   368     /* once activated, we can connect all the ports. */
   385     /* once activated, we can connect all the ports. */
   369     for (i = 0; i < channels; i++) {
   386     for (i = 0; i < channels; i++) {
   370         const char *sdlport = JACK_jack_port_name(this->hidden->sdlports[i]);
   387         const char *sdlport = JACK_jack_port_name(this->hidden->sdlports[i]);
   371         const char *srcport = iscapture ? devports[i] : sdlport;
   388         const char *srcport = iscapture ? devports[audio_ports[i]] : sdlport;
   372         const char *dstport = iscapture ? sdlport : devports[i];
   389         const char *dstport = iscapture ? sdlport : devports[audio_ports[i]];
   373         if (JACK_jack_connect(client, srcport, dstport) != 0) {
   390         if (JACK_jack_connect(client, srcport, dstport) != 0) {
   374             return SDL_SetError("Couldn't connect JACK ports: %s => %s", srcport, dstport);
   391             return SDL_SetError("Couldn't connect JACK ports: %s => %s", srcport, dstport);
   375         }
   392         }
   376     }
   393     }
   377 
   394 
   378     /* don't need these anymore. */
   395     /* don't need these anymore. */
   379     this->hidden->devports = NULL;
       
   380     JACK_jack_free(devports);
   396     JACK_jack_free(devports);
       
   397     SDL_free(audio_ports);
   381 
   398 
   382     /* We're ready to rock and roll. :-) */
   399     /* We're ready to rock and roll. :-) */
   383     return 0;
   400     return 0;
   384 }
   401 }
   385 
   402