Loading ...
Sorry, an error occurred while loading the content.

Re: [tuning] Better tuning resolution with Timidity, but still not good enough

Expand Messages
  • Ozan Yarman
    ✩ ✩ ✩ www.ozanyarman.com ... So you mean that it is safer to keep the PB lookup tables and implement linear interpolation? ... Send me both a version of
    Message 1 of 29 , Nov 1, 2009
    • 0 Attachment
      ✩ ✩ ✩
      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.
    • Ozan Yarman
      ✩ ✩ ✩ www.ozanyarman.com ... Where l is ln, or neperian (natural) logarithm of course. The same results can be obtained by the formula: 2^(cents/1200)
      Message 2 of 29 , Nov 1, 2009
      • 0 Attachment
        ✩ ✩ ✩
        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.
      • Graham Breed
        ... That s it. But not, as it happens, in bc, because the ^ operator doesn t work with non-integer powers. And this may correspond to how the underlying
        Message 3 of 29 , Nov 1, 2009
        • 0 Attachment
          Ozan Yarman wrote:

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

          > Where l is ln, or neperian (natural) logarithm of course. The same
          > results can be obtained by the formula:
          >
          > 2^(cents/1200)

          That's it. But not, as it happens, in bc, because the ^
          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
          >> 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?

          There are 14 bits of fine tuning, right? 256 requires 8
          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
          >> 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?

          That's it. But it's still easier to keep the original
          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
          >> 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!

          No, that's an example of an application that doesn't bother
          with interpolation. ZynAddSubFX is apparently better,
          though, and Csound can use the 64-bit standard library.


          Graham
        • Graham Breed
          ... 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
          Message 4 of 29 , Nov 1, 2009
          • 0 Attachment
            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. 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
            > 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 can also
            send you ZynAddSubFX instruments because I'm playing with it
            now. Maybe other people can help you there as well.


            Graham
          • Ozan Yarman
            Hello Graham, a late reply: ... I have experienced firsthand that the same soundfont contains patches that respond differently to pitch bends. One patch was a
            Message 5 of 29 , Nov 13, 2009
            • 0 Attachment
              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.
            Your message has been successfully submitted and would be delivered to recipients shortly.