New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Jack driver new api #128
Jack driver new api #128
Conversation
Signed-off-by: Stefan Westerfeld <stefan@space.twc.de>
Signed-off-by: Stefan Westerfeld <stefan@space.twc.de>
Signed-off-by: Stefan Westerfeld <stefan@space.twc.de>
Signed-off-by: Stefan Westerfeld <stefan@space.twc.de>
For instance for synchronizing the play position pointer ui with the audio buffering, you want to know how much write latency you have, but don't care about the amount of read latency. Signed-off-by: Stefan Westerfeld <stefan@space.twc.de>
Signed-off-by: Stefan Westerfeld <stefan@space.twc.de>
Great work Stefan, thanks for the updates.
I've pointed out a few places that still need work.
bse/driver-jack.cc
Outdated
Block::copy (n_values, ovalues, ivalues); | ||
} | ||
|
||
#if 0 // <- avoid unused warning |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use BSE_USED or BSE_UNUSED to silence the compiler here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
bse/driver-jack.cc
Outdated
else | ||
{ | ||
// should we try to generate and show an error message if connecting jack failed? | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, if there's no jack, there are no devices to list. Simple. Stay silent.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, removed the else branch.
Driver::Entry entry; | ||
entry.devid = device_name; | ||
entry.priority = Driver::JACK; | ||
entries.push_back (entry); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Two Driver::Entry structures must never have the same priority. That's why we have predefined priority constants for drivers, cards, devices, subdevices. Also, we need the other Entry fields to be filled to allow GUI selection. For now, it doesn't matter too much how to match name/blurb/status fields to extra info, each is just another line in my current UI prototype, but we need something to display devices to the user that make them humanly identifyable.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are never two Driver::Entry structures here. There is a loop, so you might expect it, but basically the code picks the only device which it considers to be the "default" device from the devices map. It used generate a list of devices, but I think thats more harmful than it helps, but I left the devices query and generate list code there, in case we want to do it differently.
Jack is not very descriptive. Typically we only get the client name "system" and the port names "playback_1", "playback_2",... and we know that it is a hardware device. So ok, I'm trying to give all that information to the user in my new version, but still, we for instance do not get a soundcard name or anything useful. There is a Jack Metadata API which could be used to attach descriptions to clients, but at least on my system, this returns nothing. So really what we have is "system", "is hardware device", "2in 2out", nothing really useful for the user.
|
||
/* macro for jack dropout tests - see below */ | ||
#define TEST_DROPOUT() if (unlink ("/tmp/drop") == 0) usleep (1.5 * 1000000. * buffer_frames_ / mix_freq_); /* sleep 1.5 * buffer size */ | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know this is disabled, atm, but please still make this /tmp/bse-dropout (or similar) so we're not stamping over namespaces if this is activated on purpose or by accident.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, done.
bse/driver-jack.cc
Outdated
vector<vector<T> > channel_buffer_; | ||
std::atomic<int> atomic_read_frame_pos_; | ||
std::atomic<int> atomic_write_frame_pos_; | ||
uint channel_buffer_size_; // = n_frames + 1; the extra frame allows us to |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is C++17, always and unconditionally initialize all struct members that don't have a ctor. If in doubt, just add =0, =false, =EnumType(0).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Of course. Fixed. Seems the jack driver predates C++11.
bse/driver-jack.cc
Outdated
static void | ||
static_shutdown_callback (void *jack_handle) | ||
{ | ||
static_cast<JackPcmDriver *> (jack_handle)->shutdown_callback(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use a lambda instead of static_*(), see below.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
bse/driver-jack.cc
Outdated
{ | ||
jack_set_process_callback (jack_client_, static_process_callback, this); | ||
jack_set_latency_callback (jack_client_, static_latency_callback, this); | ||
jack_on_shutdown (jack_client_, static_shutdown_callback, this); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note that lambdas that don't take context arguments boil down to normal functions that can be used as function pointer. For example, here is how it looks when you replace the static_* wrappers with lambda:
jack_on_shutdown (jack_client_, [] (void *p) {
static_cast<JackPcmDriver*> (p)->shutdown_callback();
}, this);
This could also be a one liner if you have a wider terminal.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed. Interesting, didn't know that this would work.
} | ||
~JackPcmDriver() | ||
{ | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The dtor should release all resources, e.g. call close(), either unconditionally, or with if (jack_client_)
. It may also be executed without open() being called previously, or after a failing open() without close().
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right. Fixed.
bse/driver-jack.cc
Outdated
disconnect_jack (jack_client_); | ||
jack_client_ = nullptr; | ||
} | ||
JDEBUG ("JACK: opening PCM \"%s\" readupble=%d writable=%d: %s", devid_.c_str(), readable(), writable(), bse_error_blurb (error)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please make this "JACK: %s: ...", devid_, ...
And fix "readable" ;-)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed.
Ok, last commit should have all the fixes you requested. |
Signed-off-by: Stefan Westerfeld <stefan@space.twc.de>
f0c4879
to
a960497
Compare
Ok, here is a port of the Jack driver (#31) to the new driver API. I tested playback and also stereo-through. This doesn't yet have midi support.