Hi!

Evan Laforge <[email protected]> writes:

> It's undocumented, so it's hard for me to read.  Also the math terms
> are a bit over my head, that might be part of it.  But it's
> interesting, because I've been working on a similar system.  Well,
> similar only in that in order to represent pitches I wind up with high
> and low level representations, but I think the actual realization of
> that is totally different.

I hope to write some proper documentation soon -- you may notice that
some of the comments have turned into mini-essays, in preparation for
this. In the latest commit I've tried to make the organisation of
Music.hs a little more obvious, and Examples.hs a bit more helpful.

I don't consider myself to have much of a head for mathematics, but
having read up on the relevant bits, I decided that -- given that it was
simple enough for me to understand -- there was no reason not to at
least write down the relevant formalisation (and formalising things
mathematically is The Haskell Way, right? :-)).


> I just have a pitch as a function which takes a key and a set of
> transposition signals (e.g. diatonic, chromatic, cents, hz) to a
> frequency, and then a scale is just a Map String Pitch.  So I think
> it's more flexible than yours since the pitch is very general, e.g. it
> can respond to any kind of transposition or key it feels like, and
> e.g. retune over time or relative to the intonation of other pitches.
> But then less flexible since it's a function, so you can only
> manipulated it through its arguments.  That makes a lot of analysis
> impossible.  I think this tradeoff between code and data is
> fundamental.

Pitch-as-a-function is a nice idea -- but, as you suggest, I'm looking
for something which gives me analysis/manipulation-flexibility, at the
expense of representation-flexibility. From my point of view -- which is
basically Western 'classical' music -- objects encountered in music
(pitches, intervals, durations etc.) are a collection of discrete data
types; and my attempt has been to find a correct representation in
Haskell of these types, for some value of 'correct' that appeals to my
own prejudices.

> Can you talk about why you chose this particular representation and
> what it allows you to do?

Essentially, I was frustrated that everyone seemed to be representing
intervals (and pitches) as integer numbers of semitones, which is really
not how musical intervals are constructed according to compositional
practice -- it's essentially letting the current norm of
12-equal-temperament tuning affect how pitches and intervals are
represented even in the absence of any tuning system. E.g. Midi makes
this mistake, though there is a half-baked 'Midi tuning standard' -- as
does Haskore, as far as I can tell. So, even if you have no problem with
12-equal temperament (I have no particular beef, it's as good a
compromise as any), importing it's all-semitones-are-created-equal idea
into the representation of music seems bound to confuse things.

The only package I could find on Hackage that attempted a more sensible
representation is Hans Hoglund's 'music-pitch' package. He counts
intervals as diatonic semitones (m2) and chromatic semitones (A1),
though some of it seems to be tied up in a Show instance in a slightly
ad-hoc way[1].

The main thrust is that, quite apart from tuning systems being
representable as groups with one generator (equal temperaments) or two
generators (meantone temperaments) (or more generators), the *notation*
of intervals in common musical practice defines a two-generator group
regardless of the tuning system in use[2].

> I guess you could write transformations at various levels,
> e.g. diatonic transposition at AbstractPitch1, or something else at
> AbstractPitch2 (I don't know what an "ordinary pitch" is), and perhaps
> impose vibrato or something at AbstractPitch3 (though your pitches
> seem to be discrete and not signals, though I guess you could just
> make a list of them).  But these uses probably aren't what you had in
> mind.

By 'ordinary pitch', I just meant F, C#, Ab, etc., as you would see
written on a page (I should have been clearer, sorry).

You're completely correct about what I have "in mind" -- I'm currently
only really concerned with what I consider to be "essential" to the
music theory -- pitches, intervals and durations. This represents a bit
of early music-bias (and general arrogance) on my part, so sorry about
that!


> The example piece seems like it's just a note list, so it doesn't
> really demonstrate the interesting things made possible by the three
> layer thing.

Yes, I perhaps shouldn't have emphasised the three-layer thing so much
-- it was just the way things fell out when I decided to separate out
into different types the different notions that the word "pitch"
has. The names ("AbstractPitch2" etc.) are completely arbitrary, and I
wasn't trying to make any grand statements about levels of abstraction
or anything -- so don't take too much notice of my dodgy naming
system. The different types of pitch only relate to each other in terms
of how you transform between them (applying scales or tuning systems).

The example piece is a long note list because I quite liked it and
wanted to transcribe the whole thing :-) -- it's purpose is to
demonstrate one of the tuning systems in Tuning.hs.

The contents of Tuning.hs are really my grand attempt at showing what
this representation of pitch/intervals makes possible, i.e., among other
things, giving definitions of certain classes of tuning systems
succinctly and intuitively.

> Also, it seems like you're focusing on scales with 7 diatonic steps?
> The Name type with its A-G implies that it's hardcoded that way.

That's correct. It always seems like a nice idea to say things like
"this package is not limited to Western classical music, and, in fact
only implements it as a special case" (most of the music-related
packages on Hackage seem to make some variant on that statement), and I
think such attempts are laudable, but I'm not currently claiming any
such generality -- it's not like there's a shortage of Western classical
music to play around with.

That said, it might be nice to implement some scales from the Arabic or
Indian traditions, to demonstrate some of the more exotic tuning systems
in Tuning.hs (cf. TET17 and TET22). Also, I'm considering adding a
hexachord-based pitch representation, to more accurately write down
pre-1500 music.

Hope that answers some of your questions! Sorry for the interminable
essay.

Edward


[1] To illustrate, load the file "Music/Pitch/Relative/Interval.hs" from
music-pitch-1.3.1, and evaluate the following expression (representing a
stack of seven minor thirds):
>    7 *^ m3
Then load my own "Examples.hs" and evaluate the same thing. (Note that
despite my criticism, Hans Hoglund's module is the reason I'm using the
AffineSpace & AdditiveGroup classes, which was an excellent idea.)


[2] Note that there's a choice of generator pairs available: Hoglund
uses (m2, A1), I use (d2, A1), and many others are possible. See the
function 'intervalDivisorsFrac' in my own Algebra.hs for a way of
converting between pairs.

_______________________________________________
haskell-art mailing list
[email protected]
http://lists.lurk.org/mailman/listinfo/haskell-art

Reply via email to