Re: [LAD] Conciderations of Design

2011-11-13 Thread Harry van Haaren
David: Thanks for such insight & in-depth response. The points you've made
are being taking into concideration at the moment. "Polling" is indeed
probably the term I was looking for, but didn't come to mind.

I suppose I should have shed light on the "use-case" a touch more in my
initial question: Its for a live program where all processing is done in
blocks. So no need for sample accuracy or any of that, polling is the
winner :D

Re: Connection logic... I've not yet decided how to approach this.
Currently "state" is handled in each class, but this provides bigger
problems: every parameter change needs to be passed to that class, and the
way I have that implemented currently means about 6 function calls, and
lots of array access... hogs up JACK cpu time and is inefficient.

Thorsten: Intresting read, I don't think FRP is a route I'm going to take
at the moment, as it would null all work I have done so far... but it did
get me thinking in different ways :)

Jeff: Nice balance between performance & flexibility. As prev noted, its a
"block-processing" app, so I won't implement the audio rate controls. Never
the less, thanks for the tip!
___
Linux-audio-dev mailing list
Linux-audio-dev@lists.linuxaudio.org
http://lists.linuxaudio.org/listinfo/linux-audio-dev


Re: [LAD] Conciderations of Design

2011-11-12 Thread Jeff McClintock
David's advice is right on.

> why not use audio rate control ports? Or some sort of hybrid, allowing
> you to
> switch as needed - but that quickly becomes a complexity explosion...

I use a hybrid where ports are audio-rate AND each port has two states:
'streaming' or 'static'. So if you don't want audio-rate modulation, you
pass a buffer of identical values and set the port state 'static' (not
changing).
 The advantage is: 'Dumb' plugins need no special-case code, just write them
as though the port was always audio-rate, one single simple code-base.
 'Smart' plugins can query the port state and switch to more efficient code
when the port is 'static', e.g. read only the first sample, treat it like a
block-accurate parameter (i.e. Far more efficient).

Best Regards,
Jeff



___
Linux-audio-dev mailing list
Linux-audio-dev@lists.linuxaudio.org
http://lists.linuxaudio.org/listinfo/linux-audio-dev


Re: [LAD] Conciderations of Design

2011-11-12 Thread Thorsten Wilms

On 11/11/2011 11:19 PM, harryhaa...@gmail.com wrote:


I'm seeing downsides to each approach:
1: Tell it on every change -> performance hit
2: Request it every time it runs -> Keeping control over the many values
& unique ID's of class instances


This made me wonder what functional reactive programming * might have to 
offer here. This could be of interest:

www.cse.chalmers.se/~dave/Courses/Topics/SavedProjects/2007/2007-reactive/report.ps

* 
http://stackoverflow.com/questions/1028250/what-is-functional-reactive-programming



--
Thorsten Wilms

thorwil's design for free software:
http://thorwil.wordpress.com/
___
Linux-audio-dev mailing list
Linux-audio-dev@lists.linuxaudio.org
http://lists.linuxaudio.org/listinfo/linux-audio-dev


Re: [LAD] Conciderations of Design

2011-11-11 Thread David Olofson
On Friday 11 November 2011, at 23.19.44, harryhaa...@gmail.com wrote:
> Hi All,
> 
> Recent thoughts of mine include changing the "direction" of operations in
> real-time program design:
> Eg: Don't call a set() on a Filter class to tell it its cutoff, every time
> there's a change,
> but make it ask a State class what its cutoff should be every time it runs.

There are issues with both methods, depending on what you want to do.

Function calls add overhead that can become significant if you're doing very 
frequent parameter changes.

Polling, as I understand the latter approach to be, might be a great idea if 
you're only reading the parameter once per "block" of processing. You'll need 
to get that number from *somewhere* no matter what; be it a private closure, 
or some more public structure. However, if there are expensive calculations 
between that parameter and what you actually need inside the DSP loop, it 
might not be all that great. Things get even worse if you want to handle 
parameter changes with sample accurate timing. (Function calls can handle that 
just fine; just add a timestamp argument, and have plugins/units handle that 
internally in whatever way is appropriate.)

Some sort of event queues can offer some of the advantages of both of these, 
if designed properly. If they're delivered in timestamp order (either by 
system design or by means of priority queues or similar), processing them 
becomes very efficient and scalable the large numbers of "control targets"; 
you only have to check the timestamp of the next event, then process audio 
until you get there, and you only ever consider changes that actually occured 
- no polling.

All that said, how far do you need to take it? Unless you're going to throw 
tens of thousands of parameter changes at your units while processing, this 
overhead may not be as significant as one might think at first. It might be a 
better idea to focus on features and interfaces first. Remember, premature 
optimization is the root of all evil... :-)


> Along the same lines, say I have a single linked list of AudioElements, and
> the 3rd element needs info, should
> it request it, be told it, or have some other system to inform it of
> events?

I tend to go with "connection" logic and some sort of direct references when 
designing that sort of things - but again, that depends on the application and 
usage patterns you're designing for.

For example, in a physics engine (game or simulation), you have potentially 
hundreds or even thousands of bodies moving around, and you have to rely on 
spatial partitioning of some sort to figure out which bodies *can* potentially 
collide within the time frame currently being evaluated. In a naïve design, 
you essentially have to check every body against every other body, every 
single frame, and that... doesn't scale very well at all. :-)

As a more relevant (I think) extreme in the other direction, we have musical 
synthesis systems: Hundreds or even thousands of units processing audio in 
various ways (I'm thinking modular synthesis here, obviously - no way any sane 
person would use that many units otherwise... I think ;-) - but you won't 
normally see random communication between arbitrary units! What you will 
normally have is a number of (relatively) long "conversations" between units, 
usually best abstracted as some sort of persistent connections. Obviously, 
this saves a lot of time, as there is no overhead for looking units up, except 
possibly when making new connections. (Probably no need for that if you wire 
things as you build the graph.)


> I'm seeing downsides to each approach:
> 1: Tell it on every change -> performance hit

How are you going to avoid that anyway? Even if you do want to filter high 
frequency control data down, you'll need to deal with all data there is, or 
risk "random" behavior due to aliasing distortion. (Like downsampling audio 
without filtering or interpolation.)

Or, if you're going to use a lot of potentially high frequency control data, 
why not use audio rate control ports? Or some sort of hybrid, allowing you to 
switch as needed - but that quickly becomes a complexity explosion...


> 2: Request it every time it runs -> Keeping control over the many values &
> unique ID's of class instances

Well, if designed properly, this should scale with the graph. Basically, each 
connectable entity should only ever need to know what it's connected to - if 
even that. (See LADSPA ports.) Also, keeping such connection state data along 
with the state data of units might be a good idea performance wise, as it can 
make memory access more cache friendly.

But of course, the ultimate answer to all such questions is: Benchmarking! 
Though having a rough idea about how modern hardware works can help getting 
the initial design reasonably non-broken.


-- 
//David Olofson - Consultant, Developer, Artist, Open Source Advocate

.--- Games, examples, libraries, scripting, sound, music, graphics -