spell-music / csound-expression

Haskell Framework for Electronic Music
320 stars 31 forks source link

how to connect to a jack input port automatically (from dacBy)? #61

Closed jwaldmann closed 3 years ago

jwaldmann commented 3 years ago

When I use dacBy (setJack "ce" <> ...), ports ce:output1/2 are created, and connect to system:playback_1/2. That's fine, I hear the sound.

But for (remote) teaching, I need connections to another port as well (PulseAudio JACK Source:front-left/right) because that's being used by the video conference software (BBB, running in the browser, using WebRTC).

I can manually make that connection in qjackctl but that's inconvenient (have to do it each time I evaluate an expression from ghci).

I thought that something like this would help

dacBy (setJack "ce" <> setRates 48000 256 <> setBufs 2048 4096 ) $ do 
  { jackoAudioOutConnect "dac:ce:output1" "dac:PulseAudio JACK Source:front-left" 
  ;   (0.05 *) $ at fromMono $ at (mlp (400 * uosc 1) 0.7) white 
  }

but I am getting

csound command: Segmentation fault
anton-k commented 3 years ago

For me it produces the same result.

This doc says that we can control jack connection with output flag like this -odac2 -odac5 https://csound.com/docs/manual/RealTimeJack.html

But for me it segfaults either :(

So I think as a workaraound we can do it like this. dacBy is an IO function. And we can create function that calls system after dacBy that uses jack_connect to do the job right.

we can define something like this:

run :: RenderCsd a => a -> IO ()
run expr = do
  dacBy jackOptions expr
  system "jack_connect ports"
  system "jack_connect ports"
  where
      jackOptions = setRates 44100 128 <> setJack "ce" <> setDacBy "nil"

and then use it in our examples instead of dac. Or we can redefine it as dac.

This way you don't need to connect manually. We can do it with Haskell :)

anton-k commented 3 years ago

It's sad that csound primitive is not working. Maybe it's worth to also write about it on Csound mail-list. Usually they fix stuff like this.

anton-k commented 3 years ago

Also regarding jacko segfault.

Doc for JackoAudioOutConnect says

plugin: Requires jacko plugin

Probably csound has to be built is special way to activate this plugin.

jwaldmann commented 3 years ago

Hi Anton, thanks for looking into this. I will investigate further, but probably not this week (too busy). Perhaps my students find a way ...

jwaldmann commented 3 years ago

looks related: https://github.com/csound/csound/issues/1380

anton-k commented 3 years ago

I've added function setJackConnect . It should do the job. See docs for details:

setJackConnect :: [(String, String)] -> Options

To use update to new version of CE

anton-k commented 3 years ago

it just invokes jack_connect on the list of posrts. One thing to note that use tine delay for csound to catch up with setup. I hope it will be enough. But tell me if you experience any issues.

Also thing I've noticed. Jack connection with working instance can cause unpleasant pops and cracks. One way to avoid that is to delay signal a little bit. so that it produces silence during connection:

dacBy (setJackConnect conns) $ at (delaySig 0.25) $ fromMono $ osc 110
jwaldmann commented 3 years ago

Thanks!

For documentation, here is the complete command that works for me:

dacBy (setRates 48000 128 
       <> setJack "ce" 
       <> setDacBy "nil"   -- what does this do? 
       <> setJackConnect 
            [("ce:output1","'PulseAudio JACK Source:front-left'") -- extra quotes!
            ,("ce:output1","system:playback_1")  
            ]) $ mul 0.1 $ osc 200

Note the extra single-quotes, I needed this because of the spaces in the port name.

It's still showing a lot of trace/log messages from jack, though (#60)

anton-k commented 3 years ago
<> setDacBy "nil"

This line prohibits to auto-connect to default jack-ports.

You don need to do it. If you use setJackConnect it is done all the time. At least it should be so.

jwaldmann commented 2 years ago

another work-around: make a persistent connection from csound to Firefox (or whatever) with QJackctl Patchbay, cf. https://jackaudio.org/faq/persistent_connections.html

This is not fully reliable - it sometimes happens that a csound process lives on in the background. Then the next instance will have port names starting csoundNNN:, for some number NNN, and these do not match the rules for jack-connection persistence. In that case, killall -9 csound ...