mirror of
https://github.com/cookiengineer/audacity
synced 2025-05-07 23:32:53 +02:00
170 lines
6.1 KiB
C++
170 lines
6.1 KiB
C++
/**********************************************************************
|
|
|
|
Audacity: A Digital Audio Editor
|
|
Audacity(R) is copyright (c) 1999-2012 Audacity Team.
|
|
License: GPL v2. See License.txt.
|
|
|
|
PitchName.cpp
|
|
Vaughan Johnson and Dominic Mazzoni.
|
|
|
|
******************************************************************//**
|
|
|
|
\file PitchName.cpp
|
|
\brief Utilities for converting from frequency to pitch
|
|
and from pitch to absolute (e.g., C4 for middle C)
|
|
or nominal (A through G#) pitch name.
|
|
|
|
*//*******************************************************************/
|
|
|
|
|
|
#include "Audacity.h"
|
|
#include "PitchName.h"
|
|
|
|
#include <math.h>
|
|
#include <stdio.h>
|
|
|
|
#include "Internat.h"
|
|
|
|
|
|
double FreqToMIDInote(const double freq)
|
|
{
|
|
// Make the calculation relative to A440 (A4), note number 69.
|
|
return (69.0 + (12.0 * (log(freq / 440.0) / log(2.0))));
|
|
}
|
|
|
|
double MIDInoteToFreq(const double dMIDInote)
|
|
{
|
|
return (440.0 * pow(2.0, (dMIDInote - 69.0) / 12.0));
|
|
}
|
|
|
|
unsigned int PitchIndex(const double dMIDInote)
|
|
{
|
|
// MIDI numbers can be negative. Round in the right direction.
|
|
double dRound = (dMIDInote < 0.0) ? -0.5 : 0.5;
|
|
int nPitchIndex = ((int)(dMIDInote + dRound) % 12);
|
|
|
|
// Because of the modulo, we know we're within 12 of positive, if dMIDInote is negative.
|
|
if (nPitchIndex < 0)
|
|
nPitchIndex += 12;
|
|
|
|
return nPitchIndex;
|
|
}
|
|
|
|
int PitchOctave(const double dMIDInote)
|
|
{
|
|
double dRound = (dMIDInote < 0.0) ? -0.5 : 0.5;
|
|
return ((int)((dMIDInote + dRound) / 12.0) - 1);
|
|
}
|
|
|
|
|
|
TranslatableString PitchName(const double dMIDInote, const PitchNameChoice choice)
|
|
{
|
|
static const TranslatableString sharpnames[12] = {
|
|
/* i18n-hint: Name of a musical note in the 12-tone chromatic scale */
|
|
XO("C"),
|
|
/* i18n-hint: Name of a musical note in the 12-tone chromatic scale */
|
|
XO("C\u266f"),
|
|
/* i18n-hint: Name of a musical note in the 12-tone chromatic scale */
|
|
XO("D"),
|
|
/* i18n-hint: Name of a musical note in the 12-tone chromatic scale */
|
|
XO("D\u266f"),
|
|
/* i18n-hint: Name of a musical note in the 12-tone chromatic scale */
|
|
XO("E"),
|
|
/* i18n-hint: Name of a musical note in the 12-tone chromatic scale */
|
|
XO("F"),
|
|
/* i18n-hint: Name of a musical note in the 12-tone chromatic scale */
|
|
XO("F\u266f"),
|
|
/* i18n-hint: Name of a musical note in the 12-tone chromatic scale */
|
|
XO("G"),
|
|
/* i18n-hint: Name of a musical note in the 12-tone chromatic scale */
|
|
XO("G\u266f"),
|
|
/* i18n-hint: Name of a musical note in the 12-tone chromatic scale */
|
|
XO("A"),
|
|
/* i18n-hint: Name of a musical note in the 12-tone chromatic scale */
|
|
XO("A\u266f"),
|
|
/* i18n-hint: Name of a musical note in the 12-tone chromatic scale */
|
|
XO("B"),
|
|
};
|
|
|
|
static const TranslatableString flatnames[12] = {
|
|
/* i18n-hint: Name of a musical note in the 12-tone chromatic scale */
|
|
XO("C"),
|
|
/* i18n-hint: Name of a musical note in the 12-tone chromatic scale */
|
|
XO("D\u266d"),
|
|
/* i18n-hint: Name of a musical note in the 12-tone chromatic scale */
|
|
XO("D"),
|
|
/* i18n-hint: Name of a musical note in the 12-tone chromatic scale */
|
|
XO("E\u266d"),
|
|
/* i18n-hint: Name of a musical note in the 12-tone chromatic scale */
|
|
XO("E"),
|
|
/* i18n-hint: Name of a musical note in the 12-tone chromatic scale */
|
|
XO("F"),
|
|
/* i18n-hint: Name of a musical note in the 12-tone chromatic scale */
|
|
XO("G\u266d"),
|
|
/* i18n-hint: Name of a musical note in the 12-tone chromatic scale */
|
|
XO("G"),
|
|
/* i18n-hint: Name of a musical note in the 12-tone chromatic scale */
|
|
XO("A\u266d"),
|
|
/* i18n-hint: Name of a musical note in the 12-tone chromatic scale */
|
|
XO("A"),
|
|
/* i18n-hint: Name of a musical note in the 12-tone chromatic scale */
|
|
XO("B\u266d"),
|
|
/* i18n-hint: Name of a musical note in the 12-tone chromatic scale */
|
|
XO("B"),
|
|
};
|
|
|
|
static const TranslatableString bothnames[12] = {
|
|
/* i18n-hint: Name of a musical note in the 12-tone chromatic scale */
|
|
XO("C"),
|
|
/* i18n-hint: Two, alternate names of a musical note in the 12-tone chromatic scale */
|
|
XO("C\u266f/D\u266d"),
|
|
/* i18n-hint: Name of a musical note in the 12-tone chromatic scale */
|
|
XO("D"),
|
|
/* i18n-hint: Two, alternate names of a musical note in the 12-tone chromatic scale */
|
|
XO("D\u266f/E\u266d"),
|
|
/* i18n-hint: Name of a musical note in the 12-tone chromatic scale */
|
|
XO("E"),
|
|
/* i18n-hint: Name of a musical note in the 12-tone chromatic scale */
|
|
XO("F"),
|
|
/* i18n-hint: Two, alternate names of a musical note in the 12-tone chromatic scale */
|
|
XO("F\u266f/G\u266d"),
|
|
/* i18n-hint: Name of a musical note in the 12-tone chromatic scale */
|
|
XO("G"),
|
|
/* i18n-hint: Two, alternate names of a musical note in the 12-tone chromatic scale */
|
|
XO("G\u266f/A\u266d"),
|
|
/* i18n-hint: Name of a musical note in the 12-tone chromatic scale */
|
|
XO("A"),
|
|
/* i18n-hint: Two, alternate names of a musical note in the 12-tone chromatic scale */
|
|
XO("A\u266f/B\u266d"),
|
|
/* i18n-hint: Name of a musical note in the 12-tone chromatic scale */
|
|
XO("B"),
|
|
};
|
|
|
|
const TranslatableString *table = nullptr;
|
|
switch ( choice ) {
|
|
case PitchNameChoice::Sharps: table = sharpnames; break;
|
|
case PitchNameChoice::Flats: table = flatnames; break;
|
|
case PitchNameChoice::Both: table = bothnames; break;
|
|
default: wxASSERT(false); break;
|
|
}
|
|
|
|
return table[PitchIndex(dMIDInote)];
|
|
}
|
|
|
|
TranslatableString PitchName_Absolute(const double dMIDInote, const PitchNameChoice choice)
|
|
{
|
|
// The format string is not localized. Should it be?
|
|
return Verbatim( wxT("%s%d") )
|
|
.Format( PitchName(dMIDInote, choice), PitchOctave(dMIDInote) );
|
|
}
|
|
|
|
double PitchToMIDInote(const unsigned int nPitchIndex, const int nPitchOctave)
|
|
{
|
|
return ((double)nPitchIndex + (((double)nPitchOctave + 1.0) * 12.0));
|
|
}
|
|
|
|
double PitchToFreq(const unsigned int nPitchIndex, const int nPitchOctave)
|
|
{
|
|
return MIDInoteToFreq(PitchToMIDInote(nPitchIndex, nPitchOctave));
|
|
}
|