[linux-audio-dev] more on XAP Virtual Voice ID system

Tim Hockin thockin at hockin.org
Thu Jan 9 17:56:01 UTC 2003


> > I personally find this notion bizarre and counter-intuitive.  The
> > idea that the note is turned on by some random control is just
> > awkward.  I'm willing to concede it, but I just want to be on the
> > record that I find it bizarre.

> The way I see it, this "random control" that triggers a note is 
> equivalent to MIDI NoteOn. It can even be a standardized NOTE control 
> that all synths must respond to, one way or another.

OK - in my own notes I had been referring to it as the VOICE control.  You
send the VOICE control a VOICE_ON message and a VOICE_OFF message, or
simpler send 0 and 1.

> > comprehend, and more consistent. I want to toss MIDI, but not
> > where the convention makes things easy to understand.  I think that
> > explaining the idea that a voice is created but not 'on' until the
> > instrument decides is going to confuse people.  Over engineered. 
> 
> I think the alternative would render continous control synths even 
> more confusing. "Why do I have to send a VOICE_ON to make the synth 
> work at all?"

> Anyway, it's really an implementation issue. Just don't mention it in 
> the API docs. Just say that the NOTE control corresponds to MIDI 
> NoteOn/Off. Problem solved!

So stroking the NOTE control in your mind is *identical* to sending a 1 to
the VOICE control in my mind.

> > The plugin CAN use the VVID table to store flags about the voice,
> > as you suggested.  I just want to point out that this is
> > essentially the same as the plugin communicating to the host about
> > voices, just more passively.
> 
> Only the host can't really make any sense of the data.

If flags are standardized, it can.  Int32:  0 = unused, +ve = plugin owned,
-ve = special meaning.

> > It seems useful.
> 
> Not really, because of the latency, the polling requirement and the
> coarse timing.

When does the host allocate from the VVID list?  Between blocks.  As long as
a synth flags or releases a VVID during it's block, the host benefits from
it.  The host has to keep a list of which VVIDs it still is working with,
right?

> > If the plugin can flag VVID table entries as released, the host can
> > have a better idea of which VVIDs it can reuse.
> 
> Why would this matter? Again, the host does *not* do physical voice 
> management.
> 
> You can reuse a VVID at any time, because *you* know whether or not 
> you'll need it again. The synth just doesn't care, as all it will 

right, but if you hit the ned of the list and loop back to the start, you
need to find the next VVID that is not in use by the HOST.  That can include
VVIDs that have ended spontaneously (again, hihat sample or whatever).  The
host just needs to discard any currently queued events for that (expired)
VVID.  The plugin is already ignoreing them.

> > > This is where the confusion/disagreement is, I think: I don't
> > > think of this event as "INIT_START", but rather as
> > > "CONTEXT_START". I don't see the need for a specific "init" part
> > > of the lifetime of a context. Initialization ends whenever the
> > > synth decides to start playing instead of just tracking controls.
> >
> > Right - this is the bit I find insane.  From the user perspective: 
> > I want to start a note.  Not whenever you feel like it.  Now.  Here
> > are the non-default control values for this voice.  Anything I did
> > not send you, assume the default.  Go.
> 
> So, bowed string instruments, wind instruments and the like are 
> insane designs? :-)

No, they just might not have init params.  The voice is started when the bow
contacts the string.

> A bowed string instrument is "triggered" by the bow pressure and 
> speed exceeding certain levels; not directly by the player thinking 

Disagree.  SOUND is triggered by pressure/velocity.  The instrument is ready
as soon as bow contacts the string.

> > The difference comes when the host sends the 'magic' start-voice
> > control too soon.
> >
> > Assume a synth with a bunch of init-latched controls.
> > Assume velocity is the 'magic trigger'.
> > time0: Host sends VOICE_START/ALLOC/whatever
> > time0: Host sends controls A, B, C  (latched, but no effect from
> > the synth) time0: Host sends control VELOCITY (host activates
> > voice)
> > time0: Host sends controls D, E, F (ignored - they are
> > init-latched, and init is over!)
> >
> > Do you see the problem?
> 
> No, I see a host sending continous control data to an init-latched 
> synth. This is nothing that an API can fix automatically.

Ok, let me make it more clear.  Again, same example.  The host wants to send 
7 parameters to the Note-on.  It sends 3 then VELOCITY.  But as soon as
VELOCITY is received 'init-time' is over.  This is bad.  The host has to
know which control ends init time.  Thus the NOTE/VOICE control we seem to
be agreeing on.

> Yes, it has to be triggered by a standardized control, so hosts 
> and/or users will know how to hook synths up with sequencers, 
> controllers and other senders.

Precisely.

> If it has no voice controls, there will be no VVIDs. You can still 
> allocate and use one if you don't want to special case this, though. 
> Sending voice control events to channel control inputs is safe, since 
> the receiver will just ignore the 'vvid' field of events.

I think that if it wants to be a synth, it understands VVIDS.  It doesn't
have to DO anything with them, but it needs to be aware.  And the NOTE/VOICE
starter is a voice-control, so any Instrument MUST have that.

> > > has killed the voice. Thus, no need for a "VOICE_END" or similar
> > > event either.
> >
> > The host still has to be able to end a voice, without starting a
> > new one.
> 
> Why? What does "end a voice" actually mean?

It means that the host wants this voice to stop.  If there is a release
phase, go to it.  If not, end this voice (in a plugin-dpecific way).
Without it, how do you enter the release phase?

> >From the sender POV:
> 	I'm done with this context, and won't send any more events
> 	referring to it's VVID.

No.  It means I want the sound on this voice to stop.  It implies the above,
too.  After a VOICE_OFF, no more events will be sent for this VVID.

> >From the synth POV:
> 	The voice assigned to this VVID is now silent and passive,

More, the VVID is done.  No more events for this VVID.  The reason that
VVID_ALLOC is needed at voice_start is because the host might never have
sent a VOICE_OFF.  Or maybe we can make it simpler:

Host turns the NOTE/VOICE on.
It can either turn the NOTE/VOICE off or DETACH it.  Here your detach name
makes more sense.  A step sequencer would turn a note on, then immediately
detach.

> assumed to be more special than it really is. NOTE/VOICE_ON/VOICE_OFF 
> is a gate control. What more do you need to say about it?

Only if you assume a voice lives forever, which is wasteful.  Besides that,
a gate that gets turned off and on and off and on does not restart a voice,
just mutes it temporarily.  Not pause, not restart - mute.

> > control. But until then we need a consistent way to handle
> > init-latched controls. Because they ARE special.  They all need to
> > be sent before the voice is activated.
> 
> Yes - just like you have to send MIDI Program Change *before* playing 
> notes. It's not really a continous control, but MIDI sequencers don't 
> special case it, since it's obvious enough that the user should say 
> what sound he/she wants *before* starting to play.

Well, you CAN change Program any time you like - it is not a per-voice
control.

> > YES!  The same as a VOICE_ON. or send a 1 to the VOICE control. 
> > Describe it how you will, it tastes like VOICE_ON.  Remember before
> > when I said I would concede this point?  I lied!  I might concede
> > VVIDs and give up on plugin-allocated VIDs, but this seems more and
> > more right, and you yourself talked me back into it.
> 
> Well, then we can probably conclude that most of this is a matter of 
> terminology confusion. :-)

MOSTLY.  We still have agree on the problem of init- and release-latched
controls. See below.

> Either way, what I'm trying to figure out is a way to have both 
> note-on latched and continous control synths do sensible things even 
> if the sender doesn't know which type it's dealing with.

Of course.  See below again :)

> > I don't like
> > that.  Perhaps release velocity is a different control.
> 
> Yes, I think so.

Release velocity is a release-latched control.

Control set events can have three forms (a control can handle any
combination of them by flags or something):

1) events that apply to the starting of the voice
2) events that apply to an active voice
3) events that apply to the ending of an event

Controls which are init-latched ONLY (e.g. velocity for a velo map) need to be
grouped together before the voice is started.

Controls which are release-latched ONLY (e.g. release velocity) need to be
grouped together before the voice is ended.

We need to standardize the way of sending these.

Idea 1:  as we've been discussing, have some window during which events are
KNOWN to be init (or release).
 -- INIT:
      send VOICE_INIT(new_vvid)  /* declare a vvid */
      send SET(new_vvid, ctrl) /* set controls for init */
      send VOICE_ON(new_vvid) /* start the vvid */
 -- RELEASE:
      send VOICE_DEINIT(vvid) /* going into release */
      send SET(vvid, ctrl) /* set controls for release */
      send VOICE_OFF(vvid) /* do release */


Idea 2:  similar to idea 1, but less explicit.
 -- INIT:
      send SET(new_vvid, ctrl) /* implicitly creates a voice */
      send VOICE_ON(new_vvid) /* start the vvid */
 -- RELEASE:
      send SET(new_vvid, ctrl) /* send with time X */
      send VOICE_OFF(vvid) /* also time X - plug 'knows' it was for release */


Idea 3:  different events for init/release/active sets.


Of those, I like #1.  It feels familiar.  You declare a variable before you
use it, and you unlink something before you kill it.

#2 init is ok.  I don't like the release.  #3 is not pretty.



we're gettig there...
Tim



More information about the Linux-audio-dev mailing list