[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [sc-users] automated buffer -- How's that get in there?!?



Hi James (why pretend anyone else is still reading -- this must be
annoying... sorry everyone!)

Not at all, I think it's entirely on topic and probably pretty educational.

This bit sets the watcher symbol to be universally recognized for use by
routines, etc.
~watcher = NodeWatcher.newFrom(s);

Yep. It's mostly for efficiency. You could do NodeWatcher.newFrom(s) every time but I think it's cleaner to do it once.

This bit uses the above nodewatcher to parse and categorize (and set?) the
state of the buffers in the pool.

~stateManager = { |buffer, node, endState = \ready|
        buffer.state = \busy; // don't let anyone else use this buffer
                // below is to make sure the state changes when the synth
stops
        ~watcher.register(node);
        Updater(node, { |node, flag|
                (flag == \n_end).if({
                        buffer.state = endState;
                });
                node.releaseDependants;
        });
};

Yep. It does set the buffer states ... buffer.state = \something

These are my fake filters for which I have working replacements whose names
must be registered for access in this global variable.  I assume that I
should register (send.(s)) the synths to the server before doing this, so
feasibly I'll have a list of synths that preceed the following.

Yes.

So this controls the playing and filtering of the soundfiles in buffers, in this case also controlling the recording process. The \recorder and \player synths would have to be registered previously with the filter synthdefs. In this case, you are using the weighted choose to record and play soundfiles
%25 of the time (each) and %50 to filter the SFs.

Yes.

  Could you describe what
is happening with the

 ~stateManager.value(buf1, node);

bit of code?

The ~stateManager environment variable holds a function whose job it is to handle the buffer states. When you send the "value" message to a function, it executes the function with the arguments in parentheses. Rather than copy and paste the state manager code, I write it once and call it in several places.

So, I dropped the above code into a file, added the pool definition at the beginning, dropped in a bunch of synths and after inserting some ')'s and '}'s places, everything registered with no errors. Of course, nothing works
because I have no sound files.  (and for other reasons, I'm sure)

I will need to record the sound files to the buffers myself, independantly from the above routine because the recordings will be time varying... that
is, I'll make them when I have to : D.

So, to do this, I'll need to register a recording synth def... something
like the following when I register the rest of my junk...

SynthDef(\recorder, { arg targetbufnum, outbus = 0;
         var sig = AudioIn.ar(1);
		RecordBuf.ar(sig, targetbufnum);
         	Out.ar(outbus, sig);
}).send(s);

(stole this bit and modified it so it won't work!  Impressive, no?)

What about it isn't working?

One issue is that the Task I wrote assumes that the synths will release themselves. Just add a line in there somewhere, it doesn't matter where (just not before the variable declaration):

Line.kr(0, 1, BufDur.kr(targetbufnum), doneAction: 2);

So the recording will last exactly as long as there is space in the buffer, and then will stop.

Then I'll need a way to parse the pool, etc, as with the routine.  I've
nabbed the '\recorder' bit of code from the above routine and deleated it so nothing is accidentally thrown into a buffer, and I've started a routine of my own to handle the recordings only it doesn't seem like a routine is the
best tool for the job.

Can you tell me if I'm making any sort of conceptual faux pas with the
"recorder" bit above?

I'm not clear on why the recorder needs to be in a separate routine, but there shouldn't be any harm in doing it that way.

In addition, are there methods you find useful for collecting information on activities?... IOW, to see if anything is working? (like the ~pool.post;
above, which told me nothing, but more useful!)

Usually what I do is insert debugging statements into the routine itself. Something like:

(
~rec = Routine({
        var buf1, buf2, node;
        n.do {
               buf1 = ~pool.select({ |b| b.state == \empty
}).tryPerform(\choose);
buf1.debug("buffer selection");
               buf1.notNil.if({
              node = Synth(\recorder, [\targetbufnum, buf1.buffer.bufnum]);
node.debug("started synth");
               ~stateManager.value(buf1, node);
                                });
                        }
	})
)

Also you might add one to the state manager so that you get a printed output when the Updater executes.

I must say that, despite my ongoing inability to grasp certain core concepts with the program, that I'm learning quite a bit, and having a blast! (when I'm not crying myself to sleep after bashing my face against my disgusting
300-pound CRT out of frustration)

Patience! SuperCollider is not easy to learn, but (for me at least) the power is worth it.

I know your site bio states that you received your PhD from Duke, did you study any of this sort of thing there? The "designing [your] own software
for live algorithmic composition and performace" seems like you have a
history in programming as well?

Actually, I didn't get into any of this until about a year-and-a-half after finishing. I taught myself programming when I was a kid (BASIC and Pascal in junior high and C in high school). I never took computer science classes so some of my code organization is quirky but I keep getting better.

The line about designing my own software is partly marketing puffery, but it's really true. Any time you write a piece in SuperCollider, you're writing your own music software. Maybe people think calling them "patches" is more modest, but I don't agree. Making a Max/PD patch is still programming.

hjh

: H. James Harkins
: jamshark70@xxxxxxxxxxxxxxxxx
: http://www.dewdrop-world.net
.::!:.:.......:.::........:..!.::.::...:..:...:.:.:.:..:

"Come said the Muse,
Sing me a song no poet has yet chanted,
Sing me the universal."  -- Whitman