[LAD] C++11 user defined literals: Musical duration

From: Mario Lang <mlang@email-addr-hidden>
Date: Mon Feb 18 2013 - 20:10:08 EET

hi.

The following just manifested itself while experimenting with code. I
find it quite neat since it makes for quite natural looking constants:

class duration_log
{
  int8_t log;
public:
  constexpr duration_log(int log) : log(log) {}
  constexpr operator int() const { return log; }
  template<char...> friend duration_log constexpr operator"" _th();
};

           duration_log constexpr maxima = 3;
           duration_log constexpr longa = 2;
           duration_log constexpr breve = 1;
           duration_log constexpr whole = 0;
           duration_log constexpr half = -1;
           duration_log constexpr quarter = -2;
template<> duration_log constexpr operator"" _th<'8' >() { return -3; }
template<> duration_log constexpr operator"" _th<'1', '6' >() { return -4; }
template<> duration_log constexpr operator"" _th<'3', '2' >() { return -5; }
template<> duration_log constexpr operator"" _th<'6', '4' >() { return -6; }
template<> duration_log constexpr operator"" _th<'1', '2', '8'>() { return -7; }
template<> duration_log constexpr operator"" _th<'2', '5', '6'>() { return -8; }

---
(there is actually no need for the wrapper class duration_log, but it
 makes it easier to play with overloaded functions.  You could of course
 just replace duration_log with int, if you do not care for type safety.)
Now I can write things like "16_th" or "64_th".
It turns out that there is a quite neat formula for the typical music
notation duration calculation.  Given that the base rhythmic type is
expressed as a log (as in LilyPond for instance), the rational number of
the duration with a certain amount of dots and time modification (tuple) can be
written like this:
#include <boost/rational.hpp>
template<typename Rational = boost::rational<int>>
inline Rational augmented_rational( int log, unsigned dots
                                  , int numerator, int denominator
                                  )
{
  return log < 0 ? Rational { ((1 << (dots + 1)) - 1) * numerator
                            , denominator << -log << dots
                            }
                 : Rational { (((1 << (dots + 1)) - 1) << log) * numerator
                            , denominator << dots
                            };
}
---
This is quite efficient since there is no need to multiply or manipulate
rational numbers in any way.  You just get the final value straight out
of the expression.
Comments?
-- 
CYa,
  â¡â â —â Šâ •
_______________________________________________
Linux-audio-dev mailing list
Linux-audio-dev@lists.linuxaudio.org
http://lists.linuxaudio.org/listinfo/linux-audio-dev
Received on Mon Feb 18 20:15:08 2013

This archive was generated by hypermail 2.1.8 : Mon Feb 18 2013 - 20:15:08 EET