1 // Copyright 2004 "Gilles Degottex"
3 // This file is part of "Music"
5 // "Music" is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU Lesser General Public License as published by
7 // the Free Software Foundation; either version 2.1 of the License, or
8 // (at your option) any later version.
10 // "Music" is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU Lesser General Public License for more details.
15 // You should have received a copy of the GNU Lesser General Public License
16 // along with this program; if not, write to the Free Software
17 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
29 #include <CppAddons/CAMath.h>
30 #include <CppAddons/StringAddons.h>
34 enum NotesName{LOCAL_ANGLO, LOCAL_LATIN};
35 extern NotesName s_notes_name;
36 inline NotesName GetNotesName() {return s_notes_name;}
37 inline void SetNotesName(NotesName type) {s_notes_name = type;}
39 extern int s_tonality;
40 inline int GetTonality() {return s_tonality;}
41 inline void SetTonality(int tonality) {s_tonality = tonality;}
43 extern int s_sampling_rate;
44 inline int GetSamplingRate() {return s_sampling_rate;}
45 void SetSamplingRate(int sampling_rate);
47 extern double s_AFreq;
48 inline double GetAFreq() {return s_AFreq;}
49 void SetAFreq(double AFreq);
51 extern const int UNDEFINED_SEMITONE;
52 extern int s_semitone_min;
53 extern int s_semitone_max;
54 inline int GetSemitoneMin() {return s_semitone_min;}
55 inline int GetSemitoneMax() {return s_semitone_max;}
56 inline int GetNbSemitones() {return s_semitone_max-s_semitone_min+1;}
57 void SetSemitoneBounds(int semitone_min, int semitone_max);
59 struct SettingsListener
61 virtual void samplingRateChanged() {}
62 virtual void AFreqChanged() {}
63 virtual void semitoneBoundsChanged() {}
66 virtual ~SettingsListener();
69 extern list<SettingsListener*> s_settings_listeners;
70 void AddSettingsListener(SettingsListener* l);
71 void RemoveSettingsListener(SettingsListener* l);
73 //! convert frequency to a float number of half-tones from A3
75 * \param freq the frequency to convert to \f$\in R+\f$ {Hz}
76 * \param AFreq tuning frequency of the A3 (Usualy 440) {Hz}
77 * \return the float number of half-tones from A3 \f$\in R\f$
79 inline double f2hf(double freq, double AFreq=GetAFreq()) {return 12.0*(log(freq)-log(AFreq))/log(2.0);}
81 // le ht doit �re le ht le plus proche de freq !! et pas un simple arrondi en dessous de la valeur r�l !!
82 //! convert frequency to number of half-tones from A3
84 * \param freq the frequency to convert to \f$\in R+\f$ {Hz}
85 * \param AFreq tuning frequency of the A3 (Usualy 440) {Hz}
86 * \return the number of half-tones from A3. Rounded to the nearest half-tones(
87 * not a simple integer convertion of \ref f2hf ) \f$\in R\f$
89 inline int f2h(double freq, double AFreq=GetAFreq())
91 double ht = f2hf(freq, AFreq);
92 if(ht>0) return int(ht+0.5);
93 if(ht<0) return int(ht-0.5);
96 //! convert number of half-tones to frequency
98 * \param ht number of half-tones to convert to \f$\in Z\f$
99 * \param AFreq tuning frequency of the A3 (Usualy 440) {Hz}
100 * \return the converted frequency
102 inline double h2f(double ht, double AFreq=GetAFreq()) {return AFreq * pow(2.0, ht/12.0);}
104 //! convert half-tones from A3 to the corresponding note name
106 * \param ht number of half-tones to convert to \f$\in Z\f$
108 * \return his name (Do, Re, Mi, Fa, Sol, La, Si; with '#' if needed)
110 inline string h2n(int ht, NotesName local=GetNotesName(), int tonality=GetTonality(), bool show_oct=true)
126 if(ht>2) oct++; // octave start from C
127 // if(oct<=0) oct--; // skip 0-octave in occidental notations ??
130 // sprintf(coct, "%d", oct);
131 // string soct = coct;
135 soct = StringAddons::toString(oct);
137 if(local==LOCAL_ANGLO)
139 if(ht==0) return "A"+soct;
140 else if(ht==1) return "A#"+soct;
141 else if(ht==2) return "B"+soct;
142 else if(ht==3) return "C"+soct;
143 else if(ht==4) return "C#"+soct;
144 else if(ht==5) return "D"+soct;
145 else if(ht==6) return "D#"+soct;
146 else if(ht==7) return "E"+soct;
147 else if(ht==8) return "F"+soct;
148 else if(ht==9) return "F#"+soct;
149 else if(ht==10) return "G"+soct;
150 else if(ht==11) return "G#"+soct;
154 if(ht==0) return "La"+soct;
155 else if(ht==1) return "La#"+soct;
156 else if(ht==2) return "Si"+soct;
157 else if(ht==3) return "Do"+soct;
158 else if(ht==4) return "Do#"+soct;
159 else if(ht==5) return "Re"+soct;
160 else if(ht==6) return "Re#"+soct;
161 else if(ht==7) return "Mi"+soct;
162 else if(ht==8) return "Fa"+soct;
163 else if(ht==9) return "Fa#"+soct;
164 else if(ht==10) return "Sol"+soct;
165 else if(ht==11) return "Sol#"+soct;
171 inline int n2h(const std::string& note, NotesName local=LOCAL_ANGLO, int tonality=GetTonality())
177 std::vector<double> conv(const std::vector<double>& u, const std::vector<double>& v);
179 // TODO freq reffinement