Pproto, Dictionary Collection and NRT

Hi,

I am trying to access a dictionary of samples when exporting my patterns with the method asScore using non-real-time synthesis.

I have used this code to create a sample library

(
~sample = Dictionary.new;
PathName ("path").entries.do{
	|subfolder|
	~sample.add(
		subfolder.folderName.asSymbol ->
		Array.fill(
			subfolder.entries.size,
			{
				|i|
				Buffer.readChannel(s,subfolder.entries[i].fullPath,channels:[0]);
			}
		);
	);
}
)

How would I access the samples from the above library in NRT following this process in the documentation?

(

a =Pproto({
	~newGroup = (type: \group).yield;
	~s1 = (type: \allocRead, path:"path" ).yield
},
[
	Pbind (
		\instrument,\grainBuf,
		\group, Pkey(\newGroup),
		\sndbuf, Pkey(\s1),
	)
]);

)

The eventType allocRead already performs the buffer allocating. Just for the sake of it, I tried using the variable ~samples as the path: in Pproto, but as I suspected that wouldn’t do the job. Would I have to make the dictionary inside of the makeFunction? Is there an available eventType that can handle this, or would I have to create one?

I have the added complexity of selecting the samples randomly from the dictionary. I am able to achieve this in real-time with

\sndbuf, Pfunc{~sample[\key][rand(~sample[\key].size)]},

and would need guidance on how to implement that within Pproto for NRT.

Thanks in advance,

You can do whatever initialization you need. If that initialization includes creating a dictionary, then yes, create the dictionary.

There won’t be a specific event type for every complex initialization sequence you might need. But you can yield multiple events.

The other catch you’re going to run into is that there currently isn’t an \allocReadChannel event type. So:

(
Event.addEventType(\allocReadChannel, {|server|
	var bufNum = ~bufNum;
	if(bufNum.isNil) {
		bufNum = ~bufNum = server.bufferAllocator.alloc;
	};
	~schedBundle.value(~lag, ~timingOffset, server,
		[\b_allocReadChannel, bufNum, ~path, ~firstFileFrame, ~numFrames, ~channels]
	);
});

EventTypesWithCleanup.cleanupTypes.put(\allocReadChannel, \freeBuffer);
)

(
p = Pproto(
	{
		var paths = (Platform.resourceDir +/+ "sounds/*.*").pathMatch;
		~samples = paths.collect { |path|
			// you can yield a Pproto-init event within a loop, no problem
			(type: \allocReadChannel, path: path, channels: [0]).yield;
		};
	},
	Pbind(
		\bufnum, Pfunc { |ev|
			ev[\samples][ev[\samples].size.rand]  // get the buffer-read event
			.at(\bufNum)  // get the bufnum from that event
		},
		// .... etc.
	).trace
).play;
)

p.stop;  // frees the buffers

Something like that. I haven’t tested with NRT.

hjh

Thank you for this! I have been playing around with it and can confirm it has no problem with NRT exporting. Also , thank you for anticipating the allocReadChannel. I was trying to solve that prior by editing the source code of allocRead to include ~channels but wasn’t having any luck.

Are there any resources on writing eventTypes? I need to achieve something similar for a buffer that stores custom envelopes for GrainBuf. I am going to build on your script and experiment from there.

Appreciate your help, all the best