| Well, not bad for one evening's response!
Let's see what's in the bag...
Eric Scheirer wrote:
> One of the nice things is that it will be really easy to use
> it to generate scores in other formats, too; for example,
> to write a back-end so that it can produce SASL scores for
> use with SAOL instead.
>
> I'll do this as soon as you have the basics written, and
> you can quote me on that.
Cool!
This provides yet another incentive to concentrate on a really good
basic structure; if the foundation's no good, I'll be fixing the house
forever.
On the same note--
Aaron Isaksen wrote:
> This PERL module would be useful, but not just to CSound users. If you
> are mostly concerned with the score file part of CSound, then I wouldn't
> make it only for CSound. Why not output MIDI score, or some other kind?
> So, if you think that you'd want your functions to sometimes output MIDI,
> and sometimes output CSound .sco, then you probably want an object
> oriented programming approach.
Point taken. So far, no one has said "don't do object-oriented." I guess
OOP is the way to go. So now I have to really start learning it! Hope I
can avoid buying another $40 book, my computer-book budget is long
exhausted... thank god for the Perl manpages...
re. midi: someone in comp.lang.perl.misc pointed out that there is a
MIDI module on CPAN. I'll have to take a look and see what it does.
Personally, I'd like to concentrate on csound scores. But really all
that means is having ways to conveniently lump groups of events
together, process pfields, and keep track of time, and that ought to be
fairly portable to other score formats. I will probably leave that to
other people to implement, though.
Hans Mikelson weighed in as well:
> I have not done too much OOP lately and not in Perl but I think it might
> look something like if it were in C++ style:
>
> Verse Verse1(pattern_from_file("some-score-file1.sco",[4 .. 10]));
> Verse Verse2(pattern_from_file("some-score-file2.sco",[4 .. 10]));
> Timer Time(0)
>
> Verse1.Play(Time, 2);
> Time.Set(0);
> Verse2.Play(Time, 1);
> Verse2.Shuffle(5, Beats(4, 9), 2); ???
> Verse2.Play(Time, 1);
Hmmm, looks like Perl, only different. :)
A nice fellow (lady?) in comp.lang.perl.misc rewrote my example as:
my $verse1 = CMusic->new ("some-score-file.sco", [ 4 .. 10 ]);
my $verse2 = CMusic->new ("some-other-score-file.sco", [ 0 .. 20 ]);
$verse1->play (2);
$verse1->rewind();
$verse2->play (2);
$verse2->shuffle_pfield ($verse2->pfield(5, beats(4 to 9), *= 2));
$verse2->play();
I notice that both of you supplied definitions for verse2, even though I
didn't bother. Aww, ain't that sweet?
> Some of the advantages lie in functions name clutter. You could have
> Verse.Play() do one thing and Pattern.Play() and Song.Play(), do something
> else.
I wasn't sure what the benefit of this was, until it dawned on me that
it might help with something I'd been struggling with-- how to handle
nested patterns. That is, I think one should be able to build large
chunks of events out of small chunks of events, and manipulate the whole
at either the macro- or micro- level. Not that I have the foggiest idea
how that would be implemented. OK, I guess now I need to spend some more
time pondering my needs and then go back to comp.lang.perl.misc...
Hey Hans, thanks for the summary of O.O.P. I'd read similar things in
"Learning Perl" and skimming through a C book I have, but it takes
hearing these things several times in several different ways before I
get it. I think I'm almost there...
>Encapsulation as far as I
> understand means that the variables and the functions are contained in the
> class so that other classes can have the same local variables and local
> functions without bugging neighboring classes.
Sounds good.
> I think Polymorphism means that a function can do different things depending
> on the data you give it. A good example would be overloading + to do
> something like: (snip)
This also could be quite handy.
> Finally inheritance means that one class can inherit properties from a base
> class.
For some reason I don't quite "grok" inheritance. I'll look for an
example and see if that helps.
> One of the applications for a scoring language for me would be to call lots
> of different fractals so it might be good to grab some equations from
> fracint.
(snip)
> These can probably be implemented as subroutines pretty easily though.
I'll probably leave that to you. I'd like to focus on getting the
structure solid and well-designed.
Darn it, this was supposed to be a quick, easy project! Oh well, that
always happens. I wonder when I'll actually write some music?
> I
> started writing a Perl program which used fractals to generate score events
> in a granular synthesis fashion.
Well, if this library becomes a reality, I hope it could help you!
But getting ahead of myself for a moment:
Csound score ramping and carrying are very handy features that should be
supported by the perl module. There will probably need to be a way to
cause them to be calculated whenever you need to... for instance,
shuffling the order of a sequence of notes might break the intended
ramping effect, since it would move the anchoring values. There should
be ways to either interpolate the pfields in question before doing the
shuffle, or preserving the original ramp (i.e. keeping the anchor values
in the same place while everything else moves around).
For example,
i1 0 2 10 4 ; let's label this A
i1 1 3 20 < ; B
i1 2 1 100 < ; C
i1 3 8 80 10 ; D
If we simply shuffle those notes in time and then sort them, we could
end up with:
i1 0 1 100 < ; C
i1 1 2 10 4 ; A
i1 2 8 80 10 ; D
i1 3 3 20 < ; B
This is obviously a very strange result. Both of the unknown p5's now
depend on values not contained in this example, and could cause invalid
csound scores if there's no i1's before or after this in the final
score.
Alternatively, you might want to end up with this, so the original ramp
is preserved while the other pfields are moved:
i1 0 1 100 4 ; C
i1 1 2 10 < ; A
i1 2 8 80 < ; D
i1 3 3 20 10 ; B
Or you might want to interpolate the ramps before the shuffle, so you
end up with:
i1 0 1 100 4 ; C
i1 1 2 10 < ; A
i1 2 8 80 < ; D
i1 3 3 20 10 ; B
So there need to be methods to do all these things. Tricky stuff...
For that matter, I think that pretty much every existing feature of the
csound score should be well-supported by the module. i, f, s, r, a, and
e statements all need to be considered, as well as "." and "<". A
possible exception is the macro system, since the perl module is
intended to be a more powerful way to achieve some of the same things. I
don't really want to worry about how csound score macros might interact
with my pattern idea. But hey, if you're interested in scores with
unpredictable behavior, that might be a feature.
Regards,
PW
p.s. I forgot one item from my list of reasons to write this module:
--would be really useful for impersonating =cwt4ab7s or whatever the |