process a sound with a UGen inside of a loop in supercollider - iteration

began using supercollider, read through the tutorials and practiced a bit but i can't seem to make this work. how can i process an input N times in a row ?
basically, i want build a synth to crush a sound source by running it through a distortion N times. i've tried many things, but what i want to do is basically:
// distortion function
dfunc = {
arg inp; // input
AnalogVintageDistortion.ar(
inp, 1, 2.5, 20.dbamp, 10.dbamp, 200, 10
)};
// taking an input and running a 1st distortion
in = In.ar(input, 1);
dout = dfunc.value(in);
// rerunning the distorsion 10 times
10.do({
dout = dfunc.value(dout);
});
basically, it would be a quick equivalent of doing:
dout = AnalogVintageDistorsion.ar(
AnalogVintageDistorsion.ar(
AnalogVintageDistorsion.ar(
dout
)
)
);
i'm coming from python, where this result would be achieved by:
for i in range(10):
dout = dfunc(dout)
thanks in advance !!

Related

How to call a multidimensional prediction on a keras model with a javascript api

I have trained a model based on the keras lstm_text_generation example, and I would like to perform predictions on this model with front-end javascript.
First I tried using keras.js, however that only takes 1-dimensional Float32Array vectors in it's prediction function so I am unable to use it since the lstm_text_generation example uses a multidimensional array of shape (1, maxlen, len(chars)).
Next I tried using tensorflow.js, using this tutorial to port my keras model to a model.json file. Everything seems to work fine, up to the point where I perform the actual prediction where it freezes and gives me the warning Orthogonal initializer is being called on a matrix with more than 2000 (65536) elements: Slowness may result.
I noticed that in many of the tensorflow.js examples, people convert their arrays to tensor2d, but I did this and it had no effect on the performance of my code.
For anyone curious, here is the javascript code I wrote...
async function predict_from_model() {
const model = await tf.loadModel('https://raw.githubusercontent.com/98mprice/death-grips-lyrics-generator/master/model.json');
try {
var seed = "test test test test test test test test"
var maxlen = 40
for (var i = 0; i < 1; i++) {
var x_pred = nj.zeros([1, maxlen, 61]).tolist()
for (var j = 0; j < seed.length; j++) {
x_pred[0][j][char_indices[seed.charAt(j)]] = 1
}
console.log("about to predict")
const preds = model.predict(x_pred) //gets stuck here
console.log("prediction done")
}
} catch (err) {
// handle error
}
}
...to perform the same function as on_epoch_end() in the lstm_text_generation.py example. The output of x_pred is the same in both python and javascript code, so I don't think the issue lies there.
I think I need to make some optimisations in tensorflow.js, but I'm not sure what. Does anyone know how to fix any of my issues above and/or any other javascript library that would work for my purpose?
x_pred needs to be a tensor, the simplest way to create a tensor with custom values is tf.buffer, which can be initialized with a TypedArray or can be modified using .set() which would be better for you, because most of your values are 0 and buffer are filled with zeros by default. And to create a tensor out of a buffer just use .toTensor();
So it would something like this:
var x_pred = tf.buffer([1, maxlen, 61]);
for (var j = 0; j < seed.length; j++) {
x_pred.set(1, 0, j, char_indices[seed.charAt(j)]);
}
console.log("about to predict")
const preds = model.predict(x_pred.toTensor());
console.log("prediction done")

game maker random cave generation

I want to make a cave explorer game in game maker 8.0.
I've made a block object and an generator But I'm stuck. Here is my code for the generator
var r;
r = random_range(0, 1);
repeat(room_width/16) {
repeat(room_height/16) {
if (r == 1) {
instance_create(x, y, obj_block)
}
y += 16;
}
x += 16;
}
now i always get a blank frame
You need to use irandom(1) so you get an integer. You also should put it inside the loop so it generates a new value each time.
In the second statement, you are generating a random real value and storing it in r. What you actually require is choosing one of the two values. I recommend that you use the function choose(...) for this. Here goes the corrected statement:
r = choose(0,1); //Choose either 0 or 1 and store it in r
Also, move the above statement to the inner loop. (Because you want to decide whether you want to place a block at the said (x,y) location at every spot, right?)
Also, I recommend that you substitute sprite_width and sprite_height instead of using the value 16 directly, so that any changes you make to the sprite will adjust the resulting layout of the blocks accordingly.
Here is the code with corrections:
var r;
repeat(room_width/sprite_width) {
repeat(room_height/sprite_height) {
r = choose(0, 1);
if (r == 1)
instance_create(x, y, obj_block);
y += sprite_height;
}
x += sprite_width;
}
That should work. I hope that helps!
Looks like you are only creating a instance if r==1. Shouldn't you create a instance every time?
Variable assignment r = random_range(0, 1); is outside the loop. Therefore performed only once before starting the loop.
random_range(0, 1) returns a random real number between 0 and 1 (not integer!). But you have if (r == 1) - the probability of getting 1 is a very small.
as example:
repeat(room_width/16) {
repeat(room_height/16) {
if (irandom(1)) {
instance_create(x, y, obj_block)
}
y += 16;
}
x += 16;
}
Here's a possible, maybe even better solution:
length = room_width/16;
height = room_height/16;
for(xx = 0; xx < length; xx+=1)
{
for(yy = 0; yy < height; yy+=1)
{
if choose(0, 1) = 1 {
instance_create(xx*16, yy*16, obj_block); }
}
}
if you want random caves, you should probably delete random sections of those blocks,
not just single ones.
For bonus points, you could use a seed value for the random cave generation. You can also have a pathway random generation that will have a guaranteed path to the finish with random openings and fake paths that generate randomly from that path. Then you can fill in the extra spaces with other random pieces.
But in regards to your code, you must redefine the random number each time you are placing a block, which is why all of them are the same. It should be called inside of the loops, and should be an integer instead of a decimal value.
Problem is on the first line, you need to put r = something in the for cycle

Sorting float array in fragment shader without dynamic branching in OpenGL ES (iPad)

We have a somewhat complicated fragment shader, which we cannot split into smaller shaders.
One of the thing the shader does is calculate the distance of the fragment/pixel to 7 other points, and find the two nearest ones.
On the iPad, we are having huge performance problems with this part of the code, and Instruments tells us the bottleneck is the shader code which leads to dynamic branches in the GPU.
We sacrificed readability and tried several code changes to avoid these dynamic branches:
Changed the loop so that it's not really a loop, but a repeating series of instructions.
Simplified the code so that it contains only very simple if-like instructions.
This is the 'simplest' version of the code we came up with:
bool isLowest;
float currentDistance, lowestDistance, newLowest;
lowestDistance = distances[1];
int indexOfLowest = 1, newIndexOfLowest;
// 'loop' for index 2
currentDistance = distances[2];
isLowest = currentDistance < lowestDistance;
newLowest = isLowest ? currentDistance : lowestDistance;
lowestDistance = newLowest;
newIndexOfLowest = isLowest ? 2 : indexOfLowest; // BAD LINE
indexOfLowest = newIndexOfLowest;
// 'loop' for index 3
currentDistance = distances[3];
isLowest = currentDistance < lowestDistance;
newLowest = isLowest ? currentDistance : lowestDistance;
lowestDistance = newLowest;
newIndexOfLowest = isLowest ? 3 : indexOfLowest; // BAD LINE
indexOfLowest = newIndexOfLowest;
// etc. until index 8
As you can see, the code finds the index of the lowest distance. In our opinion, this code can be executed without dynamic branches. The last four lines of one 'loop' are just simple calculations, they are not real branches.
The problem is the second-last row in a 'loop, where indexOfLowest gets a new value:
newIndexOfLowest = isLowest ? 2 : indexOfLowest;
If we comment out that line, everything works fine on 60 FPS and Instruments doesn't report dynamic branches. But with this line, it's not more than 8 FPS.
How can we rewrite this code such that it does not cause dynamic branches in the GPU?
EDIT: Just updated the code to an even simpler version, which has the same problems. The old code had a for loop with fixed limits. But the problem is still there.
EDIT 2: We just analyzed the code using PowerVR's PVRShaderEditor (previously PVRUniSCoEditor), where it shows the expected GPU cycles per shader source code line. The line in question (BAD LINE in the code above) is shown with only 1-2 GPU cycles. The fact that this line causes dynamic branches which lead to huge performance problems is not mentioned. Any other ideas how we could debug this code, so we can understand why it's causing these branches?
We did it. Casting the bool to float (1.0 for true, 0.0 for false) was helpful here:
bool isLowest;
float currentDistance, lowestDistance, newLowest;
lowestDistance = distances[1];
int indexOfLowest = 1, newIndexOfLowest;
// 'loop' for index 2
currentDistance = distances[2];
isLowest = currentDistance < lowestDistance;
indexOfLowest = float(isLowest) * float(2 - indexOfLowest);
lowestDistance = isLowest ? currentDistance : lowestDistance;
// 'loop' for index 3
currentDistance = distances[3];
isLowest = currentDistance < lowestDistance;
indexOfLowest = float(isLowest) * float(3 - indexOfLowest);
lowestDistance = isLowest ? currentDistance : lowestDistance;
// etc. until index 8
This calculates the index of the lowest distance, without using dynamic branches.

openCV cvContourArea

I'm trying to use cvFindContours, which definitely seems like the way to go. I'm having a problem with getting the largest one. There is a function call cvContourArea, which suppose to get the area of a contour in a sequence. I'm having trouble with it.
int conNum = cvFindContours(outerbox, storage, &contours, sizeof(CvContour),CV_RETR_LIST,CV_CHAIN_APPROX_NONE,cvPoint(0, 0));
CvSeq* current_contour = contours;
double largestArea = 0;
CvSeq* largest_contour = NULL;
while (current_contour != NULL){
double area = fabs(cvContourArea(&storage,CV_WHOLE_SEQ, false));
if(area > largestArea){
largestArea = area;
largest_contour = current_contour;
}
current_contour = current_contour->h_next;
}
I tried replacing storage (in the cvContourArea) with contours, but same error keeps coming up no matter what:
OpenCV Error: Bad argument (Input array is not a valid matrix) in cvPointSeqFromMat, file /Volumes/ramdisk/opencv/OpenCV-2.2.0/modules/imgproc/src/utils.cpp, line 53
I googled and could hardly find example of cvContourArea that takes 3 arguments.. as if it's changed recently.. I want to loop thru the found contours and find the biggest one and after that draw it using the cvDrawContours method.. Thanks!
Try to change &storage to current_contour in the following statement.
Change
double area = fabs(cvContourArea(&storage,CV_WHOLE_SEQ, false));
to
double area = fabs(cvContourArea(current_contour,CV_WHOLE_SEQ, 0));

taking AudioBuffer samples

i am trying to take the audio buffer samples in real time( resolution of ms)
i am using this function, but it gives me error.
AudioBufferList *bufferList = NULL;
AudioBuffer audioBuffer = bufferList->mBuffers[0];
int bufferSize = audioBuffer.mDataByteSize / sizeof(SInt32);
SInt32 *frame = audioBuffer.mData;
SInt32 signalInput[22050];
for( int i=0; i<bufferSize; i++ )
{
SInt32 currentSample = frame[i];
*(signalInput +i) = currentSample;
NSLog(#"Total power was: %ld ",currentSample);
}
what am i doning wrong here ?
i only need to get the audio samples .i dont want 2 pages code(such as in the app doc)
thanks .
What you want is inconsistent with what you are trying to do. A NULL bufferlist can produce no samples.
You need the two+ pages of code to properly configure the Audio Session and the RemoteIO Audio Unit (etc.) in order to get what you are trying to get. Otherwise there are no samples. The phone won't even turn on audio recording or know how to set up the recording (there a bunches of options) before turning it on. Study the docs and deal with it.