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.