00001 #ifndef __CMusicMath__
00002 #define __CMusicMath__
00003
00004 #include "CTimeSignature.hpp"
00005 #include <Basics/CString.hpp>
00006
00007
00008
00009 using Exponent::Music::CTimeSignature;
00010 using Exponent::Basics::CString;
00011
00012
00013
00014 namespace Exponent
00015 {
00016 namespace Music
00017 {
00035 class CMusicMath
00036 {
00037 public:
00038
00039
00040
00041 const static double CMUSIC_MATH_FREQUENCY[];
00042 const static double CMUSIC_MATH_TIME[];
00043 const static double CMUSIC_MATH_SONG_PHASE[];
00044 const static double CMUSIC_MATH_SONG_POSITION[];
00046
00047
00052 enum ETempoDivision
00053 {
00054
00055 e_sixtyFourBars = 0,
00056 e_thirtyTwoBars,
00057 e_sixteenBars,
00058 e_eightBars,
00059 e_fourBars,
00060 e_twoBars,
00061 e_oneBar,
00062 e_halfBar,
00063 e_quarterBar,
00064 e_eigthBar,
00065 e_sixteenthBar,
00066 e_thirtySecondBar,
00067 e_sixtyFourthBar,
00069
00070 e_sixtyFourBarsTriplet,
00071 e_thirtyTwoBarsTriplet,
00072 e_sixteenBarsTriplet,
00073 e_eightBarsTriplet,
00074 e_fourBarsTriplet,
00075 e_twoBarsTriplet,
00076 e_oneBarTriplet,
00077 e_halfBarTriplet,
00078 e_quarterBarTriplet,
00079 e_eigthBarTriplet,
00080 e_sixteenthBarTriplet,
00081 e_thirtySecondBarTriplet,
00082 e_sixtyFourthBarTriplet,
00084
00085 e_sixtyFourBarsDotted,
00086 e_thirtyTwoBarsDotted,
00087 e_sixteenBarsDotted,
00088 e_eightBarsDotted,
00089 e_fourBarsDotted,
00090 e_twoBarsDotted,
00091 e_oneBarDotted,
00092 e_halfBarDotted,
00093 e_quarterBarDotted,
00094 e_eigthBarDotted,
00095 e_sixteenthBarDotted,
00096 e_thirtySecondBarDotted,
00097 e_sixtyFourthBarDotted,
00099 e_numTempoDivisions
00100 };
00101
00102
00103
00111 static double getRateInMilliseconds(const double bpm, const ETempoDivision tempoDivision, const CTimeSignature &timeSignature);
00112
00119 static double getRateInHertz(const double bpm, const ETempoDivision tempoDivision);
00120
00127 static ETempoDivision getClosestTempoDivisionToRateInHertz(const double bpm, const double frequency);
00128
00134 static double getPhase(const ETempoDivision tempoDivision);
00135
00141 static double getSongPhasePosition(const ETempoDivision tempoDivision);
00142
00143
00144
00151 static double getNumberOfSamples(const double sampleRate, const double lengthInSeconds);
00152
00153
00154
00160 static long getClosestMidiNote(const double frequency);
00161
00167 static double getNoteFrequency(const long note);
00168
00177 static double getNoteFrequency(const long note, const long octaveDetune, const long semiDetune, const long fineDetune);
00178
00179
00180
00187 static double getTempoNoteShift(const double originalBpm, const double newBpm);
00188
00195 static double getTimeStretch(const double originalBpm, const double newBpm);
00196
00203 static double getNewTempoPitchShift(const double shift, const double bpm);
00204
00212 static double getBpmFromTime(const double length, const CTimeSignature &timeSignature, const long numberOfBeats = 4);
00213
00221 static double getTimeFromBpm(const double bpm, const CTimeSignature &timeSignature, const long numberOfBeats = 4);
00222
00223
00224
00230 static void getADivisionString(CString &theString, const ETempoDivision tempoDivision);
00231
00232
00233
00234 private:
00235
00236
00237
00242 enum ETempoDivisionType
00243 {
00244 e_straight = 0,
00245 e_triplet,
00246 e_dotted,
00247 };
00248
00249
00250
00255 class CFrequencyTable
00256 {
00257 public:
00258
00262 CFrequencyTable()
00263 {
00264
00265 const double kappa = 1.059463094359;
00266
00267
00268 double frequency = 6.875;
00269
00270
00271 frequency *= kappa;
00272
00273
00274 frequency *= kappa;
00275
00276
00277 frequency *= kappa;
00278
00279
00280 for (long i = 0; i < 128; i++)
00281 {
00282 m_frequencyTable[i] = frequency;
00283 frequency *= kappa;
00284 }
00285 }
00286
00292 CFrequencyTable &operator = (const CFrequencyTable &table)
00293 {
00294
00295 for (long i = 0; i < 128; i++)
00296 {
00297 m_frequencyTable[i] = table.m_frequencyTable[i];
00298 }
00299 return *this;
00300 }
00301
00307 double getFrequency(const long index) const
00308 {
00309 if (index >= 0 && index < 128)
00310 {
00311 return m_frequencyTable[index];
00312 }
00313 return 0.0;
00314 }
00315
00316
00317
00318 protected:
00319
00320
00321
00322 double m_frequencyTable[128];
00323 };
00324
00325
00326
00333 static ETempoDivision getAdjustedTempoDivision(const ETempoDivision division, ETempoDivisionType &type);
00334
00341 static double convertValueToTempoDivisionType(const double value, const ETempoDivisionType type);
00342
00343
00344
00345 const static CFrequencyTable CMUSIC_MATH_FREQUENCY_TABLE;
00347 const static double CMUSIC_MATH_TRIPLET_TIME;
00348 const static double CMUSIC_MATH_DOTTED_TIME;
00349 };
00350 }
00351 }
00352 #endif // End of CMusicMath.hpp