|
|
Subject: writing primitives - msg#00067
List: audio.supercollider.devel
hello,
i'm trying to rewrite the following code as a ArrayedCollection c
primitive and got some questions.
(
~surroundMaxDimensions= 3;
~surroundMaxArea= 3;
~surroundings= Array.fill(~surroundMaxDimensions+1, {|i|
Array.fill(~surroundMaxArea+1, {|j|
var area;
area= Array.series(j*2+1, 0-j);
area.dup(i).allTuples;
});
});
)
(
~dimensions= 2;
~area= 1;
~surroundings[~dimensions][~area]+[50, 50];
)
the c code below works so and so. running it repeatedly, say for
benchmarking, gives random errors. it's like the lists my primitive
returns sometimes get garbled. {10000.do{[50, 50].surroundings(2, 1,
true).collect{|x| x+1}}}.bench
guess i'm not calling GCWrite properly somewhere.
also, is it possible to code this up as a plugin and not have to modify
sclang?
(sorry i'm not very good with c)
thanks,
F
int prArraySurroundings(struct VMGlobals *g, int numArgsPushed)
{
PyrSlot *a, *b, *c, *d, *slots2, *slots3, *slots10, *slots11;
//*slots1,
PyrObject *obj1, *obj2, *obj3, *obj10, *obj11;
int indexSize, newSize, i, j, worldDim, area;
double ww;
a = g->sp - 3;
b = g->sp - 2;
c = g->sp - 1;
d = g->sp; //boolean - exclude/include fix later
if (b->utag != tagInt) return errWrongType;
if (c->utag != tagInt) return errWrongType;
if (d->utag != tagTrue && d->utag != tagFalse) return errWrongType;
obj1 = a->uo;
worldDim = b->ui;
area = c->ui;
indexSize = area*2+1;
newSize = pow(indexSize, worldDim);
obj10 = (PyrObject*)instantiateObject(g->gc, obj1->classptr, worldDim,
false, true);
obj10->size = worldDim;
slots10 = obj10->slots;
obj11 = (PyrObject*)instantiateObject(g->gc, obj1->classptr,
indexSize, false, true);
obj11->size = indexSize;
slots11 = obj11->slots;
obj2 = (PyrObject*)instantiateObject(g->gc, obj1->classptr, newSize,
false, true);
obj2->size = newSize;
slots2 = obj2->slots;
//--build index array obj10
for (i=0; i<worldDim; ++i) {
for (j=0; j<indexSize; ++j) {
slots11[j].ucopy = 0-area+j;
}
SetObject(slots10+i, obj11);
}
//obj10 is here... [[-1, 0, 1]] or [[-1, 0, 1], [-1, 0, 1]] etc. for
area=1
//or [[-2, -1, 0, 1, 2]] or [[-2, -1, 0, 1, 2], [-2, -1, 0, 1, 2]]
etc. for area=2
//--stolen from prArrayAllTuples
for (i=0; i<newSize; ++i) {
int k = i;
obj3 = (PyrObject*)instantiateObject(g->gc, obj1->classptr, worldDim,
false, true);
obj3->size = worldDim;
slots3 = obj3->slots;
for (j=worldDim-1; j>=0; --j) {
PyrObject *obj4 = slots10[j].uo;
slots3[j].ucopy = obj4->slots[k%obj4->size].ucopy;
getIndexedDouble(obj1, j, &ww);
//commenting out this
slots3[j].ucopy += ww;
// and this line doesnt help either
g->gc->GCWrite(obj3, obj3); //why not (obj3,
obj4) here instead?
k /= obj4->size;
}
SetObject(obj2->slots+i, obj3);
g->gc->GCWrite(obj2, obj3);
}
a->uo = obj2;
return errNone;
}
#|
fredrikolofsson.com klippav.org musicalfieldsforever.com
|#
Was this page helpful?
Thread at a glance:
Previous Message by Date:
click to view message preview
Re: TimeLine Scheduler
On Jul 17, 2005, at 3:19 PM, Charlls Quarra wrote:
The
problem is when you play with big clouds of grains you
_have_ to have a bunch of nodes playing at a given
time, and there is no workaround this one, since you
cannot allow architecture limit possible compositions.
You can set the maximum number of nodes at server startup by using the
server options. There is a maxNodes parameter. That's documented in the
Server-Architecture helpfile.
hjh
: H. James Harkins
: jamshark70-n2XjBy9Frl0FLkkUnhLBSV6hYfS7NtTn@xxxxxxxxxxxxxxxx
: http://www.dewdrop-world.net
.::!:.:.......:.::........:..!.::.::...:..:...:.:.:.:..:
"Come said the Muse,
Sing me a song no poet has yet chanted,
Sing me the universal." -- Whitman
Next Message by Date:
click to view message preview
Re: TimeLine Scheduler
On Jul 17, 2005, at 12:19 PM, Charlls Quarra wrote:
Note that im cool with scheduling events ahead of
time, more time ahead one can schedule the better.
I think you missed the point.
The
problem is when you play with big clouds of grains you
_have_ to have a bunch of nodes playing at a given
time, and there is no workaround this one,
Anything that can be scheduled all at once can be scheduled
incrementally. For a real time system incremental scheduling is
necessary.
since you
cannot allow architecture limit possible compositions.
The problem you are having is not an architecture limit, it is that
you are using the architecture in a way that cannot be made real time.
Previous Message by Thread:
click to view message preview
Phasor bug redux
On 13 Jun 2005, at 19:14, Scott Wilson wrote:
On 13 Jun 2005, at 01:24, Joshua Parmenter wrote:
Hmmm:
<x-tad-smaller>380.4 * 44100; // approx secs times sample rate</x-tad-smaller>
<x-tad-smaller>16775640</x-tad-smaller>
<x-tad-smaller>2.pow(24)</x-tad-smaller>
<x-tad-smaller>16777216</x-tad-smaller>
<x-tad-smaller>stops at 2 to the 24th!</x-tad-smaller>
<x-tad-smaller>Josh</x-tad-smaller>
You're right. This demonstrates the problem more succinctly:
<x-tad-smaller>'/tr'</x-tad-smaller><x-tad-smaller>,{ </x-tad-smaller><x-tad-smaller>arg</x-tad-smaller><x-tad-smaller> time,responder,msg;
[msg.last, (msg.last * s.sampleRate.reciprocal).asTimeString].postln;
}).add;
x = SynthDef(\phasorPing, { </x-tad-smaller><x-tad-smaller>arg</x-tad-smaller><x-tad-smaller> updateRate = 0.1;
</x-tad-smaller><x-tad-smaller>var</x-tad-smaller><x-tad-smaller> phasor;
phasor = </x-tad-smaller><x-tad-smaller>Phasor</x-tad-smaller><x-tad-smaller>.ar(0, </x-tad-smaller><x-tad-smaller>1</x-tad-smaller><x-tad-smaller>, 0, </x-tad-smaller><x-tad-smaller>SampleRate.ir * 600</x-tad-smaller><x-tad-smaller>);
</x-tad-smaller><x-tad-smaller>Impulse</x-tad-smaller><x-tad-smaller>.kr(updateRate.reciprocal), </x-tad-smaller><x-tad-smaller>1</x-tad-smaller><x-tad-smaller>, phasor);
}).play
</x-tad-smaller>
It works differently for different rates though at rate 2 it stops at 12:40.8 or 2 to the 25th!!
I still haven't found the solution to this, but I think I found another bug in Phasor. The last line in Phasor_Ctor needs to be changed from
ZOUT0(0) = unit->mLevel = 0.f;
to
ZOUT0(0) = unit->mLevel = ZIN0(2);
or else when you get into the loop sc_wrap will set the initial output value incorrectly.
I think this is right and my tests seem to confirm it, but I'm starting to get a headache from trying to sort this out, so can someone else take a look and confirm before I commit it?
Thanks,
S.
_______________________________________________
sc-dev mailing list
sc-dev-Ayv8T2snMLBt9CRQqspbbg@xxxxxxxxxxxxxxxx
http://www.create.ucsb.edu/mailman/listinfo/sc-dev
Next Message by Thread:
click to view message preview
Re: writing primitives
rewrote it and think the problem was that i didn't use
*sizeof(PyrObject) for the output array init size. now works and i'm
happy but still confused when GCWrite supposed to be called. am i
generating something that should be cleaned up here?
int prArraySurroundings(struct VMGlobals *g, int numArgsPushed)
{
PyrSlot *a, *b, *c, *d, *areaArraySlots, *indexArraySlots,
*outArraySlots;
PyrObject *obj, *areaArray, *indexArray, *outArray;
int areaSize, outSize, i, j, worldDim, area;
double w;
a = g->sp - 3; //list
b = g->sp - 2; //worldDim
c = g->sp - 1; //area
d = g->sp; //boolean - exclude/include fix later
if (b->utag != tagInt) return errWrongType;
if (c->utag != tagInt) return errWrongType;
if (d->utag != tagTrue && d->utag != tagFalse) return errWrongType;
obj = a->uo;
worldDim = b->ui;
area = c->ui;
areaSize = area*2+1;
outSize = pow(areaSize, worldDim);
areaArray = newPyrArray(g->gc, areaSize, 0, true);
areaArraySlots = areaArray->slots;
areaArray->size = areaSize;
indexArray = newPyrArray(g->gc, worldDim, 0, true);
indexArraySlots = indexArray->slots;
indexArray->size = worldDim;
outArray = newPyrArray(g->gc, outSize*sizeof(PyrObject), 0, true);
outArraySlots = outArray->slots;
outArray->size = outSize;
//--build index array
for (i=0; i<areaSize; ++i) {
areaArraySlots[i].ucopy = 0-area+i;
}
for (i=0; i<worldDim; ++i) {
SetObject(indexArraySlots+i, areaArray);
}
//indexArray is here... [[-1, 0, 1]] or [[-1, 0, 1], [-1, 0, 1]] etc.
for area=1
//or [[-2, -1, 0, 1, 2]] or [[-2, -1, 0, 1, 2], [-2, -1, 0, 1, 2]]
etc. for area=2
//--all tuples
for (i=0; i<outSize; ++i) {
int k = i;
PyrObject *tempArray = newPyrArray(g->gc, worldDim, 0, true);
PyrSlot *tempArraySlots = tempArray->slots;
tempArray->size = worldDim;
for (j=worldDim-1; j>=0; --j) {
tempArraySlots[j].ucopy =
areaArraySlots[k%areaSize].ucopy;
getIndexedDouble(obj, j, &w);
tempArraySlots[j].ucopy += w;
k /= areaSize;
}
SetObject(outArraySlots+i, tempArray);
}
a->uo = outArray;
return errNone;
}
On 18.07.2005, at 14:17, Fredrik Olofsson wrote:
hello,
i'm trying to rewrite the following code as a ArrayedCollection c
primitive and got some questions.
(
~surroundMaxDimensions= 3;
~surroundMaxArea= 3;
~surroundings= Array.fill(~surroundMaxDimensions+1, {|i|
Array.fill(~surroundMaxArea+1, {|j|
var area;
area= Array.series(j*2+1, 0-j);
area.dup(i).allTuples;
});
});
)
(
~dimensions= 2;
~area= 1;
~surroundings[~dimensions][~area]+[50, 50];
)
#|
fredrikolofsson.com klippav.org musicalfieldsforever.com
|#
|
|