supercollider / supercollider

An audio server, programming language, and IDE for sound synthesis and algorithmic composition.
http://supercollider.github.io
GNU General Public License v3.0
5.53k stars 754 forks source link

Make selection of AUDIOAPI a launch time option #1945

Open hzulla opened 8 years ago

hzulla commented 8 years ago

For my project, it would be beneficial if the scsynth binary supported both JACK and PortAudio.

However, the current code allows one and only one SC_AUDIO_API setting at compile time.

Making AUDIOAPI a runtime choice would require quite a bit of code restructuring.

I'm digging into the code to try that right now, but next to the jack/portaudio/coreaudio setting, there are some more obscure variations in there.

So, SuperCollider developers, what would be the preferred route to do this? Would you want me to try and restructure the code, even if it hurts, to add a command line option to scsynth? Or would you rather suggest that I just build a second scsynth binary with an alternative AUDIO cmake setting?

Related questions to this: Is SC_AUDIO_API_AUDIOUNITS actually in use? It looks like at least SC_AU.cpp hasn't been touched since a few years and it appears that one could remove it from the code. What is the status of the other two, SC_AUDIO_API_COREAUDIOIPHONE and SC_AUDIO_API_ANDROIDJNI?

danstowell commented 8 years ago

The "status" of the other two is: one is for iPhone, one is for Android. They're used for those. The AudioUnit thing, I've no idea if it's used, someone else would have to comment.

Making audio api a runtime choice would be hard to do. It would also mean that when compiling SC, you would need the development libraries for all of those frameworks. It wouldn't be a good idea to do it for absolutely all the APIs (for example, iPhone and Android, they go hand-in-hand with custom builds). If you were to do it for, say, portaudio and jack, if it's doable then I guess why not, but there would still need to be some compile-time switchery so that iPhone/Android/Linux would only make available the APIs that make sense for each platform.

(Note: in the near future I want to propose yet another new audio API in, the Bela Xenomai driver.)

What do I recommend you do? I've no idea, don't really know what you're trying to achieve. If all you want is to distribute scsynth with portaudio capability, then don't bother with any of this, just adapt the debian packaging to build a portaudio version as a separate package. But maybe that's not what you're trying to do.

sonoro1234 commented 8 years ago

build a second scsynth binary with an alternative AUDIO cmake setting is a good option because we already have it!!

crucialfelix commented 8 years ago

I think you mean at launch time rather than runtime. NO ? Connecting to a different audio driver while the music is playing is a bit much. Its not like just switching speakers.

I'd have to agree with Victor that the simplest solution is to compile two binaries and choose which one to launch. Otherwise scsynth would be a larger binary which 99% would wish to avoid.

Audio Units is something that people really want. Some day somebody will give it some love, so we shouldn't throw it out. I know of a few people still pumping out AU plugins from their sc code. They love it.

On Sat, Apr 2, 2016 at 12:02 PM Victor Bombi notifications@github.com wrote:

build a second scsynth binary with an alternative AUDIO cmake setting is a good option because we already have it!!

— You are receiving this because you are subscribed to this thread.

Reply to this email directly or view it on GitHub https://github.com/supercollider/supercollider/issues/1945#issuecomment-204685186

https://twitter.com/crucialfelix https://medium.com/@crucialfelix http://www.mattermind.com/

hzulla commented 8 years ago

Thanks for commenting.

Sorry, this is going to get long, please bear with me.

First of all, thanks again for SuperCollider! I'm a small-time contributor to @samaaron's Sonic Pi and as you know, SuperCollider is the synthesizer core used by Sonic Pi. Over the past months, I've also helped to get Sonic Pi packaged for Debian and for that, also packaged the sc3 plugins collection as a dependency.

So now I'm co-owner of all incoming Linux bug reports. And boy, does it suck. ;-)

The Sonic Pi users on desktop Linux mainly struggle with getting Sonic Pi to run, in the first place. Most of the time, it's JACKD related issues.

You see, JACKD is great for musicians and for Linux users who know how to tinker with their audio settings. But our Sonic Pi users are 9+ year old kids and primary school teachers. They don't need minimal latency, but a solution that just works out of the box. An easy way to switch sound cards would be a welcome bonus.

Raspbian on the Raspberry Pi is shipped with pure ALSA, while other desktop Linux distributions these days default to using PulseAudio.

My original attempt was to investigate getting JACKD and PulseAudio configured alongside without breaking each other. PulseAudio and JACKD are different solutions to a similar problem, but both camps seem to wildly disagree with each other and interoperability isn't much of a concern for either of them. It is somewhat possible to get JACKD and PulseAudio cooperate on the same system, but the distribution packages of Debian/Ubuntu/Raspbian aren't configured for this by default. The preferred pulseaudio-module-jack solution still isn't perfect, as the resulting setup breaks the system's main volume slider. As a user, you usually do want a working main volume slider, especially when you have kids messing with audio in strange ways.

So, the next idea was to get SuperCollider work without JACKD. There is an alternative PortAudio driver in SuperCollider, but there are two new problems down that road.

Problem one: The PortAudio driver isn't included in Linux builds. The Linux distribution packages of SuperCollider (e.g. for Debian) come with JACKD, only. If Sonic Pi wanted to use a jackless SuperCollider, I'd have to ask all the major distributors to build two binaries - one using JACKD, one using PortAudio. That's not an elegant solution. Looking at applications such as vlc or mplayer, they don't build vlc-alsa, vlc-pulse and vlc-jack, but just offer one binary with different audio drivers as launch-time options or include them as dynamic libraries or plugins.

Problem two: The PortAudio driver doesn't work reliably on my Linux box, there are buffer underruns and choppy audio. It may be possible to fix this, which would be the preferred solution, as I don't want to add complexity to SuperCollider by writing another AUDIOAPI option for, say, ALSA.

So in summary, I need a trouble-free way to launch SuperCollider, and by now I suspect that this requires an option to use something else than JACKD for audio. I don't care about latency, but things should just work without breaking existing ALSA (Raspberry Pi) or PulseAudio (practically everything else) setups. We really don't want to ship a custom SuperCollider Linux binary with Sonic Pi, so the solution needs to be easy to work with for distribution packagers and thus should be included with SuperCollider's default build rules for Linux. And the solution should not add too much additional complexity for you SuperCollider devs.

hzulla commented 8 years ago

I think you mean at launch time rather than runtime. NO?

You're right, that's what I meant.

Otherwise scsynth would be a larger binary which 99% would wish to avoid.

I don't think it's much of a burden. One could reduce the size of the binary by making the audio drivers dynamic libraries, so that there is only of the alternative audio drivers in memory at runtime (see above example about vlc or mplayer).

Asking distributors to release separate scsynth packages for each possible AUDIOAPI setting seems like the less desirable option to me.

danstowell commented 8 years ago

OK, I see. I don't think vlc or mplayer is a good comparison: SuperCollider has always been designed as a high-quality low-latency audio system, widely used for professional stuff, and that's quite different from the job that VLC and mplayer are doing. (For example, if we were to alter SC so that it falls back to portaudio if jack isn't available, then as you've found, people will get buffer underruns and choppy audio, and they'll blame SC.)

I'm not trying to block this idea you've floated; if there was a PR for jack-or-portaudio-at-runtime I'm sure we'd all be really interested! Just that (a) at least some compile-time switches (such as for iphone/android) must stay; (b) when discussing this idea "in theory" there are some pretty good reasons for suggesting it's not the route to pursue; and (c) there's a much easier way to get what you want.

It's a fair point that to provide an scsynth-portaudio package you'd want to do it for all major linux distros, but honestly if you do it once for debian/ubuntu you'll have solved 95% of the problem, and probably 99.9% of your problem if it's the less tech-savvy desktop linux users who you're trying to help.

hzulla commented 8 years ago

SuperCollider has always been designed as a high-quality low-latency audio system, widely used for professional stuff

Well, it has found a beautiful use outside of its original design and your new users are really really happy with it. It's just that low-latency isn't a concern there.

I'm not trying to change your project's objectives, just wanting to make an adjustment that suits our use of it. :-)

crucialfelix commented 8 years ago

We are more than happy to make sonicpi users and devs happy ! Just have to figure out the cleanest solution.

Asking distributors to release separate scsynth packages for each possible AUDIOAPI setting seems like the less desirable option to me.

Agreed. It's the fastest solution, but not the long term one.

We really don't want to ship a custom SuperCollider Linux binary with Sonic Pi,

Fair enough. I actually assumed you already were. I'm doing some Electron apps with scsynth included and I'm shipping it in the bundle.

samaaron commented 8 years ago

For the record, I personally care about latency and I see Sonic Pi's audience as being much broader than just school children - although I totally understand how @hzulla places an emphasis on young users :-)

Also, we do already ship a custom scsynth binary in our Windows distribution to get around the firewall warnings which was discussed here:

https://github.com/supercollider/supercollider/issues/1266

In the upcoming v2.10 will will also ship with a custom scsynth for OS X which supports FLAC.

Of course, the more we can work together - the better for everyone. I think that finding a way to get scsynth to boot out-of-the-box in a heterogenous linux context would be beneficial for everyone. I totally agree with @danstowell that focussing on Ubuntu is the way forward here.

hzulla commented 8 years ago

Fair enough. I actually assumed you already were.

Actually, we use distributor packages whenever possible. Some like Debian require us to (I have the scars to prove it). ;-)

samaaron commented 8 years ago

Again, for the record, I concur with @hzulla. We'd love to see scynth gain a flag to start listening on the loopback rather than publicly and we look forward to seeing OS X binaries with FLAC support. Then we can revert back to using non-custom binaries on all platforms :-)

bagong commented 8 years ago

seeing OS X binaries with FLAC support

3.7.1 is around the corner. But you'll have to make sure the plugins know where the libsndfile libs are.

samaaron commented 8 years ago

@bagong ah - aren't you planning on statically compiling libsndfile in like you currently do?

bagong commented 8 years ago

Hmm? No, libsndfile is dynamically linked, like in your PR. How do you do it in Sonic Pi atm? I am not sure what statically linking would imply as there are 3 libs (flac/org/vorbis) now...

samaaron commented 8 years ago

I currently dynamically link it, bundle the lib* files and then munge all the dynamic link paths within the binaries which is a bit of a pain. I was doing it that way as it's the only way I know how to (my compiling skills are weak). I think it was just a bit of wishful thinking on my part that you'd be able to whip up a single standalone portable scsynth binary.

bagong commented 8 years ago

Well, my compiling skills are probably weaker than yours. But sounds like you are not using bundle utilities? But maybe this is not the right thread to discuss this?

samaaron commented 8 years ago

I think you're right, we should continue this discussion elsewhere :-)

However, I'm not using bundle utilities - just a lot of otool -L and install_name_tool :-)

bagong commented 8 years ago

Ah, that sounds as if you could profit a lot from bundle utilities. Contact me on Gitter if you like...

llloret commented 8 years ago

Hi, guys, are there any new thoughts on this one?

scztt commented 8 years ago

I really don't think this would be particularly complex to build? At a glance, it would simply mean hooking up to one of several different SC_NewAudioDriver functions depending on a runtime switch, and probably moving a few bits of functionality that are currently protected by #ifdefs to driver-specific functions. The existing SC build system could be modified to simply build several drivers instead of a single one, and a simple map of driver names -> initialization functions could be done with #ifdefs so I don't think it would even require any plugin-style dynamic loading. This could be done without affecting standard scsynth builds, as long as they were built against a single driver.

vivid-synth commented 8 years ago

@hzulla one thing to consider is that there may be a tension here, especially with the relatively resource-constrained Raspberry Pi: you point out that

But our Sonic Pi users are 9+ year old kids and primary school teachers. They don't need minimal latency, but a solution that just works out of the box

but then you do describe having choppy audio and buffer underruns when you don't use jack.

I agree with everyone here that a boot-time flag to change audio API would be a welcome addition, but it's worth considering if, whether they know it or not, users do in fact want minimal latency.

hzulla commented 8 years ago

@vivid-synth The buffer underruns appear to be a bug in the ALSA part of Portaudio. The funny thing is that there are no such buffer underruns when you use PortAudio with PulseAudio's ALSA emulation.

Oh, those lovely Linux audio acronyms and terms.

Anyway:

Since Raspbian recently moved away from being pure ALSA and now installs PulseAudio by default, the choppy audio problem has gone away and SuperCollider with PortAudio would be a solution when wanting to run SC without JACK.

vivid-synth commented 8 years ago

@hzulla Ah, great - carry on then.

hzulla commented 8 years ago

The hands-down best solution would actually be to implement a PulseAudio driver in SuperCollider. (Sorry, haven't done that yet.) Until that exists, PortAudio is the second-best alternative.

mossheim commented 4 years ago

@samaaron @hzulla -- it's been a while :) sorry this was never implemented; are you still interested in this feature?