- Main Page
- Namespaces
- Files

- File List
- File Members

# C:/Musimathics_local/Musimat/MusimatTutorial/B0202.cpp File Reference

`#include "MusimatTutorial.h"`

Go to the source code of this file.

## Functions
| MusimatTutorialSection (B0202)
Void | realToRational (Real f, Integer Reference num, Integer Reference den)
Static Void | para1 ()
Real | realRhythm (Rhythm x)
Void | para2 ()

## Function Documentation

MusimatTutorialSection | ( | B0202 |  | ) |

Definition at line 2 of file B0202.cpp.

References para1(), and para2().

    00002                               {
    00003 Print("*** B.2.2 Rhythm ***");
    00004 /*****************************************************************************
    00005
    00006 B.2.2 Rhythm
    00007
    00008 Duration in common music notation is expressed as a fraction of a whole note. For example a whole
    00009 note equals four quarter notes:
    00010
    00011 w  = q + q + q + q
    00012
    00013 /*****************************************************************************
    00014 We could write this mathematically as follows:
    00015
    00016 1   1 1 1 1
    00017 - = -,-,-,-
    00018 1   4 4 4 4
    00019
    00020 which suggests using rational fractions to represent rhythmic durations. A rational fraction is a
    00021 ratio of integers. Musimat comes with a built-in data type called Rhythm, which emulates com-
    00022 mon musical notation conventions regarding rhythm. For example, the quarter note is defined as
    00023 *****************************************************************************/
    00024
    00025 Rhythm Q = Rhythm( 1, 4 );
    00026
    00027 /*****************************************************************************
    00028 The first number is the numerator of the rational fraction, the second is the denominator. Note that
    00029 we can’t write Rhythm(1/4) because the integer quotient of 1/4 is 0 with a remainder of 1; integer
    00030 division is performed if both the numerator and denominator are integers, which won’t work here.
    00031 Specifying the numerator and denominator separately avoids this problem and has some other
    00032 numerical advantages as well. Executing Print(Q); prints (1, 4). Internally, Rhythm()
    00033 keeps the integer numerator and denominator values separately.
    00034
    00035 Rhythmic duration can also be given as a real expression.
    00036 *****************************************************************************/
    00037
    00038 Print(Rhythm(0.5));
    00039
    00040 /*****************************************************************************
    00041 prints (1, 2). How does Rhythm() convert this real expression into a ratio of integers? It does so by
    00042 calling the following function internally:
    00043 *****************************************************************************/
    00044         para1();  // Step into this function to continue the tutorial
    00045         para2();  // Step into this function to continue the tutorial
    00046 }

Static Void para1 | ( |  | ) |

Definition at line 67 of file B0202.cpp.

    00067                     {
    00068 /*****************************************************************************
    00069 Function realToRational() takes a Real value f and attempts to find a rational fraction
    00070 num/den that is as close as possible to it. It starts by setting num = den = 1 and asking whether
    00071 num/den is already close enough to f. If so, it returns. Otherwise, it asks whether (num+1) / den
    00072 is closer than num / (den+1). If so, it increments num; otherwise it increments den and repeats the
    00073 process. Because num and den are Reference arguments, any changes to these variables within
    00074 realToRational() are reflected in the value of the actual arguments supplied to it.
    00075
    00076 This method can be used to find rational approximations to most any real value. For example,
    00077 *****************************************************************************/
    00078
    00079 Real Pi = 3.14159265;
    00080 Print(Rhythm(Pi));
    00081
    00082 /*****************************************************************************
    00083 prints (1953857, 621932). Note that 1953857/621932 = 3.14159265, which is
    00084 pretty close to the value of Pi. This method is limited by the precision of the computer hardware.
    00085 The precision of a rational approximation depends upon the value of the built-in variables
    00086 iterations and limit. For example, with the values shown in the preceding code, it took
    00087 realToRational() 2,575,787 trials to come up with its best approximation of Pi, requiring
    00088 about 1 second on my computer. The iteration and limit parameters can be set to whatever
    00089 values produce the optimal performance/accuracy cost/benefit ratio. Barring obscure rhythms
    00090 (nothing, say, beyond triplet eights), iterations = 240 and limit = 1.0/480 should be
    00091 satisfactory.
    00092
    00093 Although the details go beyond the scope of this book, here is a sketch of how Rhythm() uses
    00094 realToRational():
    00095
    00096 Rhythm(Real x) {
    00097         Integer num, den; // internal parameters for Rhythm
    00098         realToRational( x, num, den ); // convert x to num / den rational fraction
    00099         // . . .
    00100 }
    00101
    00102 When called with a Real argument, Rhythm() calls realToRational() to set its internal integer
    00103 rational fraction values.
    00104
    00105 Musimat provides built-in definitions for standard binary divisions of a whole note:
    00106 *****************************************************************************/
    00107
    00108 Rhythm Whole = Rhythm(1.0/1.0);
    00109 Rhythm Half = Rhythm(1.0/2.0);
    00110 Rhythm Quarter = Rhythm(1.0/4.0);
    00111 Rhythm Eighth = Rhythm(1.0/8.0);
    00112 Rhythm Sixteenth = Rhythm(1.0/16.0);
    00113
    00114 /*****************************************************************************
    00115 It is easy to define ternary divisions as well. For example, a triplet eighth is Rhythm(1.0/12.0)
    00116 because there are  triplet eighths per whole note. By the same reasoning, a quintuplet
    00117 eighth is
    00118 *****************************************************************************/
    00119
    00120 Rhythm Qe = Rhythm(1.0/20.0);
    00121
    00122 /*****************************************************************************
    00123 We can express compound rhythms by addition. For example, a dotted half note is
    00124 *****************************************************************************/
    00125
    00126 Rhythm Hd = Rhythm(1.0/2.0 + 1.0/4.0);                                  // dotted half
    00127
    00128 /*****************************************************************************
    00129 Equivalently,
    00130 *****************************************************************************/
    00131
    00132 Rhythm H1 = Rhythm(3.0 / 4.0);                                                  // also a dotted half
    00133
    00134 /*****************************************************************************
    00135 We can also do arithmetic directly with rhythms. For example,
    00136 *****************************************************************************/
    00137
    00138 Print(Eighth+Sixteenth);
    00139
    00140 /*****************************************************************************
    00141 prints (3, 16).
    00142
    00143 Also,
    00144 *****************************************************************************/
    00145
    00146 Print(Whole - Sixteenth);
    00147
    00148 /*****************************************************************************
    00149 prints (15,16),
    00150 *****************************************************************************/
    00151
    00152 Print(Quarter * Sixteenth);
    00153
    00154 /*****************************************************************************
    00155 prints (1,64), and
    00156 *****************************************************************************/
    00157
    00158 Print(Quarter / Sixteenth);
    00159
    00160 /*****************************************************************************
    00161 prints (4,1). The last value corresponds to a duration of four whole notes.
    00162
    00163 We can extract the numerator and denominator from Rhythm():
    00164 *****************************************************************************/
    00165
    00166 Integer num, den;
    00167 Rhythm z = Rhythm(Eighth + Sixteenth, num, den); // assigns rational fraction for E+S to num and den
    00168
    00169 /*****************************************************************************
    00170 Used this way, Rhythm() calculates the rational fraction of its first argument and sets num and
    00171 den by reference to the result. For the preceding example, num is set to 3 and den is set to 16. We
    00172 can leverage this capability to obtain the duration of a rhythm as a real number:
    00173 *****************************************************************************/
    00174 }

Void para2 | ( |  | ) |

Definition at line 182 of file B0202.cpp.

    00182              {
    00183 /*****************************************************************************
    00184 Then, for example, executing Print(realRhythm(E + S)); prints 0.1875.
    00185 As with pitches, we can make lists of rhythms.
    00186 *****************************************************************************/
    00187
    00188 RhythmList RL = RhythmList(Quarter, Eighth, Eighth, Eighth, Sixteenth, Sixteenth, Quarter);
    00189 Print(RL);
    00190
    00191 /*****************************************************************************
    00192 prints {(1,4), (1,8), (1,8), (1,8), (1,16), (1,16), (1,4)}.
    00193
    00194 *****************************************************************************/
    00195 }}

Real realRhythm | ( | Rhythm | x | ) |

Definition at line 176 of file B0202.cpp.

    00176                           {
    00177         Integer num, den;
    00178         Rhythm(x, num, den); // find rational fraction for x and set num and den
    00179         Return(Real(num)/Real(den)); // convert num and den to reals and divide
    00180 }

Void realToRational | ( | Real | f,
|  | Integer Reference | num,
|  | Integer Reference | den |
| ) |  |  |

Definition at line 48 of file B0202.cpp.

References x, and y.

    00048                                                                           {
    00049         Const Integer iterations = 3000000;
    00050         Const Real limit = 0.000000000001;
    00051         num = den = 1; // start off with ratio of 1/1
    00052         For (Integer i = 0; i < iterations; i = i + 1) {
    00053                 If (Abs( Real(num) / Real(den) - f ) < limit)
    00054                         Return; // we have reached the limit
    00055                 Else {
    00056                         Real x = Abs(Real(num+1) / Real(den) - f);
    00057                         Real y = Abs(Real(num) / Real(den+1) - f);
    00058                         If (x < y)
    00059                                 num = num + 1;
    00060                         Else
    00061                                 den = den + 1;
    00062                 }
    00063         }
    00064         Return; // if we get here, we've not converged on the limit
    00065 } // RealAbs() is just a version of Abs() that uses Real arithmetic