Re: cpuload and ... voice scavenging!

From: Robin Davies (rerdavies@msn.com)
Date: Tue Jun 06 2000 - 19:44:21 EDT


Hmmm. I posted a response to this, but it seems to have gone missing.

Sfx implements cpuload, but I rather suspect that if one were to use the
results of cpuload to gracefully degrade you wouldn't get what you expected
at all.

The real problem with cpuload is that even in Sfx the results depend heavily
on the configuration of the decoder. Sfx provides tunable settings for use
when doing realtime interactive decoding (soon, soon) from a MIDI port.
There are really two "real-time" applications; one is realtime streaming
(e.g. all data coming from a well buffered TCP/IP stream), and the the other
is realtime interactive where note data comes from a connected MIDI input
port. The latter is much more demanding since buffering ahead must be
reduced as much as possible. Also the decoder needs to process data in much
smaller chunks regardless of the amount of pre-buffering in order to
maintain even response to input. In streaming mode, Sfx generates 20ms of
data at a time, buffered ahead about 120 ms (actually 240ms of buffer,
chasing the point 120ms after the DMA read point); in interactive mode Sfx
would ideally process 1 to 2 ms of data at a time, buffered ahead not more
than 50ms (and would need a DirectSound native driver to do it). In the
latter mode, getting pre-empted by an interrupt or higher-priority task can
easily cost 400 or 500% of a scheduling timeslot. Heavy screen or disk
activity can bump the cpuload to 1600% or higher. For instance, if the
scheduling task gets pre-empted by processing of a mouse interrupt the mouse
interrupt handler may actually take 1 or 2 ms to complete, causing cpuload
to report 200% even if the scheduler's load is minimal. Windows does
provide methods for monitoring thread-load specifically, but, unfortunately,
they are different between different versions of WinXX, and they are
relatively costly compared to a 1ms timeslot, and are therefore not used by
Sfx.

Even when running with 20ms scheduling slots, cpuload consumed by other
threads or interrupts can be significant. Unfortunately... beleive it or
not... <eyeroll> running the synthesis thread at realtime priority (a very
dangerous thing on WinXX) appears to starve the DirectSound thread that
keeps audio buffer DMA pointers up-to-date on my soundcard driver. I get
dropouts when I do this.

I've given some thought to trying to debounce the CPUload a little, or
perhaps average it over a longer period, but I'm fairly certain any
reasonable solution is going to be a compromise of some sort.

Sfx *does* perform voice scavenging, although this is, again, a
user-configurable parameter, and Sfx relies on non-standard opcodes to make
use of this feature truly sensible. (e.g. an opcode that assigns a voice
weight to an instrument for the purposes of calculating total voice load).

The SAOL standard currently makes implicit allowances for voice scavening
(e.g. the presence of the high-priority bit on SASL events) but doesn't
provide any explicit control over voice scavenging algorithms implement by a
decoder. I've tried writing my own voice scavenging opcodes in pure SAOL,
but it's not pretty. SAOL is very weak on data-types, and a reasonable
voice-scavenging algorithm would need at least two linked lists, and much
better per-MIDI-channel communications between instrument instances in order
to deal with duplicate notes.

I'm actually a little concerned about this. Voice-scavening is quite an
important feature for software synthesizers. Many off-the-shelf SoundFont/2
(and presumably DLS-2) patches have very long release times: a stock piano
patch has release times (from note-off) of about 4 seconds; several of the
GM percussion voices have release times in the 8 second range. Usually
synthesizers scavenge in order to terminate those notes that are hanging on.
The effect is usually not noticeable because if the synth needs to scavenge,
there's already plenty of audio activity so nobody's going to notice a piano
note release that gets cut short at -50db instead of -96db.

The other scavening mechanism that Sfx implements that may or may not be
nonstandard is that duplicate midi notes are hard-terminated without
executing the release envelope. This is not done for SASL notes, but was
deemed neccessary for MIDI.

A rough estimate of the effect that scavening has... Consider ELPELE.MID. It
has one single piano channel, and the piano is presumably played with not
more than 10 fingers at a time.

Estimated peak voice instances with no scavenging: 115 voice instances.
Estimated peak voice instances with duplicate MIDI note scavengening: 60.
Minimum acceptable voice limit with full scavenging: less than 20.

For what it's worth, the last time I ran elpelele on Sfx I was able to run
about 80 elpelele voices with reverb (which is good for about 20% of CPU
load as written).

Admittedly elpelele.saol's release code could be improved a bit; however the
5 second release time for an elpelele.saol piano instrument is entirely
inline with the 4 to 8 second release envelope of the EMU General Midi
SoundFont/2 piano patch.

Also remember, this is only one MIDI channel. Consider what happens if you
have 16 different instruments playing simultaneously on 16 channels. It's
going to be very common to have 32 active voices, but 100 or 200 voices very
far along in their release cycle.

Sfx's voice-scavenging extensions are documented at
http://www.angelfire.com/electronic/sfx/extensions.html .



This archive was generated by hypermail 2b29 : Mon Jan 28 2002 - 12:03:57 EST