jack: added capture support.
authorRyan C. Gordon <icculus@icculus.org>
Fri, 09 Jun 2017 00:47:47 -0400
changeset 110845da1c02714b0
parent 11083 4ca078346f4f
child 11085 d03a7de85bd5
jack: added capture support.
src/audio/jack/SDL_jackaudio.c
     1.1 --- a/src/audio/jack/SDL_jackaudio.c	Fri Jun 09 00:14:50 2017 -0400
     1.2 +++ b/src/audio/jack/SDL_jackaudio.c	Fri Jun 09 00:47:47 2017 -0400
     1.3 @@ -203,22 +203,53 @@
     1.4  }
     1.5  
     1.6  
     1.7 -#if 0 // !!! FIXME
     1.8 -/* JACK thread calls this. */
     1.9  static int
    1.10  jackProcessCaptureCallback(jack_nframes_t nframes, void *arg)
    1.11  {
    1.12 -    jack_port_get_buffer(
    1.13 -asdasd
    1.14 +    SDL_AudioDevice *this = (SDL_AudioDevice *) arg;
    1.15 +    if (SDL_AtomicGet(&this->enabled)) {
    1.16 +        jack_port_t **ports = this->hidden->sdlports;
    1.17 +        const int total_channels = this->spec.channels;
    1.18 +        const int total_frames = this->spec.samples;
    1.19 +        int channelsi;
    1.20 +    
    1.21 +        for (channelsi = 0; channelsi < total_channels; channelsi++) {
    1.22 +            const float *src = (const float *) JACK_jack_port_get_buffer(ports[channelsi], nframes);
    1.23 +            if (src) {
    1.24 +                float *dst = ((float *) this->hidden->iobuffer) + channelsi;
    1.25 +                int framesi;
    1.26 +                for (framesi = 0; framesi < total_frames; framesi++) {
    1.27 +                    *dst = *(src++);
    1.28 +                    dst += total_channels;
    1.29 +                }
    1.30 +            }
    1.31 +        }
    1.32 +    }
    1.33 +
    1.34 +    SDL_SemPost(this->hidden->iosem);  /* tell SDL thread we're done; new buffer is ready! */
    1.35 +    return 0;  /* success */
    1.36  }
    1.37  
    1.38 -/* SDL thread calls this. */
    1.39  static int
    1.40  JACK_CaptureFromDevice(_THIS, void *buffer, int buflen)
    1.41  {
    1.42 -    return SDL_SemWait(this->hidden->iosem) == 0) ? buflen : -1;
    1.43 +    SDL_assert(buflen == this->spec.size);  /* we always fill a full buffer. */
    1.44 +
    1.45 +    /* Wait for JACK to fill the iobuffer */
    1.46 +    if (SDL_SemWait(this->hidden->iosem) == -1) {
    1.47 +        return -1;
    1.48 +    }
    1.49 +
    1.50 +    SDL_memcpy(buffer, this->hidden->iobuffer, buflen);
    1.51 +    return buflen;
    1.52  }
    1.53 -#endif
    1.54 +
    1.55 +static void
    1.56 +JACK_FlushCapture(_THIS)
    1.57 +{
    1.58 +    SDL_SemWait(this->hidden->iosem);
    1.59 +}
    1.60 +
    1.61  
    1.62  static void
    1.63  JACK_CloseDevice(_THIS)
    1.64 @@ -258,6 +289,7 @@
    1.65          and capture will be "input" (we read data in). */
    1.66      const unsigned long sysportflags = iscapture ? JackPortIsOutput : JackPortIsInput;
    1.67      const unsigned long sdlportflags = iscapture ? JackPortIsInput : JackPortIsOutput;
    1.68 +    const JackProcessCallback callback = iscapture ? jackProcessCaptureCallback : jackProcessPlaybackCallback;
    1.69      const char *sdlportstr = iscapture ? "input" : "output";
    1.70      const char **devports = NULL;
    1.71      jack_client_t *client = NULL;
    1.72 @@ -323,7 +355,7 @@
    1.73          }
    1.74      }
    1.75  
    1.76 -    if (JACK_jack_set_process_callback(client, jackProcessPlaybackCallback, this) != 0) {
    1.77 +    if (JACK_jack_set_process_callback(client, callback, this) != 0) {
    1.78          return SDL_SetError("JACK: Couldn't set process callback");
    1.79      }
    1.80  
    1.81 @@ -376,17 +408,16 @@
    1.82      }
    1.83  
    1.84      /* Set the function pointers */
    1.85 -
    1.86 -    impl->OnlyHasDefaultOutputDevice = SDL_TRUE;
    1.87 -    // !!! FIXME impl->OnlyHasDefaultCaptureDevice = SDL_TRUE;
    1.88 -
    1.89      impl->OpenDevice = JACK_OpenDevice;
    1.90      impl->WaitDevice = JACK_WaitDevice;
    1.91      impl->GetDeviceBuf = JACK_GetDeviceBuf;
    1.92      impl->CloseDevice = JACK_CloseDevice;
    1.93      impl->Deinitialize = JACK_Deinitialize;
    1.94 -    // !!! FIXME impl->CaptureFromDevice = JACK_CaptureFromDevice;
    1.95 -    // !!! FIXME impl->HasCaptureSupport = SDL_TRUE;
    1.96 +    impl->CaptureFromDevice = JACK_CaptureFromDevice;
    1.97 +    impl->FlushCapture = JACK_FlushCapture;
    1.98 +    impl->OnlyHasDefaultOutputDevice = SDL_TRUE;
    1.99 +    impl->OnlyHasDefaultCaptureDevice = SDL_TRUE;
   1.100 +    impl->HasCaptureSupport = SDL_TRUE;
   1.101  
   1.102      return 1;   /* this audio target is available. */
   1.103  }