1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-09-17 16:50:26 +02:00

Plot Spectrum, Change Pitch localize pitch names; Unicode sharp/flat

This commit is contained in:
Paul Licameli 2017-10-03 11:42:59 -04:00
parent 8b86d46884
commit 3fbfef0eb1
3 changed files with 103 additions and 98 deletions

View File

@ -20,6 +20,7 @@
#include <math.h>
#include <stdio.h>
#include "Audacity.h"
#include "PitchName.h"
@ -54,96 +55,105 @@ int PitchOctave(const double dMIDInote)
}
static wxChar gPitchName[10];
static wxChar * pPitchName;
wxChar * PitchName(const double dMIDInote, const bool bWantFlats /* = false */)
wxString PitchName(const double dMIDInote, const PitchNameChoice choice)
{
pPitchName = gPitchName;
static const wxString 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"),
};
switch (PitchIndex(dMIDInote)) {
case 0:
*pPitchName++ = wxT('C');
break;
case 1:
if (bWantFlats) {
*pPitchName++ = wxT('D');
*pPitchName++ = wxT('b');
} else {
*pPitchName++ = wxT('C');
*pPitchName++ = wxT('#');
}
break;
case 2:
*pPitchName++ = wxT('D');
break;
case 3:
if (bWantFlats) {
*pPitchName++ = wxT('E');
*pPitchName++ = wxT('b');
} else {
*pPitchName++ = wxT('D');
*pPitchName++ = wxT('#');
}
break;
case 4:
*pPitchName++ = wxT('E');
break;
case 5:
*pPitchName++ = wxT('F');
break;
case 6:
if (bWantFlats) {
*pPitchName++ = wxT('G');
*pPitchName++ = wxT('b');
} else {
*pPitchName++ = wxT('F');
*pPitchName++ = wxT('#');
}
break;
case 7:
*pPitchName++ = wxT('G');
break;
case 8:
if (bWantFlats) {
*pPitchName++ = wxT('A');
*pPitchName++ = wxT('b');
} else {
*pPitchName++ = wxT('G');
*pPitchName++ = wxT('#');
}
break;
case 9:
*pPitchName++ = wxT('A');
break;
case 10:
if (bWantFlats) {
*pPitchName++ = wxT('B');
*pPitchName++ = wxT('b');
} else {
*pPitchName++ = wxT('A');
*pPitchName++ = wxT('#');
}
break;
case 11:
*pPitchName++ = wxT('B');
break;
static const wxString 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 wxString 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 wxString *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;
}
*pPitchName = wxT('\0');
return gPitchName;
return table[PitchIndex(dMIDInote)];
}
wxChar * PitchName_Absolute(const double dMIDInote, const bool bWantFlats /* = false */)
wxString PitchName_Absolute(const double dMIDInote, const PitchNameChoice choice)
{
PitchName(dMIDInote, bWantFlats);
// PitchName sets pPitchName to the next available char in gPitchName,
// so it's ready to append the register number.
wxSnprintf(pPitchName, 8, wxT("%d"), PitchOctave(dMIDInote));
return gPitchName;
// The format string is not localized. Should it be?
return wxString::Format(
wxT("%s%d"), PitchName(dMIDInote, choice), PitchOctave(dMIDInote) );
}
double PitchToMIDInote(const unsigned int nPitchIndex, const int nPitchOctave)

View File

@ -40,15 +40,20 @@ unsigned int PitchIndex(const double dMIDInote);
// MIDI note number 0 is C-1 in Scientific pitch notation.
int PitchOctave(const double dMIDInote);
enum class PitchNameChoice { Sharps, Flats, Both };
// PitchName takes dMIDInote (per result from
// FreqToMIDInote) and returns a standard pitch/note name [C, C#, etc.).
// Sharps are the default, unless, bWantFlats is true.
wxChar * PitchName(const double dMIDInote, const bool bWantFlats = false);
wxString PitchName(
const double dMIDInote,
const PitchNameChoice choice = PitchNameChoice::Sharps );
// PitchName_Absolute does the same thing as PitchName, but appends
// the octave number, e.g., instead of "C" it will return "C4"
// if the dMIDInote corresonds to middle C, i.e., is 60.
wxChar * PitchName_Absolute(const double dMIDInote, const bool bWantFlats = false);
wxString PitchName_Absolute(
const double dMIDInote,
const PitchNameChoice choice = PitchNameChoice::Sharps);
double PitchToMIDInote(const unsigned int nPitchIndex, const int nPitchOctave);

View File

@ -228,18 +228,8 @@ void EffectChangePitch::PopulateOrExchange(ShuttleGui & S)
DeduceFrequencies(); // Set frequency-related control values based on sample.
wxArrayString pitch;
pitch.Add(wxT("C"));
pitch.Add(wxT("C#/Db"));
pitch.Add(wxT("D"));
pitch.Add(wxT("D#/Eb"));
pitch.Add(wxT("E"));
pitch.Add(wxT("F"));
pitch.Add(wxT("F#/Gb"));
pitch.Add(wxT("G"));
pitch.Add(wxT("G#/Ab"));
pitch.Add(wxT("A"));
pitch.Add(wxT("A#/Bb"));
pitch.Add(wxT("B"));
for (int ii = 0; ii < 12; ++ii)
pitch.Add( PitchName( ii, PitchNameChoice::Both ) );
S.SetBorder(5);