Author |
Message |
x0ph

Joined: Oct 02, 2008 Posts: 6 Location: Belfast
|
Posted: Mon Dec 01, 2008 6:54 am Post subject:
SC: Conveying Envelope descriptions via OSC bundles. Subject description: SuperCollider Env via OSC questions |
 |
|
Hi everyone,
Actually I got a couple of questions. I'd like to pass Env parameters as args to a Synth from a custom application using OSC. I found one way to modify Env parameters in a synth is to use control.names in the SynthDef (this is from the SChelpBook [Help->Control->Env]), e.g.
Code: | envctl = Control.names([\env]).kr( env.asArray ); |
And this can be referred to later on using :
Code: | (
s.makeBundle(nil, {
// must not have more segments than the env above
e = Env([700,900,900,800], [1,1,1], \exp); // 3 segments
x = Synth("Help-Env-newClear", [\t_gate, 1]);
x.setn(\env, e.asArray);
});
) |
Inspecting the OSC dump in the post window I found that SC is somehow converting the lines above to
Code: | ["#bundle", 1,
[ 9, "Help-Env-newClear", 1000, 0, 1, "t_gate", 1 ],
[ 16, 1000, "env", 16, 700, 3, -99, -99, 900, 1, 2, 0, 900, 1, 2, 0, 800, 1, 2, 0 ]
] |
1) Where do the -99s come from?
2) What's the difference between /n_set and /n_setn? (Apart from the additional n )
3) Can I get a list somewhere linking the SC internal commands (like 9) to the external names (like /s_new)?
4) What is levelBias doing in EnvGen? |
|
Back to top
|
|
 |
dewdrop_world

Joined: Aug 28, 2006 Posts: 858 Location: Guangzhou, China
Audio files: 4
|
Posted: Mon Dec 01, 2008 10:08 am Post subject:
Re: SC: Conveying Envelope descriptions via OSC bundles. Subject description: SuperCollider Env via OSC questions |
 |
|
If you can get the sources from svn and build the latest version, this whole thing got a lot easier just recently. In the newest code, it should be OK to do this:
Synth("Help-Env-newClear", [t_gate: 1, env: e.asArray]);
In the stable 3.2 version, the setn technique is still needed.
x0ph wrote: | 1) Where do the -99s come from? |
The array generated by an envelope has the following:
[initial level, number of segments, releaseNode, loopNode,
next level, next time, shape number, curve,
next level, next time, shape number, curve, ...]
If releaseNode or loopNode are empty, they're replaced by -99. EnvGen recognizes -99 there as a signal not to sustain or loop over any envelope segments.
x0ph wrote: | 2) What's the difference between /n_set and /n_setn? (Apart from the additional n ) |
n_set sets one control value. You supply \argname, value, \argname, value where each value must be a single number.
n_setn sets several. value can be an array or single number.
x0ph wrote: | 3) Can I get a list somewhere linking the SC internal commands (like 9) to the external names (like /s_new)? |
Server Command Reference help file.
x0ph wrote: | 4) What is levelBias doing in EnvGen? |
levelBias adds a value to the level -- EnvGen targets the next breakpoint at (level from Env) * levelScale + levelBias.
James _________________ ddw online: http://www.dewdrop-world.net
sc3 online: http://supercollider.sourceforge.net |
|
Back to top
|
|
 |
x0ph

Joined: Oct 02, 2008 Posts: 6 Location: Belfast
|
Posted: Thu Dec 11, 2008 4:11 am Post subject:
Additive synth by grouping: re-trigger the group of synths Subject description: re-trigger group of synths |
 |
|
Thanks dewdrop_world !
Your comments actually helped a lot. It’s kind of working now!
Now I got stuck at another point.
I try to set up an additive synth that mixes n number of (not necessarily harmonic) frequencies together, each with individual ADSR envelope.
I've decided to use a simple sine synth with control.names for the \env (as mentioned above) to create the group of sines with the desired timbre. That works pretty good so far, I can define master controls that influence every group member.
The problem is, that I'd like to play this newly created sound like an instrument - and I don't want to send a whole bunch of envelope definitions and frequencies each time I play a simple note! So my question is, whether there's a way to reuse the configuration of such a group with little changes, for instance only the frequency changes. That is I want to re-trigger the group of synths.
Instr sounded somewhat like what I'm looking for, but I didn't quite get the idea behind Instr. All I could figure out is that "An Instr is not a SynthDef". So what is it
Also: Is there a smart way of integrating pitch shifts in additive synths (each partial with a factor)  |
|
Back to top
|
|
 |
x0ph

Joined: Oct 02, 2008 Posts: 6 Location: Belfast
|
Posted: Sun Dec 21, 2008 4:53 pm Post subject:
|
 |
|
Does anyone know the types (integer, float, binary, ...) SuperCollider uses for envelope osc descriptions such as
Code: | [ 16, 1000, "env", 16, 700, 3, 2, -99, 900, 1, 2, 0, 900, 1, 2, 0, 800, 1, 2, 0 ] |
I tried Code: | isiffiiffiiffiiffii | , but it won’t accept the release node, but stops playing even though the gate value wasn’t changed to 0! Remedy please::: |
|
Back to top
|
|
 |
dewdrop_world

Joined: Aug 28, 2006 Posts: 858 Location: Guangzhou, China
Audio files: 4
|
Posted: Mon Dec 22, 2008 8:42 pm Post subject:
|
 |
|
If you send them to controls that are local to a synth, once the synth goes away, the values you sent are forgotten. So maybe it would be better to send them to something else.
Maybe a buffer... instead of using the array control, access the buffer data using Index.kr(bufnum, (0..(buffersize)). Once you put the data into a buffer, they persist there until you put something else in.
I think Instr is probably not what you want here. An Instr is a prototype, like a cookie cutter that can make lots of slightly varying SynthDefs. But if you pass an Env in at the time of building the SynthDef, the Env is hardcoded and can't be changed from outside.
Quote: | Also: Is there a smart way of integrating pitch shifts in additive synths (each partial with a factor) |
Do you mean multiplying each frequency by the same number? Easy... [array of frequencies] * factor. Or did you have something else in mind?
Quote: | I tried
Code:
isiffiiffiiffiiffii
, but it won’t accept the release node, but stops playing even though the gate value wasn’t changed to 0! Remedy please::: |
As far as I can see, supercollider tends to use i, s and f. What I don't see is how you've encoded the various integers and floats. The example array except for "env" consists of integers so I'm not sure why you have f in the type tags.
There seems to be a bug with the asRawOSC primitive -- it doesn't like message arrays that use the command index instead of a command string. If I change 16 to n_setn, supercollider generates a long string of i in the type tags.
[ '/n_setn', 1000, "env", 16, 700, 3, 2, -99, 900, 1, 2, 0, 900, 1, 2, 0, 800, 1, 2, 0 ].asRawOSC
--> Int8Array[ 47, 110, 95, 115, 101, 116, 110, 0, 44, 105, 115, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 0, 0, 0, 0, 0, 0, 3, -24, 101, 110, 118, 0, 0, 0, 0, 16, 0, 0, 2, -68, 0, 0, 0, 3, 0, 0, 0, 2, -1, -1, -1, -99, 0, 0, 3, -124, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 3, -124, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 3, 32, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0 ]
Sorry if I'm not being much help... I usually don't work with OSC at this low level.
hjh _________________ ddw online: http://www.dewdrop-world.net
sc3 online: http://supercollider.sourceforge.net |
|
Back to top
|
|
 |
dewdrop_world

Joined: Aug 28, 2006 Posts: 858 Location: Guangzhou, China
Audio files: 4
|
Posted: Tue Dec 23, 2008 5:56 am Post subject:
|
 |
|
Maybe it would help to clarify that all those type tags are i because all the numbers in the message array are integers. If some of them were floats, there would be f's in those slots.
Also, I found out what was up with asRawOSC. If the array starts with a number, it assumes that it's an OSC bundle rather than a single message.
[ 9, \default, 1000, 0, 1, \freq, 600, \amp, 0.1 ].asRawOSC
--> Int8Array[ 35, 98, 117, 110, 100, 108, 101, 0, 0, 0, 0, 9, 0, 0, 0, 0 ]
That is, it writes out the header for #bundle with nine messages enclosed, but then it doesn't know how to interpret the non-array elements following. But a one-command bundle gets written out properly.
[ 1, [9, \default, 1000, 0, 1, \freq, 600, \amp, 0.1] ].asRawOSC
Int8Array[ 35, 98, 117, 110, 100, 108, 101, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 56, 0, 0, 0, 9, 44, 115, 105, 105, 105, 115, 105, 115, 102, 0, 0, 0, 100, 101, 102, 97, 117, 108, 116, 0, 0, 0, 3, -24, 0, 0, 0, 0, 0, 0, 0, 1, 102, 114, 101, 113, 0, 0, 0, 0, 0, 0, 2, 88, 97, 109, 112, 0, 61, -52, -52, -51 ]
James _________________ ddw online: http://www.dewdrop-world.net
sc3 online: http://supercollider.sourceforge.net |
|
Back to top
|
|
 |
dewdrop_world

Joined: Aug 28, 2006 Posts: 858 Location: Guangzhou, China
Audio files: 4
|
Posted: Wed Dec 24, 2008 8:18 am Post subject:
|
 |
|
Actually, even better might be to use control buses for the envelopes. Control buses also persist past the lifetime of any single synth.
That is, if the envelope array size is 20:
Code: | ~envbus = Bus.control(s, 20);
['/c_setn', ~envbus.index, 20] ++ envArray.extend(20, 0)
['/s_new', 'mySynth', 1000, 0, 1, envbus, ~envbus.index] |
And the synth can get the envelope values using In.kr:
Code: | EnvGen.kr(In.kr(envbus, 20), gate, ...) |
hjh _________________ ddw online: http://www.dewdrop-world.net
sc3 online: http://supercollider.sourceforge.net |
|
Back to top
|
|
 |
x0ph

Joined: Oct 02, 2008 Posts: 6 Location: Belfast
|
Posted: Tue Jan 06, 2009 2:49 am Post subject:
frequency transition |
 |
|
I changed my set-up now to work with control busses, though I had to hard code them, since I can't take advantage of the SC internal bus.control (this would require me to send the index number to my external GUI application, and I don't want to implement a bidirectional OSC yet).
This actually solved the problem of envelopes stopping before the release node! Good hint.
Quote: | The example array except for "env" consists of integers so I'm not sure why you have f in the type tags.
|
The reason for these false type tags is that I'm using my external GUI to generate the messages. The slots with a type tag for floats may contain float values the next time an OSC message is generated. I should have used 1.0 instead of 1 really. This seems to be working fine now (until I discover a new massive problem...)
What I meant by "pitch shift" is that each frequency component is shifted by an individual factor. For instance, a harmonic sound would have only integer partial factors. This was solved by specifying the frequency factor of each partial, instead of giving an absolute frequency. That way the synthDef deals with frequencies internally, but I can use frequency factors.
Now I need to find a way to do some nice "frequency transition", meaning if a sound changes from one frequency to another (including the partials), I'd like it to be smooth (e.g. change is triggered when one sine is at a peak, the new sine starts at a low, creating some irritating "bubbling" noise). Maybe there's a clever UGen that takes care of this? I haven't found anything in the help yet.
/\/\/\/\/\|\_/*\_/*\_/*\_/*\_/*
Regards
x0ph
"The reason why it's currently working is that I haven't discovered the new massive problem yet." |
|
Back to top
|
|
 |
dewdrop_world

Joined: Aug 28, 2006 Posts: 858 Location: Guangzhou, China
Audio files: 4
|
Posted: Wed Jan 07, 2009 9:42 am Post subject:
Re: frequency transition |
 |
|
x0ph wrote: | I changed my set-up now to work with control busses, though I had to hard code them, since I can't take advantage of the SC internal bus.control (this would require me to send the index number to my external GUI application, and I don't want to implement a bidirectional OSC yet). |
You could also write a bus ID allocator in your app, if hardcoding proves to be a problem. SC's bus allocator is nice but there's no requirement to use it (i.e., you're not restricted to the two choices of using SC's allocator or hardcoding - there are lots of other solutions).
x0ph wrote: | Now I need to find a way to do some nice "frequency transition", meaning if a sound changes from one frequency to another (including the partials), I'd like it to be smooth (e.g. change is triggered when one sine is at a peak, the new sine starts at a low, creating some irritating "bubbling" noise). Maybe there's a clever UGen that takes care of this? I haven't found anything in the help yet. |
Lag and its cousins are the easiest way.
Code: | b = Buffer.alloc(s, 1000, 2);
SynthDef(\lags, {
var sig = LFPulse.ar(240);
RecordBuf.ar([sig, Lag.ar(sig, 0.0012)], b, loop: 0);
Line.ar(0, 1, b.duration, doneAction: 2);
}).play;
b.plot;
// actually b.plot uses a temp file which I'm not crazy about, esp for such a small buffer
// besides, for some weird reason scsynth was crashing on my windows box with buffer.plot
// but this worked:
b.getToFloatArray(action: { |v| defer { v.plot(numChannels: 2) } }); |
Original LFPulse is the top channel in the graph, lagged is below.
James
Description: |
LFPulse on top, Lagged version of the same below |
|
Filesize: |
38.64 KB |
Viewed: |
265 Time(s) |
This image has been reduced to fit the page. Click on it to enlarge. |

|
_________________ ddw online: http://www.dewdrop-world.net
sc3 online: http://supercollider.sourceforge.net |
|
Back to top
|
|
 |
|