10#define JDEBUG(...)     Ase::debug ("jack", __VA_ARGS__) 
   12#if __has_include(<jack/jack.h>) 
   15#define MAX_JACK_STRING_SIZE    1024 
   96class FrameRingBuffer {
 
  102  uint                channel_buffer_size_ = 0;       
 
  104  uint                n_channels_ = 0;
 
  106  FrameRingBuffer (
uint n_frames = 0,
 
  109    resize (n_frames, n_channels);
 
  118  get_readable_frames()
 
  120    int wpos = atomic_write_frame_pos_;
 
  121    int rpos = atomic_read_frame_pos_;
 
  124      wpos += channel_buffer_size_;
 
  141    int rpos = atomic_read_frame_pos_;
 
  142    uint can_read = 
std::min (get_readable_frames(), n_frames);
 
  144    uint read1 = 
std::min (can_read, channel_buffer_size_ - rpos);
 
  145    uint read2 = can_read - read1;
 
  147    for (
uint ch = 0; ch < n_channels_; ch++)
 
  149    fast_copy (read1, frames[ch], &channel_buffer_[ch][rpos]);
 
  150    fast_copy (read2, frames[ch] + read1, &channel_buffer_[ch][0]);
 
  153    atomic_read_frame_pos_ = (rpos + can_read) % channel_buffer_size_;
 
  163  get_writable_frames()
 
  165    int wpos = atomic_write_frame_pos_;
 
  166    int rpos = atomic_read_frame_pos_;
 
  169      rpos += channel_buffer_size_;
 
  172    return rpos - wpos - 1;
 
  187    int wpos = atomic_write_frame_pos_;
 
  188    uint can_write = 
std::min (get_writable_frames(), n_frames);
 
  190    uint write1 = 
std::min (can_write, channel_buffer_size_ - wpos);
 
  191    uint write2 = can_write - write1;
 
  193    for (
uint ch = 0; ch < n_channels_; ch++)
 
  195    fast_copy (write1, &channel_buffer_[ch][wpos], frames[ch]);
 
  196    fast_copy (write2, &channel_buffer_[ch][0], frames[ch] + write1);
 
  205    atomic_write_frame_pos_ = (wpos + can_write) % channel_buffer_size_;
 
  215  get_total_n_frames()
 const 
  218    return channel_buffer_size_ - 1;
 
  227  get_n_channels()
 const 
  240    atomic_read_frame_pos_ = 0;
 
  241    atomic_write_frame_pos_ = 0;
 
  250  resize (
uint n_frames,
 
  253    n_channels_ = n_channels;
 
  254    channel_buffer_.resize (n_channels);
 
  257    channel_buffer_size_ = n_frames + 1;
 
  258    for (
uint ch = 0; ch < n_channels_; ch++)
 
  259      channel_buffer_[ch].resize (channel_buffer_size_);
 
  266error_callback_silent (
const char *msg)
 
  268  JDEBUG (
"%s\n", msg);
 
  272error_callback_show (
const char *msg)
 
  274  Ase::printerr (
"JACK: %s\n", msg);
 
  277static jack_client_t *
 
  281  jack_set_error_function (error_callback_silent);
 
  284  jack_client_t *jack_client;
 
  286    const String thisthreadname = this_thread_get_name();       
 
  287    this_thread_set_name (
"JackPcmDriver-C");
 
  288    jack_client = jack_client_open (
executable_name().c_str(), JackNoStartServer, &status);
 
  289    this_thread_set_name (thisthreadname);                      
 
  292  jack_set_error_function (error_callback_show);
 
  294  JDEBUG (
"attaching to server returned status: %d\n", status);
 
  299disconnect_jack (jack_client_t *jack_client)
 
  303  jack_deactivate (jack_client);
 
  304  jack_client_close (jack_client);
 
  307struct DeviceDetails {
 
  309  uint input_ports = 0;
 
  310  uint output_ports = 0;
 
  311  uint physical_ports = 0;
 
  312  uint terminal_ports = 0;
 
  313  bool default_device = 
false;
 
  321query_jack_devices (jack_client_t *jack_client)
 
  326  assert_return (MAX_JACK_STRING_SIZE >= jack_port_name_size(), devices);
 
  328  const char **jack_ports = jack_get_ports (jack_client, NULL, NULL, 0);
 
  331      bool have_default_device = 
false;
 
  333      for (
uint i = 0; jack_ports[i]; i++)
 
  335          jack_port_t *jack_port = jack_port_by_name (jack_client, jack_ports[i]);
 
  336      const char *
end = 
strchr (jack_ports[i], 
':');
 
  337      if (!jack_port || !end)
 
  341          const char *port_type = jack_port_type (jack_port);
 
  342          if (strcmp (port_type, JACK_DEFAULT_AUDIO_TYPE) == 0)
 
  344              DeviceDetails &details = devices[device_name];
 
  347              const int flags = jack_port_flags (jack_port);
 
  348              if (flags & JackPortIsInput)
 
  350                  details.input_ports++;
 
  351                  details.input_port_names.push_back (jack_ports[i]);
 
  353              if (flags & JackPortIsOutput)
 
  355                  details.output_ports++;
 
  356                  details.output_port_names.push_back (jack_ports[i]);
 
  358              if (flags & JackPortIsTerminal)
 
  359                details.terminal_ports++;
 
  360              if (flags & JackPortIsPhysical)
 
  362                  details.physical_ports++;
 
  364                  if (!have_default_device && (flags & JackPortIsInput))
 
  367                      details.default_device = 
true;
 
  368                      have_default_device = 
true;
 
  369                      char alias1[MAX_JACK_STRING_SIZE] = 
"", alias2[MAX_JACK_STRING_SIZE] = 
"";
 
  370                      char *aliases[2] = { alias1, alias2, };
 
  371                      const int cnt = jack_port_get_aliases (jack_port, aliases);
 
  372                      if (cnt >= 1 && alias1[0])
 
  374                          const char *acolon = 
strrchr (alias1, 
':');
 
  375                          details.input_port_alias = acolon ? 
std::string (alias1, acolon - alias1) : alias1;
 
  388list_jack_drivers (Driver::EntryVec &entries)
 
  391  jack_client_t *jack_client = connect_jack();
 
  394      devices = query_jack_devices (jack_client);
 
  395      disconnect_jack (jack_client);
 
  401      DeviceDetails &details = di->second;
 
  406      if (details.default_device && (details.input_ports || details.output_ports))
 
  410          entry.device_name = 
string_format (
"JACK \"%s\" Audio Device", devid);
 
  411          const std::string phprefix = details.physical_ports == details.ports ? 
"Physical: " : 
"";
 
  412          if (!details.input_port_alias.empty())
 
  413            entry.device_name += 
" [" + phprefix + details.input_port_alias + 
"]";
 
  414          entry.capabilities = details.output_ports && details.input_ports ? 
"Full-Duplex Audio" : details.output_ports ? 
"Audio Input" : 
"Audio Output";
 
  415          entry.capabilities += 
string_format (
", channels: %d*playback + %d*capture", details.input_ports, details.output_ports);
 
  416          entry.device_info = 
"Routing via the JACK Audio Connection Kit";
 
  417          if (details.physical_ports == details.ports)
 
  418            entry.notice = 
"Note: JACK adds latency compared to direct hardware access";
 
  419          entry.priority = Driver::JACK;
 
  420          entries.push_back (entry);
 
  430#define TEST_DROPOUT() if (unlink ("/tmp/ase-dropout") == 0) usleep (1.5 * 1000000. * buffer_frames_ / mix_freq_);  
  434  jack_client_t                *jack_client_ = 
nullptr;
 
  435  uint                          n_channels_ = 0;
 
  439  FrameRingBuffer<float>        input_ringbuffer_;
 
  440  FrameRingBuffer<float>        output_ringbuffer_;
 
  441  uint                          buffer_frames_ = 0;        
 
  442  uint                          block_length_ = 0;
 
  446  int                           printed_xruns_ = 0;
 
  448  bool                          is_down_ = 
false;
 
  449  bool                          printed_is_down_ = 
false;
 
  451  uint64                        device_read_counter_ = 0;
 
  452  uint64                        device_write_counter_ = 0;
 
  453  int                           device_open_counter_ = 0;
 
  456  process_callback (jack_nframes_t n_frames)
 
  462    const float *in_values[n_channels_];
 
  463    float *out_values[n_channels_];
 
  464    for (
uint ch = 0; ch < n_channels_; ch++)
 
  466        in_values[ch] = (
float *) jack_port_get_buffer (input_ports_[ch], n_frames);
 
  467        out_values[ch] = (
float *) jack_port_get_buffer (output_ports_[ch], n_frames);
 
  472        for (
auto values : out_values)
 
  475    else if (input_ringbuffer_.get_writable_frames() >= n_frames && output_ringbuffer_.get_readable_frames() >= n_frames)
 
  478        uint frames_written = input_ringbuffer_.write (n_frames, in_values);
 
  482        uint read_frames = output_ringbuffer_.read (n_frames, out_values);
 
  490        for (
auto values : out_values)
 
  496  static jack_latency_range_t
 
  498                         jack_latency_callback_mode_t mode)
 
  500    jack_latency_range_t range = { 0, 0 };
 
  503    for (
size_t p = 0; p < ports.size(); p++)
 
  505        jack_latency_range_t port_range;
 
  507        jack_port_get_latency_range (ports[p], mode, &port_range);
 
  513            range.min = 
std::min (range.min, port_range.min);
 
  514            range.max = 
std::max (range.max, port_range.max);
 
  520  latency_callback (jack_latency_callback_mode_t mode)
 
  523    if (mode == JackCaptureLatency)
 
  525        jack_latency_range_t range = get_latency_for_ports (input_ports_, mode);
 
  526        range.min += buffer_frames_;
 
  527        range.max += buffer_frames_;
 
  529        for (
auto port : output_ports_)
 
  530          jack_port_set_latency_range (port, mode, &range);
 
  534        jack_latency_range_t range = get_latency_for_ports (output_ports_, mode);
 
  535        range.min += buffer_frames_;
 
  536        range.max += buffer_frames_;
 
  538        for (
auto port : input_ports_)
 
  539          jack_port_set_latency_range (port, mode, &range);
 
  548  JackPcmDriver (
const String &driver, 
const String &devid) :
 
  552  create (
const String &devid)
 
  563  pcm_n_channels ()
 const override 
  568  pcm_mix_freq ()
 const override 
  573  pcm_block_length ()
 const override 
  575    return block_length_;
 
  581    disconnect_jack (jack_client_);
 
  582    jack_client_ = 
nullptr;
 
  589    assert_return (device_open_counter_++ == 0, Error::INTERNAL);    
 
  591    jack_client_ = connect_jack();
 
  593      return Ase::Error::FILE_OPEN_FAILED;
 
  596    flags_ |= Flags::READABLE | Flags::WRITABLE;
 
  597    n_channels_ = config.n_channels;
 
  602    mix_freq_ = jack_get_sample_rate (jack_client_);
 
  603    block_length_ = config.block_length;
 
  605    for (
uint i = 0; i < n_channels_; i++)
 
  607        const int port_name_size = jack_port_name_size();
 
  608        char port_name[port_name_size];
 
  611        snprintf (port_name, port_name_size, 
"in_%u", i);
 
  612        port = jack_port_register (jack_client_, port_name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0);
 
  614          input_ports_.push_back (port);
 
  616          error = Ase::Error::FILE_OPEN_FAILED;
 
  618        snprintf (port_name, port_name_size, 
"out_%u", i);
 
  619        port = jack_port_register (jack_client_, port_name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
 
  621          output_ports_.push_back (port);
 
  623          error = Ase::Error::FILE_OPEN_FAILED;
 
  630        uint min_buffer_frames = jack_get_buffer_size (jack_client_) * 2;
 
  635        min_buffer_frames += config.block_length;
 
  642        uint user_buffer_frames = config.latency_ms * config.mix_freq / 1000;
 
  643        uint buffer_frames = 
std::max (min_buffer_frames, user_buffer_frames);
 
  645        input_ringbuffer_.resize (buffer_frames, n_channels_);
 
  646        output_ringbuffer_.resize (buffer_frames, n_channels_);
 
  647        buffer_frames_ = output_ringbuffer_.get_writable_frames();
 
  650        if (buffer_frames_ != buffer_frames)
 
  652            Ase::warning (
"JACK driver: ring buffer size not correct: (buffer_frames_ != buffer_frames); (%u != %u)\n",
 
  653                          buffer_frames_, buffer_frames);
 
  654            error = Ase::Error::INTERNAL;
 
  656        JDEBUG (
"%s: ringbuffer size=%d duration=%.3fms", devid_, buffer_frames_, buffer_frames_ / 
double (mix_freq_) * 1000);
 
  664        fill (silence_buffers.begin(), silence_buffers.end(), &silence[0]);
 
  666        uint frames_written = output_ringbuffer_.write (buffer_frames, &silence_buffers[0]);
 
  667        if (frames_written != buffer_frames)
 
  668          Ase::warning (
"JACK driver: output silence init failed: (frames_written != jack->buffer_frames)\n");
 
  674        jack_set_process_callback (jack_client_, [] (jack_nframes_t n_frames, 
void *p) {
 
  675          return static_cast <JackPcmDriver *
> (p)->process_callback (n_frames);
 
  678        jack_set_latency_callback (jack_client_, [] (jack_latency_callback_mode_t mode, 
void *p) {
 
  679          static_cast <JackPcmDriver *
> (p)->latency_callback (mode);
 
  682        jack_on_shutdown (jack_client_, [] (
void *p) {
 
  683          static_cast<JackPcmDriver *
> (p)->shutdown_callback();
 
  688          const String thisthreadname = this_thread_get_name();       
 
  689          this_thread_set_name (
"JackPcmDriver-A");
 
  690          active_err = jack_activate (jack_client_);
 
  691          this_thread_set_name (thisthreadname);                      
 
  695          error = Ase::Error::FILE_OPEN_FAILED;
 
  704        di = devices.find (devid_);
 
  705        if (di != devices.end())
 
  707            const DeviceDetails &details = di->second;
 
  709            for (
uint ch = 0; ch < n_channels_; ch++)
 
  711                if (details.output_ports > ch)
 
  712                  jack_connect (jack_client_, details.output_port_names[ch].c_str(),
 
  713                                              jack_port_name (input_ports_[ch]));
 
  714                if (details.input_ports > ch)
 
  715                  jack_connect (jack_client_, jack_port_name (output_ports_[ch]),
 
  716                                              details.input_port_names[ch].c_str());
 
  724        flags_ |= Flags::OPENED;
 
  727        pcm_latency (&dummy, &dummy);   
 
  731        disconnect_jack (jack_client_);
 
  732        jack_client_ = 
nullptr;
 
  734    JDEBUG (
"%s: opening PCM: readable=%d writable=%d mix=%.1fHz block=%d: %s", devid_, readable(), writable(), mix_freq_, block_length_, ase_error_blurb (error));
 
  738  pcm_check_io (
long *timeoutp)
 override 
  767    if (atomic_xruns_ != printed_xruns_)
 
  769        printed_xruns_ = atomic_xruns_;
 
  770        Ase::printerr (
"JACK: %s: %d beast driver xruns\n", devid_, printed_xruns_);
 
  773    if (is_down_ && !printed_is_down_)
 
  775        printed_is_down_ = 
true;
 
  776        Ase::printerr (
"JACK: %s: connection to jack server lost\n", devid_);
 
  777        Ase::printerr (
"JACK: %s:  -> to continue, manually stop playback and restart\n", devid_);
 
  780    uint n_frames_avail = 
std::min (output_ringbuffer_.get_writable_frames(), input_ringbuffer_.get_readable_frames());
 
  783    if (n_frames_avail >= block_length_)
 
  787    uint diff_frames = block_length_ - n_frames_avail;
 
  788    *timeoutp = diff_frames * 1000 / mix_freq_;
 
  795  pcm_latency (
uint *rlatency, 
uint *wlatency)
 const override 
  799    jack_nframes_t jack_rlatency = 0;
 
  800    for (
auto port : input_ports_)
 
  802        jack_latency_range_t in_lrange;
 
  803        jack_port_get_latency_range (port, JackCaptureLatency, &in_lrange);
 
  805        jack_rlatency = 
std::max (jack_rlatency, in_lrange.max);
 
  808    jack_nframes_t jack_wlatency = 0;
 
  809    for (
auto port : output_ports_)
 
  811        jack_latency_range_t out_lrange;
 
  812        jack_port_get_latency_range (port, JackPlaybackLatency, &out_lrange);
 
  814        jack_wlatency = 
std::max (jack_wlatency, out_lrange.max);
 
  817    uint total_latency = buffer_frames_ + jack_rlatency + jack_wlatency;
 
  818    JDEBUG (
"%s: jack_rlatency=%.3f ms jack_wlatency=%.3f ms ringbuffer=%.3f ms total_latency=%.3f ms",
 
  820            jack_rlatency / 
double (mix_freq_) * 1000,
 
  821            jack_wlatency / 
double (mix_freq_) * 1000,
 
  822            buffer_frames_ / 
double (mix_freq_) * 1000,
 
  823            total_latency / 
double (mix_freq_) * 1000);
 
  828    *rlatency = jack_rlatency;
 
  829    *wlatency = jack_wlatency + buffer_frames_;
 
  832  pcm_read (
size_t n, 
float *values)
 override 
  837    device_read_counter_++;  
 
  839    float deinterleaved_frame_data[block_length_ * n_channels_];
 
  840    float *deinterleaved_frames[n_channels_];
 
  841    for (
uint ch = 0; ch < n_channels_; ch++)
 
  842      deinterleaved_frames[ch] = &deinterleaved_frame_data[ch * block_length_];
 
  846    uint frames_read = input_ringbuffer_.read (block_length_, deinterleaved_frames);
 
  849    for (
uint ch = 0; ch < n_channels_; ch++)
 
  851        const float *src = deinterleaved_frames[ch];
 
  852        float *dest = &values[ch];
 
  854        for (
uint i = 0; i < frames_read; i++)
 
  860    return block_length_ * n_channels_;
 
  863  pcm_write (
size_t n, 
const float *values)
 override 
  874    device_write_counter_++;
 
  875    if (device_read_counter_ < device_write_counter_)
 
  877        float junk_frames[block_length_ * n_channels_];
 
  878        pcm_read (n, junk_frames);
 
  879        assert_return (device_read_counter_ == device_write_counter_);
 
  883    float deinterleaved_frame_data[block_length_ * n_channels_];
 
  884    const float *deinterleaved_frames[n_channels_];
 
  885    for (
uint ch = 0; ch < n_channels_; ch++)
 
  887        float *channel_data = &deinterleaved_frame_data[ch * block_length_];
 
  888        for (
uint i = 0; i < block_length_; i++)
 
  889          channel_data[i] = values[ch + i * n_channels_];
 
  890        deinterleaved_frames[ch] = channel_data;
 
  895    uint frames_written = output_ringbuffer_.write (block_length_, deinterleaved_frames);
 
  900static const String jack_pcm_driverid = PcmDriver::register_driver (
"jack", JackPcmDriver::create, list_jack_drivers);
 
Base class for a PCM devices.
 
#define ASE_CLASS_NON_COPYABLE(ClassName)
Delete copy ctor and assignment operator.
 
#define assert_return(expr,...)
Return from the current function if expr is unmet and issue an assertion warning.
 
The Anklang C++ API namespace.
 
std::string string_format(const char *format, const Args &...args) __attribute__((__format__(__printf__
Format a string similar to sprintf(3) with support for std::string and std::ostringstream convertible...
 
uint64_t uint64
A 64-bit unsigned integer, use PRI*64 in format strings.
 
void floatfill(float *dst, float f, size_t n)
Fill n values of dst with f.
 
Error
Enum representing Error states.
 
std::string executable_name()
Retrieve the name part of executable_path().
 
uint32_t uint
Provide 'uint' as convenience type.
 
void fast_copy(size_t n, float *d, const float *s)
Copy a block of floats.
 
Driver information for PCM and MIDI handling.
 
PCM device configuration.