-
Notifications
You must be signed in to change notification settings - Fork 318
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
Add support for ASIO messages #519
base: master
Are you sure you want to change the base?
Conversation
Additional context: This PR is a recreation of an old merge request on PortAudio's previous Assembla-hosted repository. readers can find that Merge Request here... https://app.assembla.com/spaces/portaudio/git/merge_requests/3939463 |
I have a PR that overlaps somewhat with this, so we should probably coordinate that (#473). |
Merge from upstream RC
I still need to review this properly, but two obvious things:
|
I notice this was tagged for inclusion in the next release of PortAudio. I'm currently working on ASIO functionality in my company's application and expect I will have an opportunity to revisit this Pull Request in the coming weeks. |
If I understand correctly, this PR would prevent PortAudio apps from using JackRouter (routing audio through JACK) on Windows, is this correct? If so, such change would affect SuperCollider Windows users, if they use JACK. I understand that one can't make everyone happy, but I think this would be an unfortunate regression. To clarify, the issue only occurs with older versions of JACK (pre-2021); it does not occur with the current version. EDIT: maybe blocking JackRouter could be enabled/disabled at compile time with a CMake option? That way those building PortAudio themselves could make the appropriate decision as they see fit. |
This PR blocks interfacing with JACK through its ASIO adaptor, "JackRouter", in order to avoid a problem that historically rendered the JACK ASIO adaptor nonfunctional for 64-bit apps. PortAudio also supports interfacing directly with the JACK API on Windows (ie, natively rather than through ASIO/JackRouter) which will understandably be the better approach to making Windows applications with Jack support. If the bug in JackRouter has been fixed, and that fix has propagated widely, the guard could be removed -- perhaps with a CMake option as you suggest. But be advised that the JackRouter problem causes applications to crash when initializing PortAudio on any system with the faulty ASIO driver; this usually means an app without this guard will be unopenable on affected systems, regardless of whether the user intends to interface with JACK. The nature of the crash also makes inspection of the debug trace rather difficult. |
I'm aware of the bug, and that it prevents the application from starting. Is building PortAudio with the JACK backend on Windows actually operational? I don't think that was the case in the past. Also, would the application be then linked against the Jack library? IMO it's quite important to allow the same binary to run both on systems that do and don't have JACK installed. If PA's JACK backend works on Windows, AND if the JACK library would be dynamically loaded, then indeed it is a viable workaround. As I wrote, the fixed JackRouter has been around for over two years now. I don't have the data on how well it is propagated. Since SuperCollider uses PortAudio on Windows, this has come up in SuperCollider's issue tracker, so it is likely that there are users who use PortAudio + Jack (with fixed JackRouter) on Windows. |
Pardon my two year (minus one day) delay.
Note that the latter change will break compatibility with any existing applications that use my branch (the message callback will not be used because the flag is not set). I considered checking for this in |
Phil and I discussed the struct version check. Phil raised the point that the check will fail if a newer version of the struct is passed even if it does not use new features. Something to think about. Given that I don't think we have a clear and stable global policy on struct version management I think the way that the version check is being handled in this PR is fine to merge as-is even if it's not perfect. |
Please fix the trailing whitespace issues. Maybe consider installing an editor plugin to strip trailing whitespace on save.
|
Co-authored-by: Ross Bencina <[email protected]>
I noticed this. I was copying the behavior of the previous code (the current library will fail any version other than 1). At your discretion I'd be happy to modify the validation check to facilitate forward compatibility. |
I went ahead and implemented the forward-compatibility as it seems unlikely to cause problems compared to the alternative. Implementors may need a fallback to deal with the possibility of an older portaudio DLL that rejects non-1 versions though. 0308b1e |
The CI is still finding some trailing white space. |
At Ross' suggestion I've split off #885 which fixes a bug in stream info validation. 885 should be merged before this PR; otherwise it won't be possible to use ASIO messages without also specifying a channel mapping. |
#885 is merged now |
long ret = 0; | ||
|
||
(void) message; /* unused parameters */ | ||
(void) opt; | ||
|
||
PA_DEBUG( ("asioMessages : %d , %d \n", selector, value)); | ||
|
||
if (!theAsioStream) | ||
{ | ||
/* Some ASIO drivers will fire messages during OpenStream. We ignore them. */ |
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 seems like incomplete code (same in the sampleRateChanged
handler). Is there a rationale for dropping these messages?
To me, it seems that if we're going to pass through driver messages, we should pass through all of them. All it would take would be to stash the required callback data for use here even before the stream is fully created.
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.
It has been quite a while since I visited this code. My faint recollection is that some ASIO drivers were generating spurious ResetRequest messages while opening the stream, but I'd need to look into it.
This PR addresses PortAudio's bad habit of ignoring certain highly actionable messages from ASIO drivers by providing a callback mechanism to the application. Applications may receive the following events:
In particular, Reset Request is commonly used to notify the ASIO client when the stream should be reset in order to put configuration changes into effect or resume the interrupted flow of audio. Implementing automatic reset allows the user to interactively re-configure the ASIO stream by way of a driver-specific UI without superfluous manual steps in the client application.
The patch works by extending the ASIO configuration structure and, therefore, does not change PortAudio's ABI. I have been using this functionality in production for over four years in an application with an integrated crash forensics system and haven't identified any faults.