Csound Csound-dev Csound-tekno Search About

Re: schedule, schedwhen - bug report

Date1999-08-22 14:46
Fromrasmus ekman
SubjectRe: schedule, schedwhen - bug report
richard bowers wrote:
> 
> I understand that the opcodes schedule and schedwhen will only operate once
> in a single call to the instrument containing them. Is that correct?

Yes. schedule only works at i-time and schedwhen has an internal
switch that is set to "off" after generating the event.

Note that these opcodes are rather buggy: 
First, they can not create deferred events (by setting i/kwhen > 0), 
so the events are always started immediately. Any attempt to defer 
events will give them wrong ringtime, namely i/kwhen + i/kdur, while 
the turnoff time will be correctly set to start time+dur, which means 
the instr will be around (at least) from generation time through to 
deferred time + dur (ie def.time + p3).

(Programmers note: As far as I can determine, there is no simple way 
of creating deferred events from an opcode context in Csound, so I 
wouldn't care to try to fix this feature, rather disallow it until 
the rest is working.)

Secondly, the generated events will not be turned off correctly,
but be left hanging, unless there has been some "real" score 
(or midi or line input) event in the meantime.

Prognotes: This is a complication in any Csound event generation from 
an opcode.  Event turnoff is not handled by kperf() (k-rate performance), 
but by playevents() (the score event scheduler, which calls kperf() 
to run until next score event). kperf() returns only for new events 
or for event turnoff occasions, but may be expired early by "realtime" 
(midi, midi file or line input) events. Search for the variable 
"sensType" in sources if you want to see how this works.

Both sched* ugens call schedofftim() to set the turnoff time for 
the generated event. The time is indeed set, but this is no help since 
kperf() as noted doesn't check for turnoff. It does happen to work 
for schedule since this opcode generates events at i-time, and so 
will have the turnoff logged in playevents() for free before the first 
k-cycle of the calling instr. 

My solution to this problem (yes, I've been working on and off for the
last few weeks to create an opcode to generate events at k-rate)
is to define a new "realtime" event, and do some changes to playevents()
and kperf() to have it handled. Not tested enough for publishing yet,
as I for one don't think that the compiler does all necessary QA...

Thirdly, since they were created by copying a fair chunk of Csound core
code (the insert() func.) and doing some changes to that (rather than 
setting up some scheme which involves calling this function), they are 
(and will keep getting) out of synch with changes in that code, specifically, 
I believe recent stuff like cpuprc and maxalloc will not work correctly 
for instr's that have had events generated by sched* ugens.

Finally, schedwhen shifts the arguments so that p4= p3, p5= intended p4 etc 
in the generated instrument. This one is trivial to fix (it has already 
been done for schedule at one time).


In conclusion, besides wondering what the point of these opcodes is, 
I'm curious as to whether they were tested _at_all_ before publishing?
(Usually I don't complain about stuff without trying to fix it, 
but after looking at them I simply don't like them, and think they 
should be taken out and sh (*ahem* deprecated and deleted)).

Demonstration: The below csd file should generate one 2.33 second beep
after 0.5 seconds, and one after 5 seconds (modulus k-precision). 
Just see what you get...

Regards,

	re


----------------------
schedbug.csd - demo some bugs in sched* opcodes
----------------------


;

;

sr = 22050
kr = 441
ksmps = 50
nchnls = 1

instr 1
	; Start i13 after .5 sec (not)
	schedule 13, .5, 2.33, 550, 0
endin

instr 2
	; Start i3 after 1 sec 
	;   Since this doesn't work, it starts after 4.0 instead of 5.0 secs
	; It should be turned off after 2.33 secs, but hangs until next score event
	schedwhen 1, 13, 1, 2.33, 440
endin

instr 13
	; itime is actual start time, p2 is the intended, 
	; and p4=p3, p5=p4 if started by schedwhen
	itime times    
	print itime, p2, p3, p4, p5

	; Since p4 won't always be correct, we set a start pitch here
	kpitch line 440, p3, p4
	; Now we're naughty to rub in the point: this linseg continues beyond p3
	; - but the error shows even if you remove the last ", .5, 20000" args
	kamp linseg 25000, p3-.1, 25000, .1, 0, .5, 20000
	ar oscili kamp, kpitch, 1
		out ar
endin



f1 0 4096 10 1

i1 0 3.5
i2 4 6
f0 10

e