[sdiy] Voice assignment algorithms
cheater cheater
cheater00 at gmail.com
Thu Mar 25 21:24:45 CET 2010
Hi Tom,
I think the most important thing to say here is: make technology work
for what you want, not the other way around. Voice assignment
algorithms are so simple that there's reeeeally no reason to optimize
them, or to only do the simplest ever voice assignment mode, when you
could be happy with something less simple (to not say complicated).
It's good that you're prototyping on the PC, of course C is much
better for working out ideas than ASM, I find Python the best for that
myself because of speed of development.
I think a polyphonic note stealing algorithm with memory is possible
(in the single-voice case it degrades to mono legato), below is a
description of how it could work.
You need to implement a circular fixed-frame-size fixed-length stack
for the notes pressed in order of arrival and a fixed length list for
voice/note info. The circular stack holds info about the note number
and info whether that note is being voiced by something right now (1)
or if it's stolen (0). The voice list contains the note number being
played by the voice currently.
When a note on comes in, you scan the circular stack and remove all
occurrences of that note, then add it to the end of the circular
stack. You also do this when there are more notes than voices in the
stack. Then you find a free voice or the last voice that had a note
assigned and you assign the note to that voice. You keep that in a
separate list; this separates the notion of the *first note to come
in* and the *first voice to have been assigned a note*
When a note off is pressed you first scan the voice list to find that
note number.
If you don't find that note number, you scan the circular stack for
that note number and you remove all occurrences (the amount will be at
most 1) of that note info from the circular stack and then you need to
concatenate the stack to put the hole 'at the end' of the circular
stack (that's a bit costly).
If you do find that note number, you first remove the note from the
circular stack as said above, and then you scan the circular stack for
the starting with the end of the stack (the latest node added) and
going backwards until you find a note that was 'stolen' (that gives
you an oldest-stolen-first so FIFO behavior). Then you copy the note
number found in that circular stack frame, to the voice list. If you
don't find anything by scanning the circular stack backwards, it means
this voice becomes free.
I think if you analyze this idea you will find it can work for the
single-voice situation too. Whether envelopes are retriggered on
legato or not is a setting independent of voice assignment logic. This
way you can also have poly legato.
The circular stack needs to be fixed-length to ensure you don't get an
overflow. When the size is exceeded, the stack wraps around to the
beginning and starts eating itself. You need to keep two pointers: one
to the end of the stack and one to the beginning of the stack.
------------------
On another note, don't bother implementing voice logic in ASM, unless
you like the "SM" part of it. It's much more important that you
develop quickly and are able to quickly come in and make changes
later. The time saved will definitely offset any price you could have
to pay for a super powerful 0.001 MIPS voice logic processor.
C is quick enough, pretty much as quick as tape-based programming can
be, unless the implementation sucks or the hardware is way
underpowered. If you really wanted to press for performance, then you
can implement highest- or lowest-note-priority with just AND gates and
a lot of wire, or a tiny FPGA. In fact, I think you could implement
any classical note logic this way!
D.
On Thu, Mar 25, 2010 at 20:43, Tom Wiltshire <tom at electricdruid.net> wrote:
>
> On 25 Mar 2010, at 19:12, ASSI wrote:
>
>> Hi Tom,
>>
>> On Thursday 25 March 2010, Tom Wiltshire wrote:
>>>
>>> The system I've got currently stores two stacks of voices; the free
>>> stack and the busy stack.
>>
>> [...]
>>
>> I wouldn't call this a stack, but rather a FIFO or a linked list,
>> depending on implementation.
>
> Yes, that's probably a much more accurate name for it. It is a linked list.
>
>> Unless I misunderstood, there will be a
>> good deal of pointer chasing to implement a least recently used voice
>> allocation strategy.
>
> The list also stores pointers to the first and last voices in the list, so
> finding
> the least recently used (oldest) voice is just a question of looking at the
> right pointer.
>
>> This linked list stuff is very flexible in that
>> regard, but uses memory and cycles and god help you if you make an
>> implementation error on some fringe case...
>
> You're not wrong there! That's why I'm playing with the algorithm on my
> laptop now
> before I go anywhere near a processor.
>
>> Something that is to the best of my
>> knowledge sadly neglected in software voice assigners are duophonic
>> voice modes, for instance.
>
> And I'm afraid I'm probably going to join the list. If I do duophonic, it'll
> just be the
> two-voice case of the general polyphonic scheme, without any of the other
> options you could do if you only considered two voices.
>
> I think I agree with both you and Scott that best way is just to separate
> monophonic
> and polyphonic assignment algorithms. There's too many differences to do
> them justice
> with one piece of code.
>
> Thanks for your thoughts,
> Tom
>
> _______________________________________________
> Synth-diy mailing list
> Synth-diy at dropmix.xs4all.nl
> http://dropmix.xs4all.nl/mailman/listinfo/synth-diy
>
More information about the Synth-diy
mailing list