Notes are in core/note.cpp. The pitch is determined by an
integer called "pitch" which is the position on the staff
and another integer called "accs" that determines the number
of accidentals (+1 for a sharp, -1 for a flat, etc).
Converting to a note name (presumably for LilyPond output)
or MIDI pitch is done by the Note class. So we'd need to
change those methods to support other scales. Maybe
subclasses of Note would do it.
Having one integer to determine the accidental may not be
ideal but it's how LilyPond works so we're going to have to
live with it one way or another.
According to core/playable.cpp the events are placed on a
fixed grid with 1024 divisions of a whole note. That means
8 divisions of the smallest note the recognize, bizarrely
enough. It isn't good news for poly-rhythms :-(
Graham
Perhaps accs could be redone as a float or double.
> According to core/playable.cpp the events are placed on a
> fixed grid with 1024 divisions of a whole note. That means
> 8 divisions of the smallest note the recognize, bizarrely
> enough. It isn't good news for poly-rhythms :-(
256 PPQ isn't good enough for polyrhythms? Do you think that 128th
note nonuplets will be necessary? That's the first time we're going to
run out of clocks here.
-Mike
Not sure what you mean here. Can you give me an example?
-Mike
This is, for better or worse, typical. Finale, for example, uses whole
note 4096, but rounds everything to the nearest 64th (=64). In practice
this is probably necessary for quanticizing realtime entry and adequate
for representing fairly complex rhythms, but perhaps we'd like to go a
level or more further. I believe that Sibelius also uses whole note 4096
but continues down to 256th notes -- can a Sib user on the list confirm
this and describe how complex rhythms are handled?
djw
djw
Ah. And so you're saying the interplay between the two rhythms will
sound really choppy at a certain point with that low of a resolution?
-Mike
>> Having one integer to determine the accidental may not be
>> ideal but it's how LilyPond works so we're going to have to
>> live with it one way or another.
>
> Perhaps accs could be redone as a float or double.
Why? It means going all through the code and changing any
code that uses accidentals (C++ is explicitly typed,
remember) and what would be the point? LilyPond isn't going
to typeset a double, is it?
>> According to core/playable.cpp the events are placed on a
>> fixed grid with 1024 divisions of a whole note. That means
>> 8 divisions of the smallest note the recognize, bizarrely
>> enough. It isn't good news for poly-rhythms :-(
>
> 256 PPQ isn't good enough for polyrhythms? Do you think that 128th
> note nonuplets will be necessary? That's the first time we're going to
> run out of clocks here.
How do you divide a whole note into 5 equal parts with a
grid that has 1024 divisions of a whole note? It can't be
done. You can approximate it, and maybe it'd look and sound
good enough. But there has to be some other information to
tell you that it's supposed to be a division by 5. That
adds complexity. No way would I start with a 1024 tick grid
if I wanted poly-rhythms.
Graham
Yeah, but an int used where a double is required is automatically
typecasted up to a double. It might be as simple as a few search and
replaces, and it might not be. Is there some part of the code we can't
change that has to do with Lilypond?
We could make a subclass that has different types of accidentals as
well, I suppose. Like accs is the number of accidentals and then
there's a vector of what kinds of accidentals to draw. So if I want C
half sharp minus a schisma in sagittal, accs will be 2, and the vector
will have pointers to a half sharp glyph and a negative schisma glyph,
or something to that effect.
> How do you divide a whole note into 5 equal parts with a
> grid that has 1024 divisions of a whole note? It can't be
> done. You can approximate it, and maybe it'd look and sound
> good enough. But there has to be some other information to
> tell you that it's supposed to be a division by 5. That
> adds complexity. No way would I start with a 1024 tick grid
> if I wanted poly-rhythms.
I see what you're saying. 256*5*7*9*11, which should be adequate for
most things, is a division of 887040 parts per whole note, or 221760
parts per quarter note. 128*5*7*9, which is less accurate, is 40320
parts per whole note, or 10080 parts per quarter note. I'm not sure
what the desired level of accuracy is, but I can't see people needing
more than a 256th note, subdividing anything into a factor of three
more than twice, or 7, 9, or 11 more than once. But then again, people
do like to do some crazy things, so we'll have to adapt around it.
I do think that when we get into that sort of thing we're going to end
up needing to tack on some information that says "this is a
quintuplet" anyway, as at some point, unless the division per whole
note is -huge-, we'll run into some confusion with interpreting
things. For example, is a half note divided into 6 going to be thought
of as quarter note triplets divided into two eighth notes... aka
DA-dum DA-dum DA-dum? Or, rather, as two quarter notes divided into
triplets, as in ONE-and-a TWO-and-a... They will be notated
differently and mean different things in terms of phrasing and how the
musician feels the pulse.
-Mike
djw
djw
I just uploaded the first system as Cowell.tiff, with shaped noteheads and
no brackets.
LilyPond has to know what the accidental is. The current
format LilyPond uses for accidentals is an integer. As we
modify LilyPond to use arbitrary accidental sets the obvious
thing is to keep that integer. So we need a way of tying
accidentals to integers. Why not use it in Canorus as well?
Again, what's the point of a double?
> We could make a subclass that has different types of accidentals as
> well, I suppose. Like accs is the number of accidentals and then
> there's a vector of what kinds of accidentals to draw. So if I want C
> half sharp minus a schisma in sagittal, accs will be 2, and the vector
> will have pointers to a half sharp glyph and a negative schisma glyph,
> or something to that effect.
Yes, that's it. Although the Note class doesn't handle the
display.
>> How do you divide a whole note into 5 equal parts with a
>> grid that has 1024 divisions of a whole note? It can't be
>> done. You can approximate it, and maybe it'd look and sound
>> good enough. But there has to be some other information to
>> tell you that it's supposed to be a division by 5. That
>> adds complexity. No way would I start with a 1024 tick grid
>> if I wanted poly-rhythms.
>
> I see what you're saying. 256*5*7*9*11, which should be adequate for
> most things, is a division of 887040 parts per whole note, or 221760
> parts per quarter note. 128*5*7*9, which is less accurate, is 40320
> parts per whole note, or 10080 parts per quarter note. I'm not sure
> what the desired level of accuracy is, but I can't see people needing
> more than a 256th note, subdividing anything into a factor of three
> more than twice, or 7, 9, or 11 more than once. But then again, people
> do like to do some crazy things, so we'll have to adapt around it.
Yes, and what I said is that Canorus has 1024 hard coded.
It won't be trivial to change.
> I do think that when we get into that sort of thing we're going to end
> up needing to tack on some information that says "this is a
> quintuplet" anyway, as at some point, unless the division per whole
> note is -huge-, we'll run into some confusion with interpreting
> things. For example, is a half note divided into 6 going to be thought
> of as quarter note triplets divided into two eighth notes... aka
> DA-dum DA-dum DA-dum? Or, rather, as two quarter notes divided into
> triplets, as in ONE-and-a TWO-and-a... They will be notated
> differently and mean different things in terms of phrasing and how the
> musician feels the pulse.
Yes. That's similar to joining stems. A kind of invisible
group.
Graham
> But, am I correct that you did the playback with tuplets,
> then hid them, then changed the notehead graphics?
>
> -Carl
the tuplets are still there, I just told Finale not to display either the
bracket or number. Changing the notehead is independent of the tuplet
function.
djw
In general, the pitch-in-Hz needn't have a one-to-one
mapping with the accidental. The "cents offset" has to be a
method of note. Depending on the language maybe that can be
implemented as a property.
There has to be a table so that the GUI knows which
accidentals to offer.
It's tempting to make the accidental index also notate pitch
but it's simpler to put the valid accidentals in order of
size. I don't see why we have to assume any mapping to pitch.
There are going to be times where two different accidentals
refer to the same pitch-in-Hz. Maybe they'll have a
different JI pitch, though, so they still get a unique number.
Note I got LilyPond wrong before. It stores accidentals as
rationals, not integers, denoting fractions of a whole tone.
Rationals and integers can both be used to index glyph and
pitch tables. I wouldn't like to do that with floats.
Graham
> Of course this requires a good cents-to-ratios algorithm, but we know
> how to do that these days -- continued fraction expansion, stopping as
> soon as the error falls to 0.005 cents or less. It would need thorough
> testing to ensure it doesn't miss any simple ratios that are close to
> the 0.005 cent boundary through rounding error (like the apotome
> itself). Every 0.01 cents should give a unique ratio.
We have enough RAM these days for a lookup table as well.
Graham
Yes, and there also has to be a keyboard mapping.
If you're starting with a ratio there should be a better
algorithm than looping through all accidentals and seeing if
their ratios match. My preference is to describe the
nominals and accidentals in terms of R equal temperaments
for a rank R system. Then you have a mapping from JI for
each of those equal temperaments. From that you can work
out the nearest nominals and the semantics of the
accidentals for each case.
Probably the same idea would work if you describe unison
vectors instead. I may be biased towards equal temperaments
or I may have come to prefer them as a result of valid
reasoning and experience. You decide.
>> It's tempting to make the accidental index also notate pitch
>> but it's simpler to put the valid accidentals in order of
>> size. I don't see why we have to assume any mapping to pitch.
>
> You're perfectly right that we don't have to. It is ultimately just an
> index, as you say. But don't forget it is an index into all possible
> strings of accidentals in a given system. Fortunately, even sagittal
> doesn't (not even sagittal does) need more than 16 bits for that.
Incidentally, is there any chance of a sagittal font with a
separate code point for all those possible accidentals?
Some things are simpler if you only have one character per
accidental.
> But don't we want the capability to renotate a score, using a
> different notation system, at the click of a button. In that case the
> indexes into all the different systems' possible strings of accidental
> symbols have to somehow correspond, or we have to somehow store the
> semantics (i.e."meaning") of the accidentals rather than just an
> index. I'm suggesting it can be simultaneously an index and carry
> meaning, if we make it centicents (hundredths of a cent) or something
> similar.
We want that but it's not clear how it'll work or what the
priority is. One way would be to record the mapping from JI
to the accidental. But an accidental in a tempered system
would have more than one interpretation. And storing the JI
interpretation directly makes more sense than guessing from
this index. At any rate, the priority is to get the
notation to work, and this level of automatic renotation is
YAGNI.
Sure, a mnemonic for debugging purposes does no harm.
>> There are going to be times where two different accidentals
>> refer to the same pitch-in-Hz. Maybe they'll have a
>> different JI pitch, though, so they still get a unique number.
>
> Good point. I'm suggesting we always store the untempered meaning of
> the accidental (as centicents which can be decoded as ratios), so yes
> that takes care of many such cases that only arise when notating
> temperaments. However even in the JI case there are two other ways in
> which two different strings of accidentals can have exactly the same
> semantics.
>
> 1. Where a system allows alternative symbols, such as where Sagittal
> allows the use of conventional sharps and flats, Tartini-Couper
> symbols, and Wilson plus and minus symbols. Presumably the user won't
> want to mix these on the same score so it can just be specified in one
> place per score, which of the alternatives are wanted. Or each
> possible combination can just be treated as a separate notation system
> with its own lookup table. e.g PureSagittal, MixedSagittal,
> MixedSagittalTC, MixedSagittalW, MixedSagittalTCW.
Yes, a different lookup table for each. Then we *can* offer
simple conversions between at least some of them.
> Alternative spellings of JI pitches within the same system, e.g. as a
> result of a key change, usually involve a change of nominal, so the
> semantics of the accidental string changes too and there's no problem.
>
> Can you think of a case where you might want alternative spellings
> within the one score, that don't involve a change of nominal, and
> don't change the untempered semantics of the accidental, and yet use a
> different accidental string?
I don't know how it would work in any given system -- it's
your call for mixed sagittal. But sometimes you can choose
to notate a quartertone as a sharp minus another
quartertone. I can easily see that a JI system would have
two different kinds of quartertone accidentals that add up
to a sharp. It really comes down to systems like mixed
sagittal implying 12 nominals via sharps and flats but only
using 7 nominals on the staff.
> Lets assume they do exist. Here are two options.
> 1. Simply declare only one of them to be correct.
Not good enough.
> 2. Store the two alternative spellings of some accidental semantics as
> if they differred by one centicent.
Yes. Not a big deal if the number's only meaningful for
debugging.
>> Note I got LilyPond wrong before. It stores accidentals as
>> rationals, not integers, denoting fractions of a whole tone.
>> Rationals and integers can both be used to index glyph and
>> pitch tables. I wouldn't like to do that with floats.
>
> Thanks. When I looked at it over a year ago, it used an integer
> representing the number of quartertones.
Oh, it's worth looking at the development branch then.
They've added better support for accidentals which
unfortunately doesn't work with alternative fonts (despite
my best efforts so far) but is a step in the right
direction. There are some new symbols for "makam" notation
as well.
Another thing is that they say the rational accidentals are
supported in MIDI. So if you have notation based on
12-equal nominals you can get it to play back using pitch
bends. That means 72-equal should be fully supported using
a mixture of quartertone and makam accidentals. Maybe they
could even add Sims/Maneri or Spartan Sagittal to the
standard font if somebody asked.
> I totally agree re not using floats. And there's nothing stopping us
> changing it back to an integer, provided we supply an appropriate
> algorithm or lookup table to convert centicents to rational fractions
> of a whole tone.
There'll have to be lookup table saying how to represent
each accidental we might want to use. From there, it's easy
to add cents for playback and some encoding of ratios for JI
interpretations. Storing these things in one place means
it's easy to change the interpretation of an accidental, as
the tuning or key centre changes.
Graham
You can't be sure the ratio the user typed in maps exactly
to the symbol they want. There might be other equivalents
in the temperament. So you either have to search for nearby
equivalents or have a huge list with every possible JI
equivalent for every accidental. Convert the ratio into a
"pitch" in whatever system the notation uses and all you
need to do is look up what accidentals represent that
"pitch". There are complications but they're the same ones
that come up in other contexts.
> My preference is to describe the
>> nominals and accidentals in terms of R equal temperaments
>> for a rank R system. Then you have a mapping from JI for
>> each of those equal temperaments. From that you can work
>> out the nearest nominals and the semantics of the
>> accidentals for each case.
>>
>> Probably the same idea would work if you describe unison
>> vectors instead. I may be biased towards equal temperaments
>> or I may have come to prefer them as a result of valid
>> reasoning and experience. You decide.
>
> If you're writing the code, and that's what you feel comfortable with,
> and it's all transparent to the user, then why not? Except that others
> who may need to maintain it won't have your understanding or
> experience of this way of looking at things.
Is there another way? For regular notation you have one
number describing the position the staff and another
indexing a chromatic scale. You could, I suppose, represent
the nominals and accidentals using JI intervals and look for
equivalents tempering out given commas but it sounds
difficult to implement.
>> Incidentally, is there any chance of a sagittal font with a
>> separate code point for all those possible accidentals?
>> Some things are simpler if you only have one character per
>> accidental.
>
> It could be done. But not by me. I have better things to do. :)
Fair enough.
> And you'd have to do this with _all_ supported notation systems. I
> think you should just accept you need to allow for multiple characters
> (eventually with kerning). The sagittal font contains a list of
> kerning pairs for when accents are used. You might also allow for a
> system to use characters from multiple font files if that's not too
> difficult.
I think we do. But a solution that works for a lot of
important cases is still worth looking at. LilyPond has a
system that would work well with single characters if only
we could convince it to load a new font.
> If some limit neds to be placed on the number of characters composing
> a single accidental, or putting it another way, the number of
> accidentals against a single note, I'd say 5 would meet all reasonable
> needs. What was done with the Chrysalid Requiem score (up to 20
> accidentals per note) was useless and unnecessary.
> http://launch.groups.yahoo.com/group/tuning/message/41718
If the limit isn't 1 there needn't be a limit.
I've uploaded my proof of concept for this in LilyPond:
http://groups.google.com/group/microtools/web/accidental_glyph.ly
It prints a string of arbitrary sagittal characters if you
have the font installed. So it surely can be done. We need
to work out how to move the accidentals in front of the
note-head and then copy all the other stuff we're losing by
throwing away the standard methods. But it's progress!
The other file I uploaded is how I think sagittal should
work. Currently it doesn't show the accidentals. With my
hacked build I've got it as far as raising an error.
http://groups.google.com/group/microtools/web/ET22-sagittal.ly
>>> But don't we want the capability to renotate a score, using a
>>> different notation system, at the click of a button.
>> We want that but it's not clear how it'll work or what the
>> priority is. One way would be to record the mapping from JI
>> to the accidental. But an accidental in a tempered system
>> would have more than one interpretation.
>
> How so?
I mean the same accidental would represent more than one JI
interval. Not the other way round.
>> At any rate, the priority is to get the
>> notation to work, and this level of automatic renotation is
>> YAGNI.
>
> Are you suggesting recompiling the sofware with substitute modules
> with different tables, to make it work with a different system. I
> guess that fair enough. At least for a first pass.
The subject line's still Canorus. If we're going to hack on
Canorus the first thing's to adapt it to work with one other
system, maybe 72-equal. Then add an option to choose the
system and take it from there. With a brand new application
we'd have more up-front design but it needn't involve
automatic conversions until we're ready to implement them.
For full generality that certainly is difficult and if you
want to know more go and talk to Carl about it.
>> Another thing is that they say the rational accidentals are
>> supported in MIDI. So if you have notation based on
>> 12-equal nominals you can get it to play back using pitch
>> bends. That means 72-equal should be fully supported using
>> a mixture of quartertone and makam accidentals. Maybe they
>> could even add Sims/Maneri or Spartan Sagittal to the
>> standard font if somebody asked.
>
> No point fiddling about with half-measures if you've got the fire in
> your belly to do something better.
It must surely be possible to switch the fonts and the
developers haven't refused to support it but I can't work
out how to get it working. And I've got a train booked for
tomorrow so I won't be able to use this machine for over a
month, and I haven't built LilyPond on any other machine. I
can't promise I'll be able to work on it in the interim.
They're also talking about a new stable release. So we may
have to target that release. It'd be easier to distribute a
hacked font than a hacked application. As it's all open
source we could do that. Their fonts are generated by
Metafont but that doesn't mean the can't be merged in with
PostScript/OpenType/SVG fonts produced other ways. I know
nothing about producing fonts so I don't know how much work
such a hack would involve.
Still the best option is getting font switching to work.
Second best probably drawing the accidentals in Scheme,
which also allows for compound accidentals. But that's a
different thread I haven't pursued beyond that proof of concept.
>> There'll have to be lookup table saying how to represent
>> each accidental we might want to use.
>
> You mean each string of accidentals? That's where it starts to look
> like some mixture of calculation and lookup might make more sense,
> rather than such a huge lookup table.
Yes. Unless it's such a horribly complicated pitch system
that the program needs to know how the accidentals build up.
Which may be the "mixture of calculation and lookup" of
which you speak. To start with I'd rather think of systems
that are simple enough we don't need to do that.
>> From there, it's easy
>> to add cents for playback
>
> Playback cents may not need to be calculated until playback time.
Yes. They can even change during playback.
>> and some encoding of ratios for JI
>> interpretations.
>
> Preferably a prime exponent vector to make tempering calculations
> easy.
Yes.
>> Storing these things in one place means
>> it's easy to change the interpretation of an accidental, as
>> the tuning or key centre change
>
> Sure.
I'll also mention the option of having CANote (as in
Canorus) do the lookups so that not all pitch systems have
to share the same lookup tables and so on.
Graham
p.s. While I'm at it, here are the diffs for getting
different accidental fonts to not work with LilyPond
2.11.52. Note the diagnostic line telling you which index
it found.
===================================================================
RCS file: lily/pango-font.cc,v
retrieving revision 1.1
diff -r1.1 lily/pango-font.cc
76a77,121
> Box
> Pango_font::get_indexed_char (size_t signed_idx) const
> {
> // no cache
>
> PangoFont *font = pango_context_load_font(context_,
pango_description_);
> PangoFcFont *fcfont = G_TYPE_CHECK_INSTANCE_CAST (font,
> PANGO_TYPE_FC_FONT,
> PangoFcFont);
> FT_Face ftface = pango_fc_font_lock_face (fcfont);
>
> FT_UInt idx = signed_idx;
> FT_Load_Glyph (ftface,
> idx,
> FT_LOAD_NO_SCALE);
>
> FT_Glyph_Metrics m = ftface->glyph->metrics;
> int hb = m.horiBearingX;
> int vb = m.horiBearingY;
> Box b (Interval (-hb, m.width - hb),
> Interval (-vb, m.height - vb));
>
> pango_fc_font_unlock_face (fcfont);
> return b;
> }
>
> size_t
> Pango_font::name_to_index (string nm) const
> {
> PangoFont *font = pango_context_load_font(context_,
pango_description_);
> PangoFcFont *fcfont = G_TYPE_CHECK_INSTANCE_CAST (font,
> PANGO_TYPE_FC_FONT,
> PangoFcFont);
> FT_Face ftface = pango_fc_font_lock_face (fcfont);
> char *nm_str = (char *) nm.c_str ();
> size_t idx = FT_Get_Name_Index (ftface, nm_str);
> pango_fc_font_unlock_face (fcfont);
> printf("Name: %s ID: %ld %ld\n", nm.c_str(), idx,
> index_to_charcode (idx));
> if (idx)
> return idx;
>
> return (size_t) -1;
> }
>
===================================================================
RCS file: lily/include/pango-font.hh,v
retrieving revision 1.1
diff -r1.1 lily/include/pango-font.hh
41a42,43
> Box get_indexed_char (size_t) const;
> size_t name_to_index (string) const;
>> I mean the same accidental would represent more than one JI
>> interval. Not the other way round.
>
> You mean because it comes to represent a particular vector of
> generator counts in a temperament therefore it represents all possible
> detemperings of that generator count vector?
I think so. Let's assume we both have the concept right but
have difficulty communicating it.
>> The subject line's still Canorus. If we're going to hack on
>> Canorus the first thing's to adapt it to work with one other
>> system, maybe 72-equal.
>
> I'd never heard of Canorus until this thread, but I've had 3 or 4
> people ask about Sagittal in Lilypond.
Canorus is a young project. And this mailing list started
out because people wanted a GUI. Canorus is a GUI. Even if
we can't make it do exactly what we want I think the
experience of hacking it would be valuable. As it is with
LilyPond.
> I don't know anything about MetaFont or SVG. But OpenType using either
> PostScript or TrueType outlines is pretty ubiquitous these days. If
> they can't use One of the 3 formats Sagittal is currently available in
> I'll be surprised. Other people have had problems getting Sagittal to
> work, but they have both related to the character code mapping (Mac
> and Unix). One was fixed by adding 0xF00 and the other by making the
> font no longer a Symbol font and just making the character codes 0 to
> 255.
FontForge wasn't showing the correct Unicode ranges for
Sagittal. But no matter.
>> Still the best option is getting font switching to work.
>> Second best probably drawing the accidentals in Scheme,
>> which also allows for compound accidentals. But that's a
>> different thread I haven't pursued beyond that proof of concept.
>
> Nah. Gotta get font switching to work.
It isn't working and it won't give us compound accidentals
(other than by hacking the fonts).
>> Yes. Unless it's such a horribly complicated pitch system
>> that the program needs to know how the accidentals build up.
>> Which may be the "mixture of calculation and lookup" of
>> which you speak. To start with I'd rather think of systems
>> that are simple enough we don't need to do that.
>
> But even very simple systems combine conventional sharps and flats
> (and their doubles) with other symbols. It doesn't make sense to
> lookup the whole strings, just to calculate the sharps and flats and
> lookup the other symbols.
That doesn't mean the compound symbols can't each have a
single code point in the font though. Double flats already
work that way.
> With sagittal, you only need to have a lookup of the positive symbols
> less than a half apotome (57 cents). The character codes of their
> apotome inversions and extensions can be easily calculated.
But for full generality we'll need the full table.
Graham
> Has anyone checked out the Canorus and MuseScore sources
> and done a checklist of qualities we're looking for?
What qualities are we looking for? They're both C++ programs with no
support for microtonality. MuseScore has an ugly way of indexing
accidentals, which I reproduce below, but I'm sure we can work around
it.
// 0 - no accidental
// 1 - sharp
// 2 - flat
// 3 - double sharp
// 4 - double flat
// 5 - natural
// 6 - (sharp) 11 - [sharp]
// 7 - (flat) 12 - [flat]
// 8 - (double sharp) 13 - [double sharp]
// 9 - (double flat) 14 - [double flat]
// 10 - (natural) 15 - [natural]
Their potential's more related to the user interfaces than the source
code. It's up to somebody who has experience with score editors to
see how they measure up. MuseScore seems to work with 12-equal pitch
entry first, guesses the spelling, but allows you to choose an
alternative. That biases it towards scale-based music.
Graham
>
> Like Dave, I only foresee using ratios for rational
> intonation. How could they be used with temperaments?
>
Well, many temperaments include one or more just intervals and it might be
useful to have a notation that makes such a mixture explicit. It might be
useful, for example to notate the 5:4 thirds in meantone or the just
thirds and fifths in well-temperaments.
In fact, with the .txt files used to set the tuning for InTun, I often mix
just ratios with tempered intervals.