electro-music.com   Dedicated to experimental electro-acoustic
and electronic music
 
    Front Page  |  Articles  |  Radio
 |  Media  |  Forum  |  Links  |  Store
Forum with support of Syndicator RSS
 FAQFAQ   CalendarCalendar   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   LinksLinks GalleryGallery 
 RegisterRegister   ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in  Chat RoomChat Room 
 Forum index » DIY Hardware and Software » ChucK programming language
How do I obtain final gain level for output?
Post new topic   Reply to topic Moderators: Kassen
Page 1 of 1 [12 Posts]
View unread posts
View new posts in the last week
Mark the topic unread :: View previous topic :: View next topic
Author Message
Dr. Spankenstein



Joined: Mar 03, 2007
Posts: 136
Location: Cambridge
Audio files: 1

PostPosted: Mon Dec 31, 2007 7:52 am    Post subject: How do I obtain final gain level for output? Reply with quote  Mark this post and the followings unread

Is there a method for returning the gain level of the output of ChucK corresponding to all the Ugens that are a connected to the dac?

For example if I were to have...

Code:


SinOsc SinOsc => Gain Gain => dac;
0.5 => Gain.gain;



....it will be obvious what the gain level is, but how do I get the dac to return this value?

Oh and is this a sensible way to mix various levels?

Code:


Gain Gain => NRev r => Echo Echo1 => Echo Echo2 => Gain Mixer => dac;

SinOsc SinOsc => Gain;
//Dry
Gain => Mixer;
//Wet
Echo1 => Mixer;
1.0 => Gain.gain;
0.5 => Mixer.gain; // Gain Of Final Output



This way I can adjust the overall gain on the Mixer to affect the final output gain...

...or is there a more sensible way to do it?

Many thanks and a happy new year to all.

Rhys
Back to top
View user's profile Send private message
Kassen
Janitor
Janitor


Joined: Jul 06, 2004
Posts: 6502
Location: The Hague, NL
G2 patch files: 3

PostPosted: Mon Dec 31, 2007 10:16 am    Post subject: Reply with quote  Mark this post and the followings unread

That's a very good question.

First of all; the dac doesn't know about the gains of attached Ugens, it only knows about the values it receives and sums. Because on ChucK's side of the dac the values are double-floats (which can get very large indeed) but on the soundcard side they will eventually need to be normal 16 bit integers (asuming you are using CD quality sound) this process may lead to clipping.

There is good news though; the dac has a .gain function. Since there is only one dac for the whole system adjusting this in one shred will affect the whole system. This is nice, when I'm livecoding I'll often have one MiniAudicle screen open saying just

0.8 => dac.gain;

(of course with different values for .8 it could also be 1.2 or so)

Think of this as a master fader.

Not sure if that answers the question but at least it's a useful trick.

You could also make a shred that sends the dac's output to a envelope follower,

dac => my_ugen;

will work, you see. Based on that envelope follower's output you could also adjust the dac's gain. There's a example envelope-follower by Perry Cook in the examples dir, I think in /deep

_________________
Modern technology offers an endless field day to any deviant strains in our personalities. --J.G.Ballard
Back to top
View user's profile Send private message Send e-mail Visit poster's website
Dr. Spankenstein



Joined: Mar 03, 2007
Posts: 136
Location: Cambridge
Audio files: 1

PostPosted: Fri Jan 04, 2008 6:24 am    Post subject: Reply with quote  Mark this post and the followings unread

Thanks for the clear info.

I've been looking into perhaps limiting the output so that it doesnt clip.

I can see how this could be done with the Dyno Ugen with one shred running but what if I were to have say 3 shreds running at the same time?

Would I have to create some kind of Public Class Dyno Ugen to connect them all to (before the dac) using a similar approach as the "dinky try" code in the examples/class folder?

Or is there an alternative method that is best suited for this kind of problem?

Thanks

Rhys
Back to top
View user's profile Send private message
Dr. Spankenstein



Joined: Mar 03, 2007
Posts: 136
Location: Cambridge
Audio files: 1

PostPosted: Fri Jan 04, 2008 7:56 am    Post subject: Reply with quote  Mark this post and the followings unread

Here's a simple non-working summary of what I've been trying to do..

Code:


public class Limiter
{
   Dyno Limiter;
   Limiter.limit();
   public void connect(UGen UGen)
   {
      UGen => Limiter => dac;
   }
}

Limiter limiter;   // Instantiate Limiter Class

SinOsc SinOsc1;
SinOsc SinOsc2;
10.0 => SinOsc1.gain;   // Huge gain to be limited
10.0 => SinOsc2.gain;
SinOsc1 => dac;
SinOsc2 => dac;
440 => SinOsc1.freq;
441 => SinOsc2.freq;

limiter.connect(dac);   // Connect the Limiter
10:: second => now;



WARNING: My code is completely wrong so there is no limiting of the final signal.

I'm not sure how I could go about placing the limiter before the dac and have the two Oscillators going through that limiter first, with this current setup.

Thanks again,

Rhys
Back to top
View user's profile Send private message
Kassen
Janitor
Janitor


Joined: Jul 06, 2004
Posts: 6502
Location: The Hague, NL
G2 patch files: 3

PostPosted: Fri Jan 04, 2008 8:15 am    Post subject: Reply with quote  Mark this post and the followings unread

I'm no Dyno-expert. To be honest I tend to either use multiple outputs then mix the analogue way (shock! :¬) ) or simply turn the gains down manually...

But when I look at your code I'm fairly certain " Limiter.limit(); " would like some sort of parameter?

A public Dyno sounds to me like a good solution to your issue though the strategy I outlined above with the envelope follower may also have some strengths. It'll be slower in response but could be added to any situation without code changes to the rest. If you don't try it I'll build it myself some time (just not now :¬) ).

_________________
Modern technology offers an endless field day to any deviant strains in our personalities. --J.G.Ballard
Back to top
View user's profile Send private message Send e-mail Visit poster's website
Dr. Spankenstein



Joined: Mar 03, 2007
Posts: 136
Location: Cambridge
Audio files: 1

PostPosted: Fri Jan 04, 2008 10:12 am    Post subject: Reply with quote  Mark this post and the followings unread

Quote:


I'm no Dyno-expert



That's cool, I'm not hoping to do anything fancy with it but I am confused as to how I would connect a Public UGen at the end of list of UGens as opposed to the beginning?

For Example...

Code:


SinOsc SinOsc => "Public UGen";



as opposed to..

Code:


"Public UGen" => SinOsc SinOsc;



I really dont understand the envelope following/mixing techniques in ChucK fully just yet and this is kind of a quick fix until I figure out how to use the method you suggested.

Thanks

Rhys
Back to top
View user's profile Send private message
moudi



Joined: Oct 07, 2006
Posts: 58
Location: Bern Switzerland

PostPosted: Fri Jan 04, 2008 11:50 am    Post subject: Reply with quote  Mark this post and the followings unread

the handling with "public ugens" is a bit tricky at the moment.
if you want to use the same ugen from multiple shreds, you need to define a static ugen in your class.
so, declaring a static ugen is no problem in a class, but you can't instantiate it directly (a nice exception appears that this is not supported for now).
therefore you need to instantiate this public ugen within a shred.
this shred must be running the whole time you want to access this ugen, otherwise you'll get a null pointer exception.
(this means the instance of the public ugen gets disposed when the shred which has created the new instance is finished)

a short example could look like this....
please pay attention that this is written on the fly in this message and not tested in chuck!!

Code:

//the class
class xy
{
   static ugen @ myugen;
}

//the shred
xy myobj;
new ugen @=> myobj.myugen;
myobj.myugen => dac;
//and so on...


i hope this helps...
/moudi
Back to top
View user's profile Send private message Visit poster's website
Dr. Spankenstein



Joined: Mar 03, 2007
Posts: 136
Location: Cambridge
Audio files: 1

PostPosted: Fri Jan 04, 2008 12:41 pm    Post subject: Reply with quote  Mark this post and the followings unread

Very much so! Very Happy

For those who might be interested, my working code now looks like this:

Code:


public class Limiter
{
   static UGen @ myugen;
   Dyno Limiter @=> myugen;
   Limiter.limit();
}

Limiter limiter;   // Instantiate Limiter Class

SinOsc SinOsc1;
SinOsc SinOsc2;
10.0 => SinOsc1.gain;   // Huge gain to be limited
10.0 => SinOsc2.gain;

limiter.myugen => dac;

SinOsc1 => limiter.myugen;
SinOsc2 => limiter.myugen;
440 => SinOsc1.freq;
441 => SinOsc2.freq;

10:: second => now;



Thanks for your help guys and happy new year!

Rhys
Back to top
View user's profile Send private message
moudi



Joined: Oct 07, 2006
Posts: 58
Location: Bern Switzerland

PostPosted: Fri Jan 04, 2008 3:02 pm    Post subject: Reply with quote  Mark this post and the followings unread

aahhhm...
in your code here:
Code:

public class Limiter
{
   static UGen @ myugen;
   Dyno Limiter @=> myugen;
   Limiter.limit();
}

you're declaring a static ugen, but then you assign to this ugen a none static ugen. therefore the ugen (myugen) is no more static and no more accesible for every shred.

i made a test with two different shreds:
1st shred plays a simple sine wave over the myugen.
2nd shred changes the gain of the myugen.
1st shred is not affected by this change.

if you want to connect multiple ugens from different shreds to the same instance of myugen, you need to create a never ending shred as i posted above:
Code:

//never ending shred
Limiter l;
new Dyno @=> l.myugen;
l.myugen => dac;
while (true)
{
    10::minute => now;
}

//another shred with sound
//note that you don't need to instanciate Limiter again!
SinOsc s => Limiter.myugen;
// and so on


jassas
/moudi
Back to top
View user's profile Send private message Visit poster's website
Dr. Spankenstein



Joined: Mar 03, 2007
Posts: 136
Location: Cambridge
Audio files: 1

PostPosted: Sat Jan 05, 2008 8:15 am    Post subject: Reply with quote  Mark this post and the followings unread

O.K. I think I understand but how would this work with something simple like an integer?

For example if I were to have the Public Class in a seperate Shred on an infinite loop how could I reference it?

Code to be run:

Code:


Machine.add( "PublicClass.txt" ) => int cutter2;
// I cant find a way to instantiate the public class or reference it?
// X x;
<<<X>>>;
10::second => now;



Public Class looks like:

Code:


public class X
{
   int A;
   public void setA(int value)
   {
      value => A;
   }
   public int returnA()
   {
      return A;
   }
   while (true)
   {
         10::minute => now;
   }
}



I've absolutely no doubt what you are saying is correct but when I try and put it into practice it doesnt work out as planned Embarassed ?!

I'm guessing this way seperate shreds will be able to communicate with each other via another shred on which the public class runs on a infinite time loop?

Thanks for your time,

Rhys
Back to top
View user's profile Send private message
moudi



Joined: Oct 07, 2006
Posts: 58
Location: Bern Switzerland

PostPosted: Sat Jan 05, 2008 11:23 am    Post subject: Reply with quote  Mark this post and the followings unread

Hi Rhys

first of all, a public class (with or without static data) gets loaded by a shred into the vm and is from this point on accessible for all shreds. (as long as the vm is running).

if you're in need for a static int (or all other kinds of primitive types) it's another case, because you're able to instanciate them directly in your class. the "hack" with the never ending shred is only needed, because you aren't able to instanciate static ugens directly in the class.

i made a little example (a master gain) for you:
1. load the MasterGain.ck
in this shred is only the public class. the shred will immediately terminate after you loaded it.
2. load the NeverendingShred.ck
in this shred, the public ugen will be initialised and the shred runs forever (as long the vm survives).
3. load Shred1.ck
there's a simple sine wave routed to the public ugen and played for 2 minutes.
4. load Shred2.ck
the gain value of the public ugen will be changed every 2 seconds

good luck
/moudi


MasterGain.zip
 Description:

Download
 Filename:  MasterGain.zip
 Filesize:  672 Bytes
 Downloaded:  22 Time(s)

Back to top
View user's profile Send private message Visit poster's website
Dr. Spankenstein



Joined: Mar 03, 2007
Posts: 136
Location: Cambridge
Audio files: 1

PostPosted: Sat Feb 02, 2008 4:43 pm    Post subject: Reply with quote  Mark this post and the followings unread

Thanks for taking the time to upload the Master Gain code moudi.

It has now been implemented into my code and works perfectly. Not only that, I understand how it works! Very Happy

Rhys
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic Moderators: Kassen
Page 1 of 1 [12 Posts]
View unread posts
View new posts in the last week
Mark the topic unread :: View previous topic :: View next topic
 Forum index » DIY Hardware and Software » ChucK programming language
Jump to:  

You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum
Once You Know, You Newegg

Please support our site. If you click through and buy from
our affiliate partners, we earn a small commission.


Forum with support of Syndicator RSS
Powered by phpBB © 2001, 2005 phpBB Group
Copyright © 2003, 2004, 2005, 2006 and 2007 by electro-music.com