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

Getting Vivid to work with Tidal and SuperDirt #3

Open
jarmitage opened this issue Sep 22, 2017 · 36 comments
Open

Getting Vivid to work with Tidal and SuperDirt #3

jarmitage opened this issue Sep 22, 2017 · 36 comments

Comments

@jarmitage
Copy link

I tried to get Vivid and Tidal + SuperDirt working together based on this post:

http://lurk.org/groups/haskell-art/messages/topic/46bqOK1iOsiMy0fgOWMZa4

import Vivid

let (freq,_) = pI "freq" (Just 440)

defineSD $ sdNamed "foooo" () $ do
   s <- sinOsc (freq_ 440)
   out 0 [s, s]

d1 $ sound "foooo" # freq "400"

But it's not recognised by SuperDirt:

no synth or sample named 'foooo' could be found.
instrument not found: nil
[ "#bundle", 15955788339759360291, 
  [ 12, 1003, 1 ],
  [ 12, 1002, 1 ],
  [ "/g_new", 1103, 1, 2 ],
  [ "/s_new", "dirt_gate2", -1, 1, 1103, "in", 18, "out", 20, "amp", 0.4, "sample", 0, "sustain", 0.999, "fadeInTime", 0, "fadeTime", 0.001 ]
]

Most SuperDirt synths have this kind of format:

(
SynthDef(\foo, { |out, freq = 440|
	blah blah blah
	OffsetOut.ar(out, DirtPan.ar(sound, ~dirt.numChannels, pan, env))
}).add
);

So maybe it's the difference in output destination that's causing the issue?

Would love to get this to work! Thanks for making Vivid.

@telephon
Copy link

telephon commented Sep 22, 2017

There are two issues:

  1. you need to register the SynthDef name in supercollider. This you can do by writing:

~dirt.addSynth(\foooo)

  1. you need to keep with the channel mapping conventions to make it work properly. The minimum is that the out parameter needs to be left open. In vivid that would probably be:
defineSD $ sdNamed "foooo" () $ do
   s <- sinOsc (freq_ 440)
   o <- out_ 0
   out o [s, s]

The panning is another thing, but let's see if that works for you.

@jarmitage
Copy link
Author

For this:

defineSD $ sdNamed "foooo" () $ do
   s <- sinOsc (freq_ 440)
   o <- out_ 0
   out o [s, s]

I get out_ not in scope error.

If I do

defineSD $ sdNamed "foooo" () $ do
   s <- sinOsc (freq_ 440)
   out 0 [s, s]

And then ~dirt.addSynth(\foooo), I get ERROR: Message 'addSynth' not understood

@telephon
Copy link

telephon commented Sep 22, 2017

ok, I don't know how vivid works: all you need is a synth that has a control name called out.

If addSynth is not understood, then could you please also write who didn't understand it? The receiver is what? nil or SuperDirt?

@vivid-synth
Copy link
Owner

vivid-synth commented Oct 12, 2017

@telephon can you point to where addSynth is defined? I can't find it in the source for SuperDirt or supercollider.

@jarmitage to solve the first half of the problem (making "out" be an argument instead of a hardcoded 0), you'd say:

defineSD $ sdNamed "foooo" (0 ::I "out") $ do
   s <- sinOsc (freq_ 440)
   out (V::V "out") [s, s]

@telephon
Copy link

@vivid-synth
Copy link
Owner

@telephon I'm very close to getting this working but still hitting an issue.

My boot.scd file:

Server.supernova;
s.options.numBuffers = 1024 * 16;

s.waitForBoot{
Routine{
include("Vowel");
include("SuperDirt");
2.wait;

~dirt = SuperDirt.start;

5.wait;
postln(~dirt.soundLibrary);

// This seems to work!:
~dirt.soundLibrary.addSynth(\foo4);

}.play
}

(I then boot with sclang boot.scd)

I then open test.tidal in emacs and evaluate each line:

d1 $ sound "~ bd"

:set -XDataKinds
import Vivid

-- This is just on one line so we can easily eval it:
let s' = sdNamed "foo4" (0::I "out") $ do { s <- sinOsc (freq_ 440) ~* percGen none ~* 0.1 ; out (V::V "out") [s,s] } :: SynthDef '["out"]

defineSD s'

-- Neither of these lines work:
d2 $ s "foo4"
d2 $ sound "foo4"

The SynthDef is defined properly: I can open ghci and call synthNamed "foo4" () and hear a sound.

The complete error SuperDirt gives is:

ERROR: Message 'flop' not understood.
RECEIVER:
   nil
ARGS:

PROTECTED CALL STACK:
        Meta_MethodError:new    0x114e2c0
                arg this = DoesNotUnderstandError
                arg what = nil
                arg receiver = nil
        Meta_DoesNotUnderstandError:new 0x1150280
                arg this = DoesNotUnderstandError
                arg receiver = nil
                arg selector = flop
                arg args = [  ]
        Object:doesNotUnderstand        0xdd3cc0
                arg this = nil
                arg selector = flop
                arg args = nil
        DirtEvent:sendSynth     0x110b940
                arg this = a DirtEvent
                arg instrument = foo4
                arg args = nil
                var group = 1037
        DirtModule:value        0x1e5bac0
                arg this = DirtModule('sound')
                arg orbit = a DirtEvent
        ArrayedCollection:do    0x1c15f00
                arg this = [ DirtModule('sound'), DirtModule('vowel'), DirtModule('shape'), DirtModule('hpf'), DirtModule('bpf'), DirtModule('crush'), DirtModule('coarse'), DirtModule('lpf'), DirtModule('envelope'), DirtModule('tremolo'), DirtModule('phaser') ]
                arg function = a Function
                var i = 0
        a FunctionDef   0x110d400
                sourceCode = "<an open Function>"
        a FunctionDef   0x1d737c0
                sourceCode = "<an open Function>"
        Function:prTry  0x123e400
                arg this = a Function
                var result = nil
                var thread = a Thread
                var next = a Function
                var wasInProtectedFunc = true
        Function:try    0x123dec0
                arg this = a Function
                arg handler = a Function
                var result = nil
        Server:makeBundle       0x1d73400
                arg this = localhost
                arg time = 0.29827090190248
                arg func = a Function
                arg bundle = nil
        DirtEvent:playSynths    0x110cec0
                arg this = a DirtEvent
                var cutGroup = nil
        a FunctionDef   0x1cb2300
                sourceCode = "<an open Function>"
        Function:prTry  0x123e400
                arg this = a Function
                var result = nil
                var thread = a Thread
                var next = nil
                var wasInProtectedFunc = false

CALL STACK:
        DoesNotUnderstandError:reportError   0x2a58b28
                arg this = <instance of DoesNotUnderstandError>
        Nil:handleError   0xf3de18
                arg this = nil
                arg error = <instance of DoesNotUnderstandError>
        Thread:handleError   0x25c9cf8
                arg this = <instance of Thread>
                arg error = <instance of DoesNotUnderstandError>
        Object:throw   0x2209c88
                arg this = <instance of DoesNotUnderstandError>
        Function:protect   0x2a4bc38
                arg this = <instance of Function>
                arg handler = <instance of Function>
                var result = <instance of DoesNotUnderstandError>
        Environment:use   0x32531f8
                arg this = <instance of Event>
                arg function = <instance of Function>
                var result = nil
                var saveEnvir = <instance of Environment>
        DirtEvent:play   0x2a4c5d8
                arg this = <instance of DirtEvent>
        OSCFuncBothMessageMatcher:value   0x3254208
                arg this = <instance of OSCFuncBothMessageMatcher>
                arg msg = [*9]
                arg time = 26.947354181902
                arg testAddr = <instance of NetAddr>
                arg testRecvPort = 57120
        OSCMessageDispatcher:value   0x3251d98
                arg this = <instance of OSCMessageDispatcher>
                arg msg = [*9]
                arg time = 26.947354181902
                arg addr = <instance of NetAddr>
                arg recvPort = 57120
        Main:recvOSCmessage   0x3250128
                arg this = <instance of Main>
                arg time = 26.947354181902
                arg replyAddr = <instance of NetAddr>
                arg recvPort = 57120
                arg msg = [*9]
^^ The preceding error dump is for ERROR: Message 'flop' not understood.
RECEIVER: nil

@vivid-synth
Copy link
Owner

It at least appears that SuperDirt depends on some sclang-based registry of SynthDefs.

If I add this to the end of the boot.scd file:

SynthDef(\foo4, {|out=0|
   Out.ar(out, DC.ar(0))
}).add;

(I.e. I add a totally empty SynthDef, so that sclang knows there's something defined with that name)

...and then I run all the stuff above, things work as expected (I'm able to re-define the SynthDef in Haskell to my heart's content).

So @jarmitage here's your answer for now, although I'd love to know (cc @telephon @yaxu ) if there's a way to do this more cleanly.

@vivid-synth
Copy link
Owner

PS: by "at the end of the boot.scd file" I mean after everything except the final:

}.play
}

@telephon
Copy link

Yes, we currently assume that your SynthDef is registered in the SynthDescLibrary, so that we know which arguments it takes.

What you can do is just modify your default sound module. You can even do this on the fly and play around with it.

Please note that you may need the 1.0-dev-branch for it. You should be able to install it via the GUI or directly via git checkout 1.0-dev (in your SuperDirt quark folder).

(
var argNames = [\out];
~dirt.addModule('sound',
	{ |dirtEvent|
		if(~diversion.value.isNil) {
			if(~buffer.notNil) {
				// argumets could be omitted using getMsgFunc, but for making it easier to understand, we write them out
				dirtEvent.sendSynth(~instrument,  [
					bufnum: ~buffer,
					sustain: ~sustain,
					speed: ~speed,
					endSpeed: ~endSpeed,
					begin: ~begin,
					end: ~end,
					loop: ~loop,
					pan: ~pan,
					out: ~out
				])
			} {
				if(~instrument.isNil) {
					"instrument not found: %".format(~sound).postln
				} {
					// here, we just derive the arguments as necessary from the environment
					dirtEvent.sendSynth(~instrument, argNames)
				}
			}
		}
});
)

Much better is this, I'll also add this to superdirt. I haven't tested this, so let us know if it works.

(
~dirt.addModule('sound',
	{ |dirtEvent|
		if(~diversion.value.isNil) {
			if(~buffer.notNil) {
				// argumets could be omitted using getMsgFunc, but for making it easier to understand, we write them out
				dirtEvent.sendSynth(~instrument,  [
					bufnum: ~buffer,
					sustain: ~sustain,
					speed: ~speed,
					endSpeed: ~endSpeed,
					begin: ~begin,
					end: ~end,
					loop: ~loop,
					pan: ~pan,
					out: ~out
				])
			} {
				if(~instrument.isNil) {
					"instrument not found: %".format(~sound).postln
				} {
					// here, we just derive the arguments as necessary from the environment
					dirtEvent.sendSynth(~instrument, ~argNames)
				}
			}
		}
});
)

// then add your synth arguments for each synth separately:

~dirt.soundLibrary.addEvent(\foo4, (argNames: [\out]));

@vivid-synth
Copy link
Owner

@telephon I tried those two code snippets (on the 1.0-dev branch), but neither worked -- in fact, they wouldn't play samples either.

@telephon
Copy link

Can you describe? Did they post any error message? Have you tried adding a postln to see if the function is called?

@jarmitage
Copy link
Author

Thanks @vivid-synth I'm going to try the workaround and will post any results here...

@jarmitage
Copy link
Author

jarmitage commented Nov 25, 2017

My startup.scd looks a bit different to yours @vivid-synth, so I just tried running:

SynthDef(\foo4, {|out=0|
	Out.ar(out, DC.ar(0))
}).add;

~dirt.soundLibrary.addSynth(\foo4);

After SuperDirt had launched, and got:

ERROR: tried to add Nil to synth event library
CALL STACK:
	Exception:reportError   0x118e11058
		arg this = <instance of Error>
	Nil:handleError   0x118e11688
		arg this = nil
		arg error = <instance of Error>
	Thread:handleError   0x118e11528
		arg this = <instance of Thread>
		arg error = <instance of Error>
	Object:throw   0x118e11898
		arg this = <instance of Error>
	DirtSoundLibrary:addSynth   0x1189cd5f8
		arg this = <instance of DirtSoundLibrary>
		arg name = 'foo4'
		arg event = nil
		arg appendToExisting = true
	Interpreter:interpretPrintCmdLine   0x1189cb978
		arg this = <instance of Interpreter>
		var res = nil
		var func = <instance of Function>
		var code = "~dirt.soundLibrary.addSynth(..."
		var doc = nil
		var ideClass = <instance of Meta_ScIDE>
	Process:interpretPrintCmdLine   0x118e11e18
		arg this = <instance of Main>
^^ The preceding error dump is for ERROR: tried to add Nil to synth event library

I'm on the SuperDirt 1.0-dev branch.

@telephon
Copy link

maybe you could instead try the code I suggested above?

@jarmitage
Copy link
Author

jarmitage commented Nov 25, 2017

@telephon when I run your 2nd snippet above, the ~dirt.addModule('sound').. works, but then I get the following when running ~dirt.soundLibrary.addEvent(\foo4, (argNames: [\out]));:

ERROR: Message 'addEvent' not understood.
RECEIVER:
Instance of DirtSoundLibrary {    (0x1132810e8, gc=F8, fmt=00, flg=00, set=03)
  instance variables [7]
    server : instance of Server (0x110818278, size=32, set=5)
    numChannels : Integer 2
    buffers : instance of IdentityDictionary (0x1107dc848, size=5, set=3)
    bufferEvents : instance of IdentityDictionary (0x11327c1d8, size=5, set=3)
    synthEvents : instance of IdentityDictionary (0x11327cc28, size=5, set=3)
    fileExtensions : instance of Array (0x11147b840, size=4, set=2)
    verbose : false
}
ARGS:
   Symbol 'foo4'
Instance of Event {    (0x11805c888, gc=F4, fmt=00, flg=00, set=03)
  instance variables [5]
    array : instance of Array (0x1139ae7a8, size=4, set=2)
    size : Integer 1
    proto : nil
    parent : nil
    know : true
}
CALL STACK:
	DoesNotUnderstandError:reportError   0x11805bd88
		arg this = <instance of DoesNotUnderstandError>
	Nil:handleError   0x11805b968
		arg this = nil
		arg error = <instance of DoesNotUnderstandError>
	Thread:handleError   0x11805c048
		arg this = <instance of Thread>
		arg error = <instance of DoesNotUnderstandError>
	Object:throw   0x11805bac8
		arg this = <instance of DoesNotUnderstandError>
	Object:doesNotUnderstand   0x11805e098
		arg this = <instance of DirtSoundLibrary>
		arg selector = 'addEvent'
		arg args = [*2]
	Interpreter:interpretPrintCmdLine   0x117474ac8
		arg this = <instance of Interpreter>
		var res = nil
		var func = <instance of Function>
		var code = "~dirt.soundLibrary.addEvent(..."
		var doc = nil
		var ideClass = <instance of Meta_ScIDE>
	Process:interpretPrintCmdLine   0x11805ce08
		arg this = <instance of Main>
^^ The preceding error dump is for ERROR: Message 'addEvent' not understood.
RECEIVER: a DirtSoundLibrary

@jarmitage
Copy link
Author

jarmitage commented Nov 25, 2017

@telephone did you mean to write addSynth instead of addEvent?

I tried this below now, no errors but I got instrument not found: nil from SuperDirt when playing from Tidal

(
~dirt.addModule('sound',
	{ |dirtEvent|
		if(~diversion.value.isNil) {
			if(~buffer.notNil) {
				// argumets could be omitted using getMsgFunc, but for making it easier to understand, we write them out
				dirtEvent.sendSynth(~instrument,  [
					bufnum: ~buffer,
					sustain: ~sustain,
					speed: ~speed,
					endSpeed: ~endSpeed,
					begin: ~begin,
					end: ~end,
					loop: ~loop,
					pan: ~pan,
					out: ~out
				])
			} {
				if(~instrument.isNil) {
					"instrument not found: %".format(~sound).postln
				} {
					// here, we just derive the arguments as necessary from the environment
					dirtEvent.sendSynth(~instrument, ~argNames)
				}
			}
		}
});
)

SynthDef(\foo4, {|out=0|
	Out.ar(out, DC.ar(0))
}).add;

~dirt.soundLibrary.addSynth(\foo4, (argNames: [\out]));

If I change this to the below, I get FAILURE IN SERVER /s_new wrong argument type

(
~dirt.addModule('sound',
	{ |dirtEvent|
		if(~diversion.value.isNil) {
			if(~buffer.notNil) {
				// argumets could be omitted using getMsgFunc, but for making it easier to understand, we write them out
				dirtEvent.sendSynth(~instrument,  [
					bufnum: ~buffer,
					sustain: ~sustain,
					speed: ~speed,
					endSpeed: ~endSpeed,
					begin: ~begin,
					end: ~end,
					loop: ~loop,
					pan: ~pan,
					out: ~out
				])
			} {
				dirtEvent.sendSynth(~instrument, ~argNames)
			}
		}
});
)

SynthDef(\foo4, {|out=0|
	Out.ar(out, DC.ar(0))
}).add;

~dirt.soundLibrary.addSynth(\foo4, (argNames: [\out]));

I get FAILURE IN SERVER /s_new wrong argument type as well for this

(
~dirt.addModule('sound',
	{ |dirtEvent|
		if(~diversion.value.isNil) {
			if(~buffer.notNil) {
				// argumets could be omitted using getMsgFunc, but for making it easier to understand, we write them out
				dirtEvent.sendSynth(~instrument,  [
					bufnum: ~buffer,
					sustain: ~sustain,
					speed: ~speed,
					endSpeed: ~endSpeed,
					begin: ~begin,
					end: ~end,
					loop: ~loop,
					pan: ~pan,
					out: ~out
				])
			} {
				// if(~instrument.isNil) {
					// "instrument not found: %".format(~sound).postln
				// } {
					// here, we just derive the arguments as necessary from the environment
					dirtEvent.sendSynth(~instrument, ~argNames)
				// }
			}
		}
});
)

SynthDef(\foo4, {|out=0, freq=440|
	Out.ar(out, DC.ar(0))
}).add;

~dirt.soundLibrary.addSynth(\foo4, (argNames: [\out, \freq]));

@jarmitage
Copy link
Author

If I change my startup.scd to look more like @vivid-synth's, I get instrument not found: nil

(
s.options.numBuffers = 1024 * 32;
s.options.memSize = 8192 * 64;
s.options.maxNodes = 1024 * 32;
s.options.numOutputBusChannels = 16;
s.options.numInputBusChannels = 2;
s.options.device = "SuperCollider";
s.waitForBoot {
	Routine{
		include("Vowel");
		include("SuperDirt");
		2.wait;
		~dirt = SuperDirt(2,s);
		~dirt.start(57120, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]);

		SynthDef(\foo4, {|out=0, freq=440|
			Out.ar(out, DC.ar(0))
		}).add;

		~dirt.soundLibrary.addSynth(\foo4, (argNames: [\out, \freq]));
}.play
}
)

@jarmitage
Copy link
Author

Usually when you use a wrong synth/sample name in SuperDirt you get the message

no synth or sample named 'blahblahblah' could be found.
instrument not found: nil

But in this case it's just instrument not found: nil

@telephon
Copy link

telephon commented Nov 26, 2017

  1. yes, I meant addSynth, not addEvent (sorry!)
  2. I forgot that you need to add the synthdef name (instrument:) explictly
  3. no need to add a SynthDef as you did, this makes it hard to test, because this is what you don't want to do in the future, do you? So you could just use send(s) instead of add, then you can be sure that nothing is added to the SynthDescLib
~dirt.soundLibrary.addSynth(\foo4, (instrument: \foo4, argNames: [\out]));

@telephon
Copy link

telephon commented Nov 26, 2017

So the corrected code, to be added to the startup file after the SuperDirt init, would be:

(
~dirt.addModule('sound',
	{ |dirtEvent|
		if(~diversion.value.isNil) {
			if(~buffer.notNil) {
				// argumets could be omitted using getMsgFunc, but for making it easier to understand, we write them out
				dirtEvent.sendSynth(~instrument,  [
					bufnum: ~buffer,
					sustain: ~sustain,
					speed: ~speed,
					endSpeed: ~endSpeed,
					begin: ~begin,
					end: ~end,
					loop: ~loop,
					pan: ~pan,
					out: ~out
				])
			} {
				if(~instrument.isNil) {
					"instrument not found: %".format(~sound).postln
				} {
					// here, we just derive the arguments as necessary from the environment
					dirtEvent.sendSynth(~instrument, ~argNames)
				}
			}
		}
});
);

// dummy synth def, this is just for now, until you have a synthdef in vivid.
SynthDef(\foo4, {|out=0| }).send(s);

//  add your synth arguments for each synth separately:
~dirt.soundLibrary.addSynth(\foo4, (instrument: \foo4, argNames: [\out]));

untested, let me know how it goes …

@jarmitage
Copy link
Author

jarmitage commented Nov 26, 2017

Ok, so @telephon that seems to work, i.e I can add a synth from Vivid without using send(s), but unfortunately now when I do d1 $ sound "foo4" or d1 $ sound "foo4*4" # note "0 1 2 3" I just get lots of little clicks instead of a note

This might be because I don't know what I'm doing with Vivid. @vivid-synth do you have some more example Vivid code to try?

Output from SC post window after running the block and addSynth lines above, then adding and using a synth from Tidal/Vivid:

SuperDirt: listening to Tidal on port 57120
-> a SuperDirt
-> a DirtSoundLibrary
[ "/d_recv", DATA[414], DATA[16] ]
[ "#bundle", 15980408986180207021, 
  [ 12, 1003, 1 ],
  [ 15, 1003, "delayAmp", 0, "lock", 0, "cps", 1 ],
  [ 12, 1002, 1 ],
  [ 15, 1002, "dry", 0 ],
  [ "/g_new", 1064, 1, 2 ],
  [ "/s_new", "foo4", -1, 1, 1064, "out" ],
  [ "/s_new", "dirt_gate2", -1, 1, 1064, "in", 18, "out", 20, "amp", 0.4, "sample", 0, "sustain", 0.999, "fadeInTime", 0, "fadeTime", 0.001 ]
]
[ "#bundle", 15980408990475178535, 
  [ 12, 1003, 1 ],
  [ 12, 1002, 1 ],
  [ "/g_new", 1065, 1, 2 ],
  [ "/s_new", "foo4", -1, 1, 1065, "out" ],
  [ "/s_new", "dirt_gate2", -1, 1, 1065, "in", 18, "out", 20, "amp", 0.4, "sample", 0, "sustain", 0.999, "fadeInTime", 0, "fadeTime", 0.001 ]
]

@telephon
Copy link

but unfortunately now when I do d1 $ sound "foo4" or d1 $ sound "foo4*4" # note "0 1 2 3" I just get lots of little clicks instead of a note

Maybe you have to add the freq argument, too? The example I posted was really just a prototype, with only an out argument. Whatever argument you want to pass to your synth will need to be in your argument list in addSynth's argNames.

@jarmitage
Copy link
Author

jarmitage commented Nov 27, 2017

Currently I am testing with

~dirt.soundLibrary.addSynth(\foo4, (instrument: \foo4, argNames: [\out, \freq, \note]));

And

:set -XDataKinds

import Vivid

let s' = sdNamed "foo4" (0::I "out") $ do { s <- sinOsc (freq_ 440) ~* percGen none ~* 0.1 ; out (V::V "out") [s,s] } :: SynthDef '["out"]

defineSD s'

d2 $ s "foo4" # note "1" # freq "440"

But I just get clicks

@vivid-synth
Copy link
Owner

With the new code, I'm able to repro the just clicks/no music behavior (yay!) -- I'll try and identify the difference between it and my working code.

The error I get is:

exception in /s_new: type cannot be converted to float

Which I bet is the supernova equivalent of @jarmitage 's /s_new wrong argument type error

@jarmitage :

  • One thing I notice is that your code has argNames: [\out, \freq, \note], but the SynthDef only has out. I also think you probably only either want note or freq (I think tidal does conversion betw note and freq)

@telephon :

  • Interesting that we can use SynthDef.send(s) -- I thought that the whole reason we used .add`` was to add it to the SynthDescLib```
  • By the way, if you do want to install Vivid to test any of this, if you've already got Haskell installed for Tidal it should be as simple as cabal update ; cabal install vivid

@vivid-synth
Copy link
Owner

Ok, new error:

exception in /s_new: invalid name for control mapping

if I use the synthdef:

s' :: SynthDef '["out", "freq"]
s' = sdNamed "foo4" (0::I "out", 440::I "freq") $ do
   env <- percGen none ~* 0.5
   s <- sinOsc (freq_ (V::V "freq")) ~* env
   out (V::V "out") [s,s]

(which, note, has out and freq args)

and I add out and freq to the new stuff:

SynthDef(\foo4, {|out=0,freq=440| }).send(s);

~dirt.soundLibrary.addSynth(\foo4, (instrument: \foo4, argNames: [\out, \freq]));

@vivid-synth
Copy link
Owner

@telephon this is what I'm seeing:

received osc bundle { ( 15980813467621782715 )
  [12 int32:1003, int32:1]
  [12 int32:1002, int32:1]
  [/g_new int32:1412, int32:1, int32:2]
  [/s_new OSC-string:`foo4', int32:-1, int32:1, int32:1412, OSC-string:`out', OSC-string:`freq']
  [/s_new OSC-string:`dirt_gate2', int32:-1, int32:1, int32:1412, OSC-string:`in', int32:4, OSC-string:`out', int32:6, OSC-string:`amp', float32:0.16384, OSC-string:`sample', int32:0, OSC-string:`sustain', float32:0.999, OSC-string:`fadeInTime', float32:0, OSC-string:`fadeTime', float32:0.001]
}

exception in /s_new: invalid name for control mapping
exception in /s_new: invalid name for control mapping
exception in /s_new: invalid name for control mapping

The first /s_new looks very weird, with OSC-string:`out', OSC-string:`freq'] by themselves at the end there.

It also seems not to have any of the arguments I'm sending. E.g. here's the line I'm using to call it:

d2 $ s "foo4*8 " # note "[1 3 2 5]*2 " # gain "1.2 0.8"

@jarmitage
Copy link
Author

@vivid-synth I just retested with the below setup and got the same clicks, no errors

SynthDef(\foo4, {|out=0,freq=440| }).send(s);

~dirt.soundLibrary.addSynth(\foo4, (instrument: \foo4, argNames: [\out, \freq]));
:set -XDataKinds

import Vivid

s' :: SynthDef '["out", "freq"]
s' = sdNamed "foo4" (0::I "out", 440::I "freq") $ do
   env <- percGen none ~* 0.5
   s <- sinOsc (freq_ (V::V "freq")) ~* env
   out (V::V "out") [s,s]

defineSD s'

d1 $ s "foo4*8 " # note "[1 3 2 5]*2 " # gain "1.2 0.8"

@vivid-synth
Copy link
Owner

@jarmitage does your /s_new look like mine? (With OSC-string:`out', OSC-string:`freq'] at the end, and seeminly no note/freq values?)

@vivid-synth
Copy link
Owner

(Oops, forgot to mention: to get the full OSC message you need to boot with s.dumpOSC(1); inside your s.boot function @jarmitage )

@jarmitage
Copy link
Author

Here's the full output with s.dumpOSC(1); on

SuperDirt: listening to Tidal on port 57120
-> a SuperDirt // ~dirt.addModule('sound'...
-> a DirtSoundLibrary // ~dirt.soundLibrary.addSynth(\foo4...
[ "#bundle", 0, 
  [ "/dumpOSC", 1 ],
  [ "/g_new", 1, 0, 0 ],
  [ "/sync", 9998 ]
]
[ "/d_recv", DATA[424], DATA[16] ]
[ "#bundle", 15980845770847757276, 
  [ 12, 1003, 1 ],
  [ 15, 1003, "delayAmp", 0, "lock", 0, "cps", 0.166667 ],
  [ 12, 1002, 1 ],
  [ 15, 1002, "dry", 0 ],
  [ "/g_new", 1064, 1, 2 ],
  [ "/s_new", "foo4", -1, 1, 1064, "out", "freq" ],
  [ "/s_new", "dirt_gate2", -1, 1, 1064, "in", 18, "out", 20, "amp", 0.82944, "sample", 0, "sustain", 0.999, "fadeInTime", 0, "fadeTime", 0.001 ]
]
[ "#bundle", 15980845774068982168, 
  [ 12, 1003, 1 ],
  [ 12, 1002, 1 ],
  [ "/g_new", 1065, 1, 2 ],
  [ "/s_new", "foo4", -1, 1, 1065, "out", "freq" ],
  [ "/s_new", "dirt_gate2", -1, 1, 1065, "in", 18, "out", 20, "amp", 0.82944, "sample", 0, "sustain", 0.999, "fadeInTime", 0, "fadeTime", 0.001 ]
]
[ "#bundle", 15980845777290208357, 
  [ 12, 1003, 1 ],
  [ 12, 1002, 1 ],
  [ "/g_new", 1066, 1, 2 ],
  [ "/s_new", "foo4", -1, 1, 1066, "out", "freq" ],
  [ "/s_new", "dirt_gate2", -1, 1, 1066, "in", 18, "out", 20, "amp", 0.82944, "sample", 0, "sustain", 0.999, "fadeInTime", 0, "fadeTime", 0.001 ]
]
[ "#bundle", 15980845780511433155, 
  [ 12, 1003, 1 ],
  [ 12, 1002, 1 ],
  [ "/g_new", 1067, 1, 2 ],
  [ "/s_new", "foo4", -1, 1, 1067, "out", "freq" ],
  [ "/s_new", "dirt_gate2", -1, 1, 1067, "in", 18, "out", 20, "amp", 0.16384, "sample", 0, "sustain", 0.999, "fadeInTime", 0, "fadeTime", 0.001 ]
]
[ "#bundle", 15980845783732652940, 
  [ 12, 1003, 1 ],
  [ 12, 1002, 1 ],
  [ "/g_new", 1068, 1, 2 ],
  [ "/s_new", "foo4", -1, 1, 1068, "out", "freq" ],
  [ "/s_new", "dirt_gate2", -1, 1, 1068, "in", 18, "out", 20, "amp", 0.16384, "sample", 0, "sustain", 0.999, "fadeInTime", 0, "fadeTime", 0.001 ]
]
[ "#bundle", 15980845786953884756, 
  [ 12, 1003, 1 ],
  [ 12, 1002, 1 ],
  [ "/g_new", 1069, 1, 2 ],
  [ "/s_new", "foo4", -1, 1, 1069, "out", "freq" ],
  [ "/s_new", "dirt_gate2", -1, 1, 1069, "in", 18, "out", 20, "amp", 0.16384, "sample", 0, "sustain", 0.999, "fadeInTime", 0, "fadeTime", 0.001 ]
]
[ "#bundle", 15980845790175107784, 
  [ 12, 1003, 1 ],
  [ 12, 1002, 1 ],
  [ "/g_new", 1070, 1, 2 ],
  [ "/s_new", "foo4", -1, 1, 1070, "out", "freq" ],
  [ "/s_new", "dirt_gate2", -1, 1, 1070, "in", 18, "out", 20, "amp", 0.16384, "sample", 0, "sustain", 0.999, "fadeInTime", 0, "fadeTime", 0.001 ]
]
[ "#bundle", 15980845793396337178, 
  [ 12, 1003, 1 ],
  [ 12, 1002, 1 ],
  [ "/g_new", 1071, 1, 2 ],
  [ "/s_new", "foo4", -1, 1, 1071, "out", "freq" ],
  [ "/s_new", "dirt_gate2", -1, 1, 1071, "in", 18, "out", 20, "amp", 0.82944, "sample", 0, "sustain", 0.999, "fadeInTime", 0, "fadeTime", 0.001 ]
]

@vivid-synth
Copy link
Owner

@telephon looks like the same problem I saw. Is this a problem with the ~dirt.addModule('sound', code you sent?

@telephon
Copy link

[ "/s_new", "foo4", -1, 1, 1064, "out", "freq" ],

That is wrong. OK, I see (sorry, I don't currently have a tidal that works so I can't test). You could try this next:

(
~dirt.addModule('sound',
	{ |dirtEvent|
                var args;
		if(~diversion.value.isNil) {
			if(~buffer.notNil) {
				// argumets could be omitted using getMsgFunc, but for making it easier to understand, we write them out
				dirtEvent.sendSynth(~instrument,  [
					bufnum: ~buffer,
					sustain: ~sustain,
					speed: ~speed,
					endSpeed: ~endSpeed,
					begin: ~begin,
					end: ~end,
					loop: ~loop,
					pan: ~pan,
					out: ~out
				])
			} {
				if(~instrument.isNil) {
					"instrument not found: %".format(~sound).postln
				} {
					// here, we just derive the arguments as necessary from the environment
                                       if(~argNames.notNil) { 
                                          args =  currentEnvironment.getPairs(~argNames);
                                      };
				     dirtEvent.sendSynth(~instrument, args)
				}
			}
		}
});
);

// dummy synth def, this is just for now, until you have a synthdef in vivid.
SynthDef(\foo4, {|out=0| }).send(s);

//  add your synth arguments for each synth separately:
~dirt.soundLibrary.addSynth(\foo4, (instrument: \foo4, argNames: [\out]));

@jarmitage
Copy link
Author

@telephon still just clicking sounds

Example:

[ "#bundle", 15981576535494287961, 
  [ 12, 1003, 1 ],
  [ 12, 1002, 1 ],
  [ "/g_new", 1124, 1, 2 ],
  [ "/s_new", "foo4", -1, 1, 1124, "out", 18 ],
  [ "/s_new", "dirt_gate2", -1, 1, 1124, "in", 18, "out", 20, "amp", 0.82944, "sample", 0, "sustain", 0.999, "fadeInTime", 0, "fadeTime", 0.001 ]
]
[ "#bundle", 15981576536031158483, 
  [ 12, 1003, 1 ],
  [ 12, 1002, 1 ],
  [ "/g_new", 1125, 1, 2 ],
  [ "/s_new", "foo4", -1, 1, 1125, "out", 18 ],
  [ "/s_new", "dirt_gate2", -1, 1, 1125, "in", 18, "out", 20, "amp", 0.16384, "sample", 0, "sustain", 0.999, "fadeInTime", 0, "fadeTime", 0.001 ]
]
[ "#bundle", 15981576536568026749, 
  [ 12, 1003, 1 ],
  [ 12, 1002, 1 ],
  [ "/g_new", 1126, 1, 2 ],
  [ "/s_new", "foo4", -1, 1, 1126, "out", 18 ],
  [ "/s_new", "dirt_gate2", -1, 1, 1126, "in", 18, "out", 20, "amp", 0.16384, "sample", 0, "sustain", 0.999, "fadeInTime", 0, "fadeTime", 0.001 ]
]
[ "#bundle", 15981576537104874425, 
  [ 12, 1003, 1 ],
  [ 12, 1002, 1 ],
  [ "/g_new", 1127, 1, 2 ],
  [ "/s_new", "foo4", -1, 1, 1127, "out", 18 ],
  [ "/s_new", "dirt_gate2", -1, 1, 1127, "in", 18, "out", 20, "amp", 0.16384, "sample", 0, "sustain", 0.999, "fadeInTime", 0, "fadeTime", 0.001 ]
]
[ "#bundle", 15981576537641777472, 
  [ 12, 1003, 1 ],
  [ 12, 1002, 1 ],
  [ "/g_new", 1128, 1, 2 ],
  [ "/s_new", "foo4", -1, 1, 1128, "out", 18 ],
  [ "/s_new", "dirt_gate2", -1, 1, 1128, "in", 18, "out", 20, "amp", 0.16384, "sample", 0, "sustain", 0.999, "fadeInTime", 0, "fadeTime", 0.001 ]
]
[ "#bundle", 15981576538178657571, 
  [ 12, 1003, 1 ],
  [ 12, 1002, 1 ],
  [ "/g_new", 1129, 1, 2 ],
  [ "/s_new", "foo4", -1, 1, 1129, "out", 18 ],
  [ "/s_new", "dirt_gate2", -1, 1, 1129, "in", 18, "out", 20, "amp", 0.82944, "sample", 0, "sustain", 0.999, "fadeInTime", 0, "fadeTime", 0.001 ]
]
[ "#bundle", 15981576538715527847, 
  [ 12, 1003, 1 ],
  [ 12, 1002, 1 ],
  [ "/g_new", 1130, 1, 2 ],
  [ "/s_new", "foo4", -1, 1, 1130, "out", 18 ],
  [ "/s_new", "dirt_gate2", -1, 1, 1130, "in", 18, "out", 20, "amp", 0.82944, "sample", 0, "sustain", 0.999, "fadeInTime", 0, "fadeTime", 0.001 ]
]
[ "#bundle", 15981576539252398248, 
  [ 12, 1003, 1 ],
  [ 12, 1002, 1 ],
  [ "/g_new", 1131, 1, 2 ],
  [ "/s_new", "foo4", -1, 1, 1131, "out", 18 ],
  [ "/s_new", "dirt_gate2", -1, 1, 1131, "in", 18, "out", 20, "amp", 0.82944, "sample", 0, "sustain", 0.999, "fadeInTime", 0, "fadeTime", 0.001 ]
]
[ "#bundle", 15981576539789266828, 
  [ 12, 1003, 1 ],
  [ 12, 1002, 1 ],
  [ "/g_new", 1132, 1, 2 ],
  [ "/s_new", "foo4", -1, 1, 1132, "out", 18 ],
  [ "/s_new", "dirt_gate2", -1, 1, 1132, "in", 18, "out", 20, "amp", 0.82944, "sample", 0, "sustain", 0.999, "fadeInTime", 0, "fadeTime", 0.001 ]
]
[ "#bundle", 15981576540326144092, 
  [ 12, 1003, 1 ],
  [ 12, 1002, 1 ],
  [ "/g_new", 1133, 1, 2 ],
  [ "/s_new", "foo4", -1, 1, 1133, "out", 18 ],
  [ "/s_new", "dirt_gate2", -1, 1, 1133, "in", 18, "out", 20, "amp", 0.16384, "sample", 0, "sustain", 0.999, "fadeInTime", 0, "fadeTime", 0.001 ]
]

@vivid-synth
Copy link
Owner

vivid-synth commented Nov 30, 2017

@jarmitage this is not the right solution long-term (and @telephon can I help in some way digging into this?) but - for the time being: simplest seems to be best. This works for me:

boot.scd:

Server.supernova;
s.options.numBuffers = 1024 * 16;

s.waitForBoot{
Routine{
include("Vowel");
include("SuperDirt");

// In other words, we define all the SynthDefs, with their args, *before* calling SuperDirt.start:
SynthDef(\foo4, {|out=0, freq=440|
   Out.ar(out, DC.ar(0))
}).add; // .send might(?) be better here but I don't want to mess with what works


SuperDirt.start;
}.play
}

foo.tidal:

:set -XDataKinds
import Vivid

-- Use C-c C-e in emacs to eval the whole definition:
s' :: SynthDef '["out", "freq"]
s' = sdNamed "foo4" (0::I "out", 440::I "freq") $ do
   env <- percGen none ~* 0.5
   s <- sinOsc (freq_ (V::V "freq")) ~* env
   out (V::V "out") [s,s]

defineSD $ s'

d2 $ s "foo4*8 " # note "[1 3 2 5]*2 " # gain "1.2 0.8"

@jarmitage
Copy link
Author

@vivid-synth yes that works - you don't need to add the synth before SuperDirt.start either

Thanks both for looking into this. I can just define vivid1, vivid2, vivid3 etc for now!

@telephon
Copy link

yes, that's also a good way.

}).add; // .send might(?) be better here but I don't want to mess with what works

No, you need. add.
For the time being, that should be OK.

A safer alternative might be to load the SynthDesc from the file you generate in vivid:

SynthDescLib.read(path/to/your/file.scsyndef)

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

No branches or pull requests

3 participants