Git Product home page Git Product logo

captainjack's Introduction

	,---.         .              ,-_/
	|  -' ,-. ,-. |- ,-. . ,-.   '  | ,-. ,-. . ,
	|   . ,-| | | |  ,-| | | |      | ,-| |   |/
	`---' `-^ |-' `' `-^ ' ' '      | `-^ `-' |\
	          |                  /  |         ' `
	          '                  `--'
	          captain jack audio device
	         github.com/qix-/captainjack

	        copyright (c) 2016 josh junon
	        released under the MIT license

I've halted production on Captain Jack until JACK has improved. See #3.

Captain Jack

Captain Jack is a JACK-enabled audio device for OS/X.

Through the use of the new AudioServerPlugin API (since 10.5), Captain Jack provides a means of routing system audio into the JACK subsystem through either a system mix port or one or more per-application (namely, per-process) audio ports.

Installing

You must have an implementation of JACK installed on the system. You can (and should) do this by downloading and building the latest source from either JACK1 or JACK2, though it's worth mentioning JACK2 does not currently build on OS/X.

To build Captain Jack:

$ make

To install Captain Jack:

$ sudo make install

To start Captain Jack:

$ sudo make start

Developing

Debugging

Use Console.app (in /Applications/Utilities). Select system.log on the side and filter for CaptainJack.

All daemon log messages have the CaptainJack tag, and all device messages have the CaptainJack-Device tag.

Layout

Captain Jack is made up of two pieces: the device and the daemon.

Device

The Captain Jack Device is a CoreAudio HAL Plugin .driver bundle that uses the latest APIs in lieu of the deprecated AudioHardwarePlugin APIs.

The device is a user-space plugin that requires no Kext signing nor does it require disabling of SIP.

Since coreaudiod, the system service that manages audio and thus loads Captain Jack's device plugin, resides within the System bootstrap space, and since coreaudiod runs everything inside a sandbox, getting audio out of coreaudiod and into JACK requires some clever IPC.

XPC is Apple's version of IPC and is one of the two methods of IPC really available to Mach services. Its major (and deal-breaking) drawback is that it requires some sort of main dispatch loop, which isn't possible in an AudioServerPlugin bundle since everything inside of the device is just a callback and anything that blocks would effectively block not only coreaudiod but other launch daemons as well (I notice my RGB key board freeze up if Captain Jack blocks!).

Therefore, the network was the only other means of IPC (I heard that shared memory regions were allowed, but I never could figure out how to get them to work).

When a connection has been established to the daemon (a user-space launchd daemon; see below), all callbacks forward their data to an Xmit RPC call (see src/xmit.c) that in turn passes the data along the loopback socket and into the less-restrictive daemon process.

The reason why the daemon is even necessary and why the device cannot simply connect to JACK directly is that the sandbox prevents any IPC other than network IPC. Since we can't really guarantee that JACK is going to support network communication this becomes unreliable. As well, things like RO filesystem calls, the inability to trigger window apps or even look up PID process names were very restrictive, and the device quickly turned into a trampoline for audio events.

Daemon

The Captain Jack Daemon is a user-space launchd LaunchDaemon that relays Xmit-RPC'd audio data from the device to JACK. It also manages a light state for whatever might be necessary to track (e.g. client name => PID map, etc).

Xmit

The device and daemon communicate over a very opaque and light network layer dubbed Xmit (see src/xmit.c) that uses read buffer polling to achieve asynchronicity. Since it uses the TCP protocol, there is little chance of audio frames to be mixed up during transmission.

Using the network also gives us nearly free IPC with almost zero added latency (assuming the loopback interface is used, which it is in this case).

The only externalized Xmit calls are those that set up the callback functions. All transportation specifics are statically defined and managed inside of xmit.c.

License

Captain Jack is licensed under the MIT License. All JACK works are licensed under their respective licenses.

captainjack's People

Contributors

qix- avatar jdek avatar

Stargazers

 avatar  avatar Noah Laux avatar Owen Hael avatar

Watchers

James Cloos avatar  avatar  avatar

Forkers

fcgll520 bhll

captainjack's Issues

Development halted until JACK gets its shit together

Right now JACK is in shambles in terms of OS/X support.


The official build for JACK1 off homebrew fails with cryptic errors:

JACK compiled with POSIX SHM support.
loading driver ..
allocate_mach_serverport: can't check in mach port
2016-09-04 20:41:47.228 jackd[4396:17490] 20:41:47.227 WARNING:  140: This application, or a library it uses, is using the deprecated Carbon Component Manager for hosting Audio Units. Support for this will be removed in a future release. Also, this makes the host incompatible with version 3 audio units. Please transition to the API's in AudioComponent.h.
Error calling AudioUnitSetProperty - kAudioUnitProperty_StreamFormat kAudioUnitScope_Output
could not handle external client request
could not handle external client request
could not handle external client request

Further, the client sees a failed (NULL) pointer being returned but doesn't offer any insight within the status result.

The latest HEAD of JACK1 compiles and has similar results.


The official build for JACK2 doesn't install.

A user on a thread over at the JACK2 repositories seems to have built a newer version, but aside from it installing correctly, it doesn't actually work. Nothing connects, it almost seems to hang.

The JACK2 repository does not build at all for me, and from the looks of it requires several refactors of deprecated API usage to get it working.


So until either one of these projects works on OS/X Capitan, or a new implementation of JACK arises, this project is officially abandoned. Ping this thread when that happens and I'll finish Captain Jack.

I could definitely fix it but I'd have to maintain it as it seems the original developers have all but abandoned either project, and I definitely don't want to play customer support for JACK proper.

Sorry :/

Switch client/server scheme

Right now the device listens and the daemon connects, but I've realized this isn't as optimal as it could be.

The daemon runs in a main loop that processes both Captain Jack events as well as (soon) JACK events, whereas the device only operates based on callbacks. It makes sense to only have the device connect if it isn't already connected (or on error, i.e. the daemon was restarted) since it doesn't need real-time input from the daemon.

As well, the daemon can just ignore broken Captain Jack connections and try to accept() asynchronously, and can do so over and over if the coreaudio device dies. This will reduce the chances of the annoying binding problems and will make restarting the services much simpler.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.