>> Just out of curiosity, what benefits do you see from this extra layer
>> of abstraction?  In other words, why write:
...
> MyFluteInst is essentially a signal function.  So how would you do MIDI
> instead?  That's the reason for the indirection via an association list.

Yeah, you're absolutely right.  I wasn't thinking of the MIDI thing.

> The names are somewhat arbitrary, but actually match the General MIDI
> instrument names.  If you prefer a different name, the Instrument data type
> has a "Custom" constructor, so you can write, for example:
>
> instrument (Custom "my crazy instrument") m

Indeed, and I do basically the same thing.

> If you really do need a thousand instruments, I would argue that you
> shouldn't name them, you should pass an argument (via a NoteAttribute) to a
> smaller number of instruments that affect the sound in some way.

True.  But it comes down to where you draw the instrument and score
distinction.  Draw it lower and suddenly you see lots of instruments
with few parameters (making instrument management more difficult),
draw it higher and you see few instruments with many parameters
(making it more difficult to use the instruments).  Since the
distinction is artificial, I suppose it should be drawn where most
convenient for the music in question, or not at all where not
appropriate.  But that implies you need a sufficiently fluid
definition to have that flexibility.

> Not sure what you mean here.  You can define and use as many Players as you
> like in a composition.

Oh, ok.  I was assuming that the Player level was separate, so you
would have 'score -> player -> output', but couldn't have 'score ->
player -> more score -> another player -> output'.

>>  There's no need to put a "swing" attribute into the score type
>> and then teach the Player how to interpret "swing"---this is what I
>> would call having to set up knobs that you get when orchestra and
>> score are separate.
>
> But I think the source code at the music level would look the same in your
> version or mine, i.e. something like "swing m".  The difference is that your
> version would actually modify m, whereas my version would delay it until the
> player got a hold of it.

Yes, but what I was getting at is that if you do it immediately now
you have control over order of operation.  Presumably if you delay it
until the player got ahold of it you now can't do things with the
player's output, unless you have another way to delay something even
more.  In other words, while you have both hierarchical and flat
processing, they are strictly divided.

Of course if you go from score -> flat -> score, the second score has
unavoidably lost the hierarchical organization of the first.  But that
doesn't mean that you can't then use that unit as an element in its
own hierarchy.

That's the part where I'm not totally sure of good musical use cases.
It's easier to come up with examples for control over order, like pre
or post score time to real time conversion.

The general ability to reflect the performance back into score and
then edit that score seems easy enough to motivate, but then you wind
up with separate scores (e.g. an original score and then a "diff"
overlay score), and I imagine with the appropriate functions
haskore/euterpea is perfectly capable of doing that too.

> Not sure I understand your point, but perhaps I didn't make it clear that a
> Player is orthogonal to an Instrument.  So I can write, for example:
>
> player p1 (instrument i1 m1 :=: instrument i2 m2) :+:
> instrument i3 (player p2 m3 :=: player p3 m4)

Ah, understood.

> I am unclear as to what you mean by "reversed instrument", but I wanted to
> point out that most sound synthesis algorithms are "causal", meaning that
> the current output depends on past output (for example filtering, reverb,
> etc.), but not on any future output.  Therefore to reverse a signal you
> would have to generate the entire result, save it in a data structure, and
> then reverse it.  Euterpea doesn't currently allow this, since our focus has
> been on making things run fast, and storing things in data structures is
> anathema to that.  But in principle it seems easy enough to do.

Right, it seems analogous to the introduction of dragging in haskell.
It should be possible to be fast, for example nyquist does this and is
quite fast.  It's just easy to take up lots of memory if you're not
careful about holding on to references, just like dragging in haskell.
_______________________________________________
haskell-art mailing list
haskell-art@lurk.org
http://lists.lurk.org/mailman/listinfo/haskell-art

Reply via email to