>> 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