-//! convert frequency to a float number of half-tones from A3
-/*!
- * \param freq the frequency to convert to \f$\in R+\f$ {Hz}
- * \param AFreq tuning frequency of the A3 (Usualy 440) {Hz}
- * \return the float number of half-tones from A3 \f$\in R\f$
- */
-inline double f2hf(double freq, double AFreq=GetAFreq()) {return 12.0*(log(freq)-log(AFreq))/log(2.0);}
-// TODO VERIF
-// le ht doit �re le ht le plus proche de freq !! et pas un simple arrondi en dessous de la valeur r�l !!
-//! convert frequency to number of half-tones from A3
-/*!
- * \param freq the frequency to convert to \f$\in R+\f$ {Hz}
- * \param AFreq tuning frequency of the A3 (Usualy 440) {Hz}
- * \return the number of half-tones from A3. Rounded to the nearest half-tones(
- * not a simple integer convertion of \ref f2hf ) \f$\in R\f$
- */
-inline int f2h(double freq, double AFreq=GetAFreq())
-{
- double ht = f2hf(freq, AFreq);
- if(ht>0) return int(ht+0.5);
- if(ht<0) return int(ht-0.5);
- return 0;
-}
-//! convert number of half-tones to frequency
-/*!
- * \param ht number of half-tones to convert to \f$\in Z\f$
- * \param AFreq tuning frequency of the A3 (Usualy 440) {Hz}
- * \return the converted frequency
- */
-inline double h2f(double ht, double AFreq=GetAFreq()) {return AFreq * pow(2.0, ht/12.0);}
-
-//! convert half-tones from A3 to the corresponding note name
-/*!
- * \param ht number of half-tones to convert to \f$\in Z\f$
- * \param local
- * \return his name (Do, Re, Mi, Fa, Sol, La, Si; with '#' if needed)
- */
-inline string h2n(int ht, NotesName local=GetNotesName(), int tonality=GetTonality(), bool show_oct=true)
-{
- ht += tonality;
-
- int oct = 4;
- while(ht<0)
+ //! convert frequency to a float number of chromatic half-tones from A3
+ /*!
+ * \param freq the frequency to convert to \f$\in R+\f$ {Hz}
+ * \param AFreq tuning frequency of the A3 (Usualy 440) {Hz}
+ * \return the float number of half-tones from A3 \f$\in R\f$
+ */
+ inline double f2hf(double freq, double AFreq=GetAFreq())
+ {
+ return 17.3123404906675624 * log(freq/AFreq); //12.0*(log(freq)-log(AFreq))/log(2.0)
+ }
+ //! find the halftone in the array for non-chromatic tunings
+ // TODO:
+ // Decide wether the step from 12/2 for linar search to log_2(12) for a
+ // binary search really matters in a FFT-bound program
+ /*!
+ * \param relFreq the frequency divided by the frequency of the next lower A
+ * \return the number of halftones above this A
+ */
+ inline int f2h_find(double relFreq)
+ {
+ if (relFreq < s_semitones[1])
+ {
+ if (s_semitones[1] / relFreq > relFreq / s_semitones[0])
+ {
+ return 0;
+ }
+ else
+ {
+ return 1;
+ }
+ }
+ else
+ {
+ int i;
+ for (i = 2; i < 12; i += 1)
+ {
+ if (relFreq < s_semitones[i]) { break; }
+ }
+ if (s_semitones[i] / relFreq > relFreq / s_semitones[i - 1])
+ {
+ return i - 1;
+ }
+ else
+ {
+ return i;
+ }
+ }
+ }
+ // TODO VERIF
+ // le ht doit �re le ht le plus proche de freq !! et pas un simple arrondi en dessous de la valeur r�l !!
+ //! convert frequency to number of half-tones from A3
+ /*!
+ * \param freq the frequency to convert to \f$\in R+\f$ {Hz}
+ * \param AFreq tuning frequency of the A3 (Usualy 440) {Hz}
+ * \return the number of half-tones from A3. Rounded to the nearest half-tones(
+ * not a simple integer convertion of \ref f2hf ) \f$\in R\f$
+ */
+ inline int f2h(double freq, double AFreq=GetAFreq(), int tuning=GetTuning())
+ {
+ if (CHROMATIC == tuning)
+ {
+ double ht = f2hf(freq, AFreq);
+ if(ht>0) return int(ht+0.5);
+ if(ht<0) return int(ht-0.5);
+ return 0;
+ }
+ else
+ {
+ if (freq <= 1.0) return UNDEFINED_SEMITONE;
+ int oct = 0;
+ while (freq < AFreq) { freq *= 2.0; oct -= 1; }
+ while (freq >= 2.0 * AFreq) { freq /= 2.0; oct += 1; }
+ int ht = f2h_find(freq/AFreq);
+ return (12 * oct + ht);
+ }
+ }
+ //! convert number of chromatic half-tones to frequency
+ /*!
+ * \param ht number of half-tones to convert to \f
+ * \param AFreq tuning frequency of the A3 (Usualy 440) {Hz}
+ * \return the converted frequency
+ */
+ inline double h2f(double ht, double AFreq=GetAFreq())