Skip to content
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

Opt-in support for JACK backend on Windows #98

Open
wants to merge 14 commits into
base: master
Choose a base branch
from

Conversation

calvinkosmatka
Copy link
Contributor

  • Adds winjack feature to allow using JACK as the backend on Windows (non-breaking)
  • moves VirtualInput and VirtualOutput out of the os module and into their own virtual module (breaking)

jack-sys doesn't provide a link to libjack on Windows, so consumers will need to supply their own. I included linking to JACK2 at the standard installation path for the integration test and examples.

@Boddlnagg
Copy link
Owner

Thanks for the PR! I didn't know that Jack is available on Windows, too. How commonly is this used?
I added a few review comments for you to address.

@calvinkosmatka
Copy link
Contributor Author

How commonly is this used?

I suspect it's fairly uncommon, but it is at least supported by Ardour for example. As far as I know it's the only way to allow applications to create their own virtual MIDI ports on Windows, which is my use case.

I added a few review comments for you to address.

Your comments aren't showing up for me, stuck pending?

@@ -19,11 +19,12 @@ license = "MIT"
default = []
avoid_timestamping = []
jack = ["jack-sys", "libc"]
winjack = ["jack"]
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why did you create a new feature and didn't reuse the jack feature directly? On Windows it has no meaning so far.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did it this way to avoid surprises/breaks for any downstream crates that have the jack feature enabled, but expect/handle a non-jack backend on Windows. With only jack enabled, Windows will still use the winmm backend. I'm open to just reusing jack if this isn't a concern (I think it would clean up some of the cfg guards)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be even better if midir could pick between backends at runtime. Of course, that's a lot more work.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is already tracked in #4 (but yes, a lot of work).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given that a semver breaking release is already being prepared, should we go ahead just use the jack feature for windows?


[dependencies]
bitflags = "1.2"
memalloc = "0.1.0"
jack-sys = { version = "0.1.0", optional = true }
jack-sys = { version = "0.2.3", optional = true }
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this upgrade have any incompatible changes that may affect downstream crates?

Copy link
Contributor Author

@calvinkosmatka calvinkosmatka Jan 26, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The changes themselves shouldn't break anything, just formatting, replacing some libc types with primitive equivalents, add a few other jack fns, and Windows support (though it does require a 2018 edition-compatible compiler). I can loosen this to ~0.2.1

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So I assume from your comment that 0.2.1 does not require a 2018 edition compiler?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

0.2.3 is the first version of jack-sys that builds with pipewire-jack.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Apologies for the delay, haven't had a chance to work on this lately. 0.2.1 still requires 2018 edition (as does 0.2), but it buys a few extra versions of compatibility with, for instance CPAL I see 0.2 is now in the master branch for midir 0.8-pre, so bumping this to 0.2.3 for Pipewire and Windows shouldn't be an issue?

mod example {

use std::thread::sleep;
use std::time::Duration;
use std::error::Error;

use midir::{MidiInput, MidiOutput, Ignore};
use midir::os::unix::VirtualInput;
use midir::r#virtual::VirtualInput;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a bit problematic in two ways:

  1. You need to use the raw identifier syntax because virtual is a keyword ... so every user also needs to know about and use the raw identifier syntax as well. I don't like that, although I agree that os::unix is misleading when it's not Unix only (does Jack on Windows actually support virtual ports without any further setup?).
  2. Changing the module path here is an incompatible change. For migration, I think there should be at least a re-export of the types at the old path, if possible with deprecation warnings.

Maybe as an alternative, ext would be a better name, as that is the name often used by the standard library for OS/platform-dependent extensions.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like ext. I tried for a while to get deprecation warnings to work on the reexports, but this is apparently a longstanding issue (see rust-lang/rust#30827)

extern crate midir;

#[cfg(all(windows, feature = "winjack"))]
#[link(name = "C:/Program Files/JACK2/lib/libjack64")]
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can this test be run on CI? I.e., can you add "Jack on Windows" to the CI configuration (see

${{ if and(not(startsWith(parameters.name, 'Windows')), not(endsWith(parameters.name, 'WASM'))) }}:
stable-jack:
rustup_toolchain: stable-${{ parameters.target }}
features: "jack"
${{ if eq(variables['Build.SourceBranch'], 'refs/heads/master') }}:
beta-jack:
rustup_toolchain: beta-${{ parameters.target }}
features: "jack"
nightly-jack:
rustup_toolchain: nightly-${{ parameters.target }}
features: "jack"
)?
That would require installing the Jack dependency on the CI machine ...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I gave this a go in the latest commit

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see the following errors in the latest build of this PR on AzureDevOps (which might only be visible to me):
grafik

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can't quite tell what the L75 issue is, but L34 and L73 should be fixed by 7680d23

@Boddlnagg
Copy link
Owner

Your comments aren't showing up for me, stuck pending?

Sorry, you're right, I forgot to actually finalize the review.

@Be-ing
Copy link
Contributor

Be-ing commented Jan 28, 2022

While this may be useful for local development and use, it would not be practical to distribute applications using midir with this feature until dynamic loading is implemented upstream in jack-sys.

@Be-ing
Copy link
Contributor

Be-ing commented Jan 28, 2022

it would not be practical to distribute applications using midir with this feature until dynamic loading is implemented upstream in jack-sys.

I suppose that doesn't really matter without midir dynamically picking the backend at runtime (#4). Even if libjack is dynamically loaded, it's not practical to distribute a Windows build using midir with the JACK backend if there's no fallback when libjack isn't installed.

@Boddlnagg
Copy link
Owner

Just a note to myself: The PR should be merged as is (modulo the current outstanding comments), but eventually I want to do a semver-breaking change and

  • upgrade jack-sys to 0.2.3 or later (see also fix build with pipewire-jack #99)
  • remove winjack in favor of just jack (I think it would then still be possible to use platform specific Cargo dependencies to enable jack on Linux and macOS, but not on Windows, if that is what one desires)
  • remove the os::virtual module completely

@Be-ing
Copy link
Contributor

Be-ing commented Feb 8, 2022

Version 0.9 of the JACK bindings have been released together with version 0.3 of jack-sys. This brings major breaking changes for jack-sys because it now uses dlib instead of always linking libjack. Refer to my PR updating the documentation for details. This solves the problem of platform-specific ways to link libjack thereby obviating the need for a separate feature for Windows. So I suggest to close this PR without merging.

Cargo.toml Outdated

[dependencies]
bitflags = "1.2"
memalloc = "0.1.0"
jack-sys = { version = "0.1.0", optional = true }
jack-sys = { version = "~0.2.1", optional = true }
Copy link
Owner

@Boddlnagg Boddlnagg Feb 12, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why did you specify the dependency like this? I think when the major version is 0, the tilde makes no difference. Both ~0.2.1 and 0.2.1 would mean 0.2.x with x ≥ 1.
And I assume 0.2.0 would not be sufficient?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't know that! For JACK on Windows, support was only added in 0.2.1 but per the discussion above, should we make this 0.2.3 for Pipewire?

@Boddlnagg
Copy link
Owner

@Be-ing To me this means that we should at least make sure (once we upgrade to 0.3) that Windows supports building with jack, i.e. adding it to the CI. This PR could be reworked in that direction.
And @calvinkosmatka's concern is still valid that supporting the jack feature on Windows is a breaking change because currently it can be enabled without any effect on Windows.

Also, I assume that #102 would apply to Windows as well?

@Be-ing
Copy link
Contributor

Be-ing commented Feb 12, 2022

supporting the jack feature on Windows is a breaking change

Yes, so bump the minor version to indicate that.

Also, I assume that #102 would apply to Windows as well?

Yes, the OS doesn't matter for that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants