JackOutputPlugin.cxx 16 KB
Newer Older
1
/*
Max Kellermann's avatar
Max Kellermann committed
2
 * Copyright 2003-2020 The Music Player Daemon Project
3
 * http://www.musicpd.org
4 5 6 7 8 9 10 11 12 13
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
14 15 16 17
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 19
 */

20
#include "config.h"
21
#include "JackOutputPlugin.hxx"
22
#include "../OutputAPI.hxx"
23
#include "thread/Mutex.hxx"
24
#include "util/ScopeExit.hxx"
25
#include "util/ConstBuffer.hxx"
26
#include "util/IterableSplitString.hxx"
27
#include "util/RuntimeError.hxx"
28
#include "util/Domain.hxx"
29
#include "Log.hxx"
30

31
#include <atomic>
32
#include <cassert>
33

34 35 36 37
#include <jack/jack.h>
#include <jack/types.h>
#include <jack/ringbuffer.h>

38
#include <unistd.h> /* for usleep() */
39 40
#include <stdlib.h>

41
static constexpr unsigned MAX_PORTS = 16;
42

43
static constexpr size_t jack_sample_size = sizeof(jack_default_audio_sample_t);
44

45
class JackOutput final : public AudioOutput {
46 47 48
	/**
	 * libjack options passed to jack_client_open().
	 */
49
	jack_options_t options = JackNullOption;
50

51
	const char *name;
52

53
	const char *const server_name;
54

55
	/* configuration */
56

57
	std::string source_ports[MAX_PORTS];
58 59
	unsigned num_source_ports;

60
	std::string destination_ports[MAX_PORTS];
61
	unsigned num_destination_ports;
62 63
	/* overrides num_destination_ports*/
	bool auto_destination_ports;
64

65
	size_t ringbuffer_size;
66

67
	/* the current audio format */
68
	AudioFormat audio_format;
69

70
	/* jack library stuff */
71
	jack_port_t *ports[MAX_PORTS];
72
	jack_client_t *client;
73
	jack_ringbuffer_t *ringbuffer[MAX_PORTS];
74

75 76 77 78
	/**
	 * While this flag is set, the "process" callback generates
	 * silence.
	 */
79
	std::atomic_bool pause;
80

81 82 83
	/**
	 * Protects #error.
	 */
84
	mutable Mutex mutex;
85 86 87 88 89 90

	/**
	 * The error reported to the "on_info_shutdown" callback.
	 */
	std::exception_ptr error;

91
public:
92
	explicit JackOutput(const ConfigBlock &block);
93

94
private:
95 96 97 98
	/**
	 * Connect the JACK client and performs some basic setup
	 * (e.g. register callbacks).
	 *
99
	 * Throws on error.
100 101
	 */
	void Connect();
102 103 104 105

	/**
	 * Disconnect the JACK client.
	 */
106
	void Disconnect() noexcept;
107

108
	void Shutdown(const char *reason) noexcept {
109
		const std::lock_guard<Mutex> lock(mutex);
110 111
		error = std::make_exception_ptr(FormatRuntimeError("JACK connection shutdown: %s",
								   reason));
112
	}
113

114 115 116 117 118 119 120
	static void OnShutdown(jack_status_t, const char *reason,
			       void *arg) noexcept {
		auto &j = *(JackOutput *)arg;
		j.Shutdown(reason);
	}


121
	/**
122
	 * Throws on error.
123 124
	 */
	void Start();
125
	void Stop() noexcept;
126 127 128 129 130 131

	/**
	 * Determine the number of frames guaranteed to be available
	 * on all channels.
	 */
	gcc_pure
132
	jack_nframes_t GetAvailable() const noexcept;
133 134

	void Process(jack_nframes_t nframes);
135 136 137 138 139
	static int Process(jack_nframes_t nframes, void *arg) noexcept {
		auto &j = *(JackOutput *)arg;
		j.Process(nframes);
		return 0;
	}
140

141 142 143
	/**
	 * @return the number of frames that were written
	 */
144
	size_t WriteSamples(const float *src, size_t n_frames);
145

146
public:
147 148 149 150 151 152 153 154 155 156 157
	/* virtual methods from class AudioOutput */

	void Enable() override;
	void Disable() noexcept override;

	void Open(AudioFormat &new_audio_format) override;

	void Close() noexcept override {
		Stop();
	}

158
	std::chrono::steady_clock::duration Delay() const noexcept override {
159
		return pause && !LockWasShutdown()
160 161
			? std::chrono::seconds(1)
			: std::chrono::steady_clock::duration::zero();
162 163
	}

164
	size_t Play(const void *chunk, size_t size) override;
165

166
	bool Pause() override;
167 168 169 170 171 172

private:
	bool LockWasShutdown() const noexcept {
		const std::lock_guard<Mutex> lock(mutex);
		return !!error;
	}
173
};
174

175
static constexpr Domain jack_output_domain("jack_output");
176

177
/**
178
 * Throws on error.
179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197
 */
static unsigned
parse_port_list(const char *source, std::string dest[])
{
	unsigned n = 0;
	for (auto i : IterableSplitString(source, ',')) {
		if (n >= MAX_PORTS)
			throw std::runtime_error("too many port names");

		dest[n++] = std::string(i.data, i.size);
	}

	if (n == 0)
		throw std::runtime_error("at least one port name expected");

	return n;
}

JackOutput::JackOutput(const ConfigBlock &block)
198
	:AudioOutput(FLAG_ENABLE_DISABLE|FLAG_PAUSE),
199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238
	 name(block.GetBlockValue("client_name", nullptr)),
	 server_name(block.GetBlockValue("server_name", nullptr))
{
	if (name != nullptr)
		options = jack_options_t(options | JackUseExactName);
	else
		/* if there's a no configured client name, we don't
		   care about the JackUseExactName option */
		name = "Music Player Daemon";

	if (server_name != nullptr)
		options = jack_options_t(options | JackServerName);

	if (!block.GetBlockValue("autostart", false))
		options = jack_options_t(options | JackNoStartServer);

	/* configure the source ports */

	const char *value = block.GetBlockValue("source_ports", "left,right");
	num_source_ports = parse_port_list(value, source_ports);

	/* configure the destination ports */

	value = block.GetBlockValue("destination_ports", nullptr);
	if (value == nullptr) {
		/* compatibility with MPD < 0.16 */
		value = block.GetBlockValue("ports", nullptr);
		if (value != nullptr)
			FormatWarning(jack_output_domain,
				      "deprecated option 'ports' in line %d",
				      block.line);
	}

	if (value != nullptr) {
		num_destination_ports =
			parse_port_list(value, destination_ports);
	} else {
		num_destination_ports = 0;
	}

239 240
	auto_destination_ports = block.GetBlockValue("auto_destination_ports", true);

241 242 243 244 245 246 247 248
	if (num_destination_ports > 0 &&
	    num_destination_ports != num_source_ports)
		FormatWarning(jack_output_domain,
			      "number of source ports (%u) mismatches the "
			      "number of destination ports (%u) in line %d",
			      num_source_ports, num_destination_ports,
			      block.line);

249
	ringbuffer_size = block.GetPositiveValue("ringbuffer_size", 32768U);
250 251
}

252
inline jack_nframes_t
253
JackOutput::GetAvailable() const noexcept
254
{
255
	size_t min = jack_ringbuffer_read_space(ringbuffer[0]);
256

257 258
	for (unsigned i = 1; i < audio_format.channels; ++i) {
		size_t current = jack_ringbuffer_read_space(ringbuffer[i]);
259 260 261 262
		if (current < min)
			min = current;
	}

263
	assert(min % jack_sample_size == 0);
264

265
	return min / jack_sample_size;
266 267
}

268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284
/**
 * Call jack_ringbuffer_read_advance() on all buffers in the list.
 */
static void
MultiReadAdvance(ConstBuffer<jack_ringbuffer_t *> buffers,
		 size_t size)
{
	for (auto *i : buffers)
		jack_ringbuffer_read_advance(i, size);
}

/**
 * Write a specific amount of "silence" to the given port.
 */
static void
WriteSilence(jack_port_t &port, jack_nframes_t nframes)
{
Max Kellermann's avatar
Max Kellermann committed
285
	auto *out =
286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314
		(jack_default_audio_sample_t *)
		jack_port_get_buffer(&port, nframes);
	if (out == nullptr)
		/* workaround for libjack1 bug: if the server
		   connection fails, the process callback is invoked
		   anyway, but unable to get a buffer */
			return;

	std::fill_n(out, nframes, 0.0);
}

/**
 * Write a specific amount of "silence" to all ports in the list.
 */
static void
MultiWriteSilence(ConstBuffer<jack_port_t *> ports, jack_nframes_t nframes)
{
	for (auto *i : ports)
		WriteSilence(*i, nframes);
}

/**
 * Copy data from the buffer to the port.  If the buffer underruns,
 * fill with silence.
 */
static void
Copy(jack_port_t &dest, jack_nframes_t nframes,
     jack_ringbuffer_t &src, jack_nframes_t available)
{
Max Kellermann's avatar
Max Kellermann committed
315
	auto *out =
316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332
		(jack_default_audio_sample_t *)
		jack_port_get_buffer(&dest, nframes);
	if (out == nullptr)
		/* workaround for libjack1 bug: if the server
		   connection fails, the process callback is
		   invoked anyway, but unable to get a
		   buffer */
		return;

	/* copy from buffer to port */
	jack_ringbuffer_read(&src, (char *)out,
			     available * jack_sample_size);

	/* ringbuffer underrun, fill with silence */
	std::fill(out + available, out + nframes, 0.0);
}

333 334
inline void
JackOutput::Process(jack_nframes_t nframes)
335
{
Max Kellermann's avatar
Max Kellermann committed
336
	if (nframes <= 0)
337
		return;
338

339
	jack_nframes_t available = GetAvailable();
340

341 342
	const unsigned n_channels = audio_format.channels;

343
	if (pause) {
344 345
		/* empty the ring buffers */

346 347
		MultiReadAdvance({ringbuffer, n_channels},
				 available * jack_sample_size);
348

349 350
		/* generate silence while MPD is paused */

351
		MultiWriteSilence({ports, n_channels}, nframes);
352

353
		return;
354 355
	}

356 357
	if (available > nframes)
		available = nframes;
358

359 360
	for (unsigned i = 0; i < n_channels; ++i)
		Copy(*ports[i], nframes, *ringbuffer[i], available);
361

362 363
	/* generate silence for the unused source ports */

364 365
	MultiWriteSilence({ports + n_channels, num_source_ports - n_channels},
			  nframes);
366 367
}

368 369
static void
mpd_jack_error(const char *msg)
370
{
371
	LogError(jack_output_domain, msg);
372 373
}

374
#ifdef HAVE_JACK_SET_INFO_FUNCTION
375 376 377
static void
mpd_jack_info(const char *msg)
{
378
	LogDefault(jack_output_domain, msg);
379
}
380
#endif
381

382
void
383
JackOutput::Disconnect() noexcept
384
{
385
	assert(client != nullptr);
386

387 388 389
	jack_deactivate(client);
	jack_client_close(client);
	client = nullptr;
390 391
}

392 393
void
JackOutput::Connect()
394
{
395
	error = {};
396

397
	jack_status_t status;
398
	client = jack_client_open(name, options, &status, server_name);
399 400 401
	if (client == nullptr)
		throw FormatRuntimeError("Failed to connect to JACK server, status=%d",
					 status);
402

403 404
	jack_set_process_callback(client, Process, this);
	jack_on_info_shutdown(client, OnShutdown, this);
405

406
	for (unsigned i = 0; i < num_source_ports; ++i) {
407
		unsigned long portflags = JackPortIsOutput | JackPortIsTerminal;
408 409 410
		ports[i] = jack_port_register(client,
					      source_ports[i].c_str(),
					      JACK_DEFAULT_AUDIO_TYPE,
411
					      portflags, 0);
412 413
		if (ports[i] == nullptr) {
			Disconnect();
414 415
			throw FormatRuntimeError("Cannot register output port \"%s\"",
						 source_ports[i].c_str());
416 417 418 419 420
		}
	}
}

static bool
421
mpd_jack_test_default_device()
422 423 424 425
{
	return true;
}

426 427
inline void
JackOutput::Enable()
428 429 430 431
{
	for (unsigned i = 0; i < num_source_ports; ++i)
		ringbuffer[i] = nullptr;

432
	Connect();
433 434 435
}

inline void
436
JackOutput::Disable() noexcept
437 438 439 440 441 442 443 444 445 446 447 448
{
	if (client != nullptr)
		Disconnect();

	for (unsigned i = 0; i < num_source_ports; ++i) {
		if (ringbuffer[i] != nullptr) {
			jack_ringbuffer_free(ringbuffer[i]);
			ringbuffer[i] = nullptr;
		}
	}
}

449
static AudioOutput *
450
mpd_jack_init(EventLoop &, const ConfigBlock &block)
451
{
452
	jack_set_error_function(mpd_jack_error);
453 454

#ifdef HAVE_JACK_SET_INFO_FUNCTION
455
	jack_set_info_function(mpd_jack_info);
456
#endif
457

458
	return new JackOutput(block);
459 460
}

461 462 463
/**
 * Stops the playback on the JACK connection.
 */
464
void
465
JackOutput::Stop() noexcept
466
{
467
	if (client == nullptr)
468
		return;
469

470
	if (LockWasShutdown())
471
		/* the connection has failed; close it */
472
		Disconnect();
473 474
	else
		/* the connection is alive: just stop playback */
475
		jack_deactivate(client);
476
}
477

478 479
inline void
JackOutput::Start()
480
{
481 482
	assert(client != nullptr);
	assert(audio_format.channels <= num_source_ports);
483

484 485 486 487
	/* allocate the ring buffers on the first open(); these
	   persist until MPD exits.  It's too unsafe to delete them
	   because we can never know when mpd_jack_process() gets
	   called */
488 489 490 491
	for (unsigned i = 0; i < num_source_ports; ++i) {
		if (ringbuffer[i] == nullptr)
			ringbuffer[i] =
				jack_ringbuffer_create(ringbuffer_size);
492

493 494
		/* clear the ring buffer to be sure that data from
		   previous playbacks are gone */
495
		jack_ringbuffer_reset(ringbuffer[i]);
496 497
	}

498 499
	if ( jack_activate(client) ) {
		Stop();
500
		throw std::runtime_error("cannot activate client");
501 502
	}

503 504 505
	const char *dports[MAX_PORTS], **jports;
	unsigned num_dports;
	if (num_destination_ports == 0) {
506 507 508 509
		/* if user requests no auto connect, we are done */
		if (!auto_destination_ports) {
			return;
		}
510 511
		/* no output ports were configured - ask libjack for
		   defaults */
512
		jports = jack_get_ports(client, nullptr, nullptr,
513
					JackPortIsPhysical | JackPortIsInput);
514
		if (jports == nullptr) {
515
			Stop();
516
			throw std::runtime_error("no ports found");
517 518
		}

519
		assert(*jports != nullptr);
520

521 522 523
		for (num_dports = 0; num_dports < MAX_PORTS &&
			     jports[num_dports] != nullptr;
		     ++num_dports) {
524 525
			FormatDebug(jack_output_domain,
				    "destination_port[%u] = '%s'\n",
526 527 528
				    num_dports,
				    jports[num_dports]);
			dports[num_dports] = jports[num_dports];
529
		}
530 531 532
	} else {
		/* use the configured output ports */

533 534 535
		num_dports = num_destination_ports;
		for (unsigned i = 0; i < num_dports; ++i)
			dports[i] = destination_ports[i].c_str();
536

537
		jports = nullptr;
538 539
	}

540 541 542 543
	AtScopeExit(jports) {
		if (jports != nullptr)
			jack_free(jports);
	};
544

545
	assert(num_dports > 0);
546

547
	const char *duplicate_port = nullptr;
548
	if (audio_format.channels >= 2 && num_dports == 1) {
549 550
		/* mix stereo signal on one speaker */

551 552
		std::fill(dports + num_dports, dports + audio_format.channels,
			  dports[0]);
553
	} else if (num_dports > audio_format.channels) {
554
		if (audio_format.channels == 1 && num_dports >= 2) {
555 556
			/* mono input file: connect the one source
			   channel to the both destination channels */
557 558
			duplicate_port = dports[1];
			num_dports = 1;
559 560
		} else
			/* connect only as many ports as we need */
561
			num_dports = audio_format.channels;
562 563
	}

564
	assert(num_dports <= num_source_ports);
565

566 567 568
	for (unsigned i = 0; i < num_dports; ++i) {
		int ret = jack_connect(client, jack_port_name(ports[i]),
				       dports[i]);
569
		if (ret != 0) {
570
			Stop();
571 572
			throw FormatRuntimeError("Not a valid JACK port: %s",
						 dports[i]);
573
		}
574 575
	}

576
	if (duplicate_port != nullptr) {
577 578 579 580
		/* mono input file: connect the one source channel to
		   the both destination channels */
		int ret;

581
		ret = jack_connect(client, jack_port_name(ports[0]),
582
				   duplicate_port);
583
		if (ret != 0) {
584
			Stop();
585 586
			throw FormatRuntimeError("Not a valid JACK port: %s",
						 duplicate_port);
587 588
		}
	}
589 590
}

591 592
inline void
JackOutput::Open(AudioFormat &new_audio_format)
593
{
594
	pause = false;
595

596
	if (client != nullptr && LockWasShutdown())
597
		Disconnect();
598

599 600
	if (client == nullptr)
		Connect();
601

602 603 604 605 606 607 608 609 610 611 612
	new_audio_format.sample_rate = jack_get_sample_rate(client);

	if (num_source_ports == 1)
		new_audio_format.channels = 1;
	else if (new_audio_format.channels > num_source_ports)
		new_audio_format.channels = 2;

	/* JACK uses 32 bit float in the range [-1 .. 1] - just like
	   MPD's SampleFormat::FLOAT*/
	static_assert(jack_sample_size == sizeof(float), "Expected float32");
	new_audio_format.format = SampleFormat::FLOAT;
613
	audio_format = new_audio_format;
614

615
	Start();
616
}
617

618
inline size_t
619
JackOutput::WriteSamples(const float *src, size_t n_frames)
620
{
621 622
	assert(n_frames > 0);

623
	const unsigned n_channels = audio_format.channels;
624

625
	float *dest[MAX_CHANNELS];
626
	size_t space = SIZE_MAX;
627 628 629 630 631 632 633 634
	for (unsigned i = 0; i < n_channels; ++i) {
		jack_ringbuffer_data_t d[2];
		jack_ringbuffer_get_write_vector(ringbuffer[i], d);

		/* choose the first non-empty writable area */
		const jack_ringbuffer_data_t &e = d[d[0].len == 0];

		if (e.len < space)
635
			/* send data symmetrically */
Max Kellermann's avatar
Max Kellermann committed
636
			space = e.len;
637 638

		dest[i] = (float *)e.buf;
639 640 641 642 643 644 645
	}

	space /= jack_sample_size;
	if (space == 0)
		return 0;

	const size_t result = n_frames = std::min(space, n_frames);
646

647
	while (n_frames-- > 0)
648 649 650 651 652 653 654
		for (unsigned i = 0; i < n_channels; ++i)
			*dest[i]++ = *src++;

	const size_t per_channel_advance = result * jack_sample_size;
	for (unsigned i = 0; i < n_channels; ++i)
		jack_ringbuffer_write_advance(ringbuffer[i],
					      per_channel_advance);
655 656

	return result;
657 658
}

659
inline size_t
660
JackOutput::Play(const void *chunk, size_t size)
661
{
662
	pause = false;
663

664
	const size_t frame_size = audio_format.GetFrameSize();
665
	assert(size % frame_size == 0);
666
	size /= frame_size;
667

668
	while (true) {
669 670 671 672 673
		{
			const std::lock_guard<Mutex> lock(mutex);
			if (error)
				std::rethrow_exception(error);
		}
674

675 676 677 678
		size_t frames_written =
			WriteSamples((const float *)chunk, size);
		if (frames_written > 0)
			return frames_written * frame_size;
679

680 681
		/* XXX do something more intelligent to
		   synchronize */
682
		usleep(1000);
683
	}
684 685
}

686
inline bool
687
JackOutput::Pause()
688
{
689 690 691 692 693
	{
		const std::lock_guard<Mutex> lock(mutex);
		if (error)
			std::rethrow_exception(error);
	}
694

695
	pause = true;
696 697 698 699

	return true;
}

700
const struct AudioOutputPlugin jack_output_plugin = {
701 702 703 704
	"jack",
	mpd_jack_test_default_device,
	mpd_jack_init,
	nullptr,
705
};