- ✩ ✩ ✩

www.ozanyarman.com

On Oct 31, 2009, at 7:38 AM, Graham Breed wrote:

> Ozan Yarman wrote:

>

>> So, if I eliminate the pitchbend lookup tables in Timidity entirely,

>> do I arrive at MTS with 16384 increments per interval (semitone,

>> wholetone, etc...)?

>

> Yes. But it's only as good as the sample set you're using.

> If the samples aren't tuned that accurately, the results

> won't be anyway. That's why you should go for a purely

> algorithmic approach for high-precision tuning.

>

So you mean that it is safer to keep the PB lookup tables and

implement linear interpolation?

>> I imagine trying to benchmark the different compilations of Timidity

>> on my powerful Macbook Pro will produce negligible results.

>

> Probably, yes. There may be a good reason for the

> optimization but without seeing benchmarks I'll assume not.

>

>> Wait, did you say that the audio might crackle again after this? I

>> hope it's not so.

>

> I doubt it.

>

>> Or else, maybe you can patch of the tables.c file to eliminate the

>> pitchbend lookup tables entirely and send it to me via e-mail?

>

> If you know what you want to change, I can send you the

> updated file. It'd probably easier to switch to something

> like :-

>

Send me both a version of tables.c with no lookup tables and maximum

precision and another version with 256 divisions of the equal semitone

improved with linear interpolation. I'll test both versions if I can

ever successfully compile Timidity for Windows.

>> One more thing, I couldn't find a Windows executable of the latest

>> version of ZASFX, which is v. 2.4. Do you have a compiled version

>> 2.4?

>> Or do I need to compile it myself too?

>

> I have the Linux version from the Ubuntu repository. It

> doesn't have a version number, may be a custom build. I've

> never downloaded or used the Windows version.

>

Ok.

>

> Graham

>

>

>

Oz. - ✩ ✩ ✩

www.ozanyarman.com

On Oct 31, 2009, at 8:28 AM, Graham Breed wrote:

> Ozan Yarman wrote:

>> Graham, can you elaborate how using linear interpolation with the

>> lookup

>> tables will increase the pitch bend precision? Please be specific and

>> remember that I am a C programming dummy.

>

> Sure. I don't need C, but I'll use bc (the Unix calculator)

> for examples.

>

> The usual formula for converting a pitch difference in cents

> to a frequency ratio is

>

> e(x*l(2)/1200)

>

> where e() is the exp function, l() is the corresponding

> logarithm function, and x is the cents value. Because

> l(2)/1200 is a constant, that can be simplified to.

>

> e(x*0.00057762265)

Where l is ln, or neperian (natural) logarithm of course. The same

results can be obtained by the formula:

2^(cents/1200)

>

> So it only requires one multiplication and the e() function,

> which is a basic piece of mathematics and sure to be in

> floating point processors or libraries.

>

Agreed.

> The problem is that e() isn't that easy to calculate. There

> are standard algorithms that come from pure mathematics, but

> they require a relatively large number of operations to get

> an accurate result. You can also use a lookup table, which

> is a big list of known values kept in memory, like the log

> tables people used to use before desktop calculators.

>

So far so good.

> The standard libraries (in either hardware or software) will

> use fairly sophisticated ways of calculating e() that

> involve lookup tables and are optimized to be very fast.

> For most of us, those are all we ever need. There are,

> however, cases where you may find an improvement by writing

> your own algorithm:

>

> 1) You're running on limited hardware (like a hardware

> synth) and don't have enough memory free for the lookup tables.

>

> 2) You need this function in a critical piece of code where

> every bit of optimization makes a difference.

>

> 3) A time machine has transported you back to the 1970s

> where even desktop processors are more limited and the

> libraries aren't so good.

>

> There are other cases where you might not see an

> improvement, but start fiddling around anyway:

>

> 4) You're used to running on limited hardware and got into

> the habit of implementing these things yourself.

>

> 5) You didn't bother to check if the piece of code your

> working on is critical to performance or not.

>

> 6) You learned C programming from a text book written in the

> 1970s.

>

> So, for whatever reason, you think you can do better then

> the standard library designers at writing an exponential

> function. Is that hubris? Maybe not. The point is, when

> you're dealing with pitch differences, you have a very good

> idea what range of values you're going to plug in and you

> don't need the full precision of your floating point

> variables. That allows you to take short-cuts that the

> standard library designers couldn't take account of. And

> the easiest thing to write is a lookup table.

>

Ok.

> The way Timidity does it is to split the calculation between

> two different lookup tables: one for equal tempered

> semitones and one for fine tunings smaller than a semitone.

> This is convenient because we only need to consider the

> fine tuning.

Right.

>

> So the problem is to return the frequency ratio

> corresponding to an interval between 0 and 100 cents. The

> method they use is a 256 entry lookup table. The number 256

> is chosen because you can get the index into the table from

> the original tuning specification by bit shifting, which is

> very fast.

Bit shifting? Please elaborate here. What number other than 256 is

appropriate for this bit shifting? Is 1024 such a number for example?

> The lookup is also very fast, so we have a way

> of finding the frequency ratios accurately, but only in

> 1/256 semitone steps.

>

So far so good.

> (Note: Csound users may be getting smug here, but you still

> have to be careful. Csound does also implement its own

> functions with limited precision. For example: "powoftwo()

> function returns 2 ^ x and allows positive and negatives

> numbers as argument. The range of values admitted in

> powoftwo() is -5 to +5 allowing a precision more fine than

> one cent in a range of ten octaves." Avoid this for

> microtonal work.)

>

> Because 256 isn't a convenient number to work with in

> decimal, I'll instead talk about 100 divisions, or a

> resolution of 1 cent. Imagine a lookup table that gives you

> the tuning of an interval to the nearest cent.

>

> The correct tuning of a 5:4 major third in cents is, from bc,

>

> l(1.25)/l(2)*1200

> 386.31371386483481743200

Or otherwise = log(10) 1.25 x 1200 / log(10) 2.

>

> reversing that calculation with limited precision gives

>

> e(386.3137*0.00057762265)

> 1.24999998976386909720

>

> Very close to 1.25. But our lookup table only gives us

> values to the nearest cent, so we have to choose between:

>

> e(386*0.00057762265)

> 1.24977351000380408917

>

> e(387*0.00057762265)

> 1.25049561602287101401

I'm getting this now.

>

> We know that both of these are close to what we want. We

> also know that they're both wrong. In fact, because we

> threw away a fractional part of 0.3137, we can guess that

> the true value is about 0.3137 of the way from the value for

> 386 cents and that for 387 cents. That gives a new expression:

>

> e(386*0.00057762265)*(1-0.3137) + e(387*0.00057762265)*0.3137

> 1.25000003466198538348

>

> You can see that this result is much closer to what we

> wanted -- and that's linear interpolation. The true size of

> the interval that came out is

>

> l(1.25000003466198538348)*1200/l(2)

> 386.31376187124159514818

>

> Not bad -- four decimal places in and nearly four out, or

> accuracy to better than a millicent. All this from a lookup

> table in cents.

Fabulous.

> The calculation will be slower -- maybe

> it'll take two or three times as long -- and the lookup

> table is less than half the size of Timidity's.

>

So, all that is needed is to add the arguments for linear

interpolation whilst preserving the original 256 equal divisions of

the semitone tuning resolution. That way the actual increments we'll

be working with shall be much smaller than 0.39 cents. Right?

> You need to calculate the frequency every time a note is

> played, or the pitch wheel moves. That won't happen very

> often, compared to the rate at which any digital equipment

> has to process its samples. Merely doubling the time it

> takes shouldn't be significant. Unfortunately, the poor

> pitch resolution of many synthesizers shows that they aren't

> bothering :-(

Good thing that there is Timidity++ then!

>

>

> Graham

>

>

Oz. - Ozan Yarman wrote:

>> e(x*l(2)/1200)

That's it. But not, as it happens, in bc, because the ^

> Where l is ln, or neperian (natural) logarithm of course. The same

> results can be obtained by the formula:

>

> 2^(cents/1200)

operator doesn't work with non-integer powers. And this may

correspond to how the underlying hardware works, and so may

be a difference you care about.

>> So the problem is to return the frequency ratio

There are 14 bits of fine tuning, right? 256 requires 8

>> corresponding to an interval between 0 and 100 cents. The

>> method they use is a 256 entry lookup table. The number 256

>> is chosen because you can get the index into the table from

>> the original tuning specification by bit shifting, which is

>> very fast.

>

>

> Bit shifting? Please elaborate here. What number other than 256 is

> appropriate for this bit shifting? Is 1024 such a number for example?

bits, so you throw away bits. 1024 is, indeed, another

number that works. It needs 10 bits and you throw away 4.

A number that doesn't work is 100. Dividing by 100 in

binary is more difficult than repeatedly dividing by 2 --

but obviously easier in decimal. The numbers that work are

2^n for integer n.

>> The calculation will be slower -- maybe

That's it. But it's still easier to keep the original

>> it'll take two or three times as long -- and the lookup

>> table is less than half the size of Timidity's.

>

> So, all that is needed is to add the arguments for linear

> interpolation whilst preserving the original 256 equal divisions of

> the semitone tuning resolution. That way the actual increments we'll

> be working with shall be much smaller than 0.39 cents. Right?

expression and let the standard libraries sort it out if

you're on desktop hardware.

>> You need to calculate the frequency every time a note is

No, that's an example of an application that doesn't bother

>> played, or the pitch wheel moves. That won't happen very

>> often, compared to the rate at which any digital equipment

>> has to process its samples. Merely doubling the time it

>> takes shouldn't be significant. Unfortunately, the poor

>> pitch resolution of many synthesizers shows that they aren't

>> bothering :-(

>

> Good thing that there is Timidity++ then!

with interpolation. ZynAddSubFX is apparently better,

though, and Csound can use the 64-bit standard library.

Graham - Ozan Yarman wrote:
> ✩ ✩ ✩

No, I mean it may not be worth bothering. If your samples

> www.ozanyarman.com

>

> On Oct 31, 2009, at 7:38 AM, Graham Breed wrote:

>

>> Ozan Yarman wrote:

>>

>>> So, if I eliminate the pitchbend lookup tables in Timidity entirely,

>>> do I arrive at MTS with 16384 increments per interval (semitone,

>>> wholetone, etc...)?

>> Yes. But it's only as good as the sample set you're using.

>> If the samples aren't tuned that accurately, the results

>> won't be anyway. That's why you should go for a purely

>> algorithmic approach for high-precision tuning.

>

> So you mean that it is safer to keep the PB lookup tables and

> implement linear interpolation?

aren't tuned to MTS precision it doesn't matter how

precisely Timidity retunes them -- unless it does something

clever with pitch recognition, which I doubt. But

ZynAddSubFX or VAZ Plus or Csound don't require real-world

samples and so you can get much better control over the

pitch. So if you really care about this level of precision

you may be better off without a sampler.

If you want to work with SoundFonts you may have to stomach

this level of imprecision. I have a vague idea that the

SoundFont standard doesn't specify the pitch of samples any

more precisely than Timidity's tuning tables anyway ...

which would be a good reason why Timdity uses that level of

precision.

> Send me both a version of tables.c with no lookup tables and maximum

I can do that if you're ready to compile it. I can also

> precision and another version with 256 divisions of the equal semitone

> improved with linear interpolation. I'll test both versions if I can

> ever successfully compile Timidity for Windows.

send you ZynAddSubFX instruments because I'm playing with it

now. Maybe other people can help you there as well.

Graham - Hello Graham, a late reply:

On Nov 2, 2009, at 8:05 AM, Graham Breed wrote:

> Ozan Yarman wrote:

>> ✩ ✩ ✩

>> www.ozanyarman.com

>>

>> On Oct 31, 2009, at 7:38 AM, Graham Breed wrote:

>>

>>> Ozan Yarman wrote:

>>>

>>>> So, if I eliminate the pitchbend lookup tables in Timidity

>>>> entirely,

>>>> do I arrive at MTS with 16384 increments per interval (semitone,

>>>> wholetone, etc...)?

>>> Yes. But it's only as good as the sample set you're using.

>>> If the samples aren't tuned that accurately, the results

>>> won't be anyway. That's why you should go for a purely

>>> algorithmic approach for high-precision tuning.

>>

>> So you mean that it is safer to keep the PB lookup tables and

>> implement linear interpolation?

>

> No, I mean it may not be worth bothering. If your samples

> aren't tuned to MTS precision it doesn't matter how

> precisely Timidity retunes them -- unless it does something

> clever with pitch recognition, which I doubt.

I have experienced firsthand that the same soundfont contains patches

that respond differently to pitch bends. One patch was a Reed Organ

that only accepted cent increments, and the other was a Fantasia Pad

that at least accepted 0.39 cent increments (due to the restriction of

Timidity++ maybe?).

> But

> ZynAddSubFX or VAZ Plus or Csound don't require real-world

> samples and so you can get much better control over the

> pitch. So if you really care about this level of precision

> you may be better off without a sampler.

>

I concur.

> If you want to work with SoundFonts you may have to stomach

> this level of imprecision. I have a vague idea that the

> SoundFont standard doesn't specify the pitch of samples any

> more precisely than Timidity's tuning tables anyway ...

Yes, there is always the danger of that happening.

> which would be a good reason why Timdity uses that level of

> precision.

Possibly.

>

>> Send me both a version of tables.c with no lookup tables and maximum

>> precision and another version with 256 divisions of the equal

>> semitone

>> improved with linear interpolation. I'll test both versions if I can

>> ever successfully compile Timidity for Windows.

>

> I can do that if you're ready to compile it.

I found this document on the internet for the compiling of Timidity++:

http://www.csee.umbc.edu/help/sound/TiMidity++-2.13.2/doc/C/README.w32

It seems a lot of work, but I already set up Mingw and Msys (am not

sure what additional libraries and components are needed), Got the

pexports, pdcurses... I downloaded Oggvorbis, Gogo nocoder, Flac,

Portaudio and Portmidi, but the instructions require me to compile

them seperately, at which I was not successful.

> I can also

> send you ZynAddSubFX instruments because I'm playing with it

> now. Maybe other people can help you there as well.

>

Yes, I would very much like to have your ZASFX instruments.

>

> Graham

>

>

Cordially,

Oz.