数式での翻訳 |
---|
音名と音階の文字列としての結合で与えられる文字列を、音名と音階の組と同一視します。音名と音階の組全体の集合 Chou=OnMei×OnKai に属する文字列を調と呼びます。例えばDo♭♭WaseiTekiTanOnKaiは調です。実際には音名と音階の間にNoやWoShuOnToSuru等の文字列を挟んだり語順を逆にしたりするかもしれませんが、実装の都合上ここでは気にしないことにします。
第1射影と第2射影 Chou→OnMeiChou→OnKai をそれぞれGetOnMeiとGetOnKaiと置きます。
また写像 OnMeiTable:Chou×KaiMei→OnMei(N,n)↦OnMeiTable(N,n) を以下のように定めます:
- s=GetOnKai(N)∈OnKaiと置き、N0=GetKanOn(GetOnMei(N))∈KanOnと置き、S0=GetHenKaKiGou(GetOnMei(N))∈HenKaKiGouと置く。
- GetNum(N1)=GetNum(N0)+nを満たす唯一のN1∈KanOnを取る。
- ¯d=KanOnToPitchClass(N0)+PitchClassTable(s,n)−KanOnToPitchClass(N1)∈PitchClassと置く。
- d=Represent(¯d)∈{0,1,2,3,4,5,6,7,8,9,10,11}と置く。
- d⪇ならば、\textrm{GetNum}(S_1) = d + \textrm{GetNum}(S_0)を満たす唯一のS_1 \in \textrm{HenKaKiGou}を取る。
- d \geq 6ならば、\textrm{GetNum}(S_1) = d - 12 + \textrm{GetNum}(S_0)を満たす唯一のS_1 \in \textrm{HenKaKiGou}を取る。
- \textrm{OnMeiTable}((N,s),n) = (N_1,S_1)である。 (N,s)を固定した時に得られる写像 \begin{align} \mathbb{Z} & \to \textrm{OnMei} \\ n & \mapsto \textrm{OnMeiTable}((N,s),n + 7 \mathbb{Z}) \end{align} は周期7の文字列の列を定めます。例えば(N,s) = \textrm{Do♭♭WaseiTekiTanOnKai}である時、この写像の値は文字列\textrm{Do♭♭},\textrm{Re♭♭},\textrm{Mi♭♭♭},\textrm{Fa♭♭},\textrm{So♭♭},\textrm{La♭♭♭},\textrm{Ti♭♭}の繰り返しとなります。
C++での宣言 |
---|
調のクラスおよび関係する関数たちを以下のように宣言します。
class Chou
{
private:
OnMei m_N;
OnKai m_scale;
public:
inline Chou( const OnMei& N , const OnKai& scale = ChouOnKai() ) noexcept;
inline const OnMei& GetOnMei() const noexcept;
inline const OnKai& GetOnKai() const noexcept;
inline string Display() const noexcept;
inline KanOn KanOnTable( const KaiMei& num ) const noexcept;
inline HenKaKiGou HenKaKiGouTable( const KaiMei& num ) const noexcept;
inline OnMei OnMeiTable( const KaiMei& num ) const noexcept;
private:
HenKaKiGou HenKaKiGouTable_Body( const KaiMei& num , const KanOn& N ) const noexcept;
inline OnMei OnMeiTable_Body( const KaiMei& num , const KanOn& N ) const noexcept;
};
inline bool operator==( const Chou& N1 , const Chou& N2 ) noexcept;
inline bool operator!=( const Chou& N1 , const Chou& N2 ) noexcept;
C++での定義 |
---|
実際の実装例についてはこちらをご覧下さい。実装においては以下の仕様を要請します。
inline Chou::Chou( const OnMei& N , const OnKai& scale ) noexcept
はメンバ初期化子m_N( N )
,m_scale( scale )
で定める。inline const OnMei& Chou::GetOnMei() const noexcept
はreturn m_N
と定める。inline const OnKai& Chou::GetOnKai() const noexcep
はreturn m_scale
と定める。inline string Chou::Display() const noexcept
はreturn m_scale.Display() + ": " + m_N.Display()
と定める。inline KanOn Chou::KanOnTable( const KaiMei& num ) const noexcept
はreturn m_N.GetKanOn() + num
と定める。inline HenKaKiGou Chou::HenKaKiGouTable( const KaiMei& num ) const noexcept
はreturn HenKaKiGouTable_Body( num , KanOnTable( num ) )
と定める。inline OnMei Chou::OnMeiTable( const KaiMei& num ) const noexcept
はreturn OnMeiTable_Body( num , KanOnTable( num ))
と定める。HenKaKiGou Chou::HenKaKiGouTable_Body( const KaiMei& num , const KanOn& N ) const noexcept;
はconst int d
を( OnMei::KanOnToPitchClass( m_N.GetKanOn() ) + m_scale.PitchClassTable( num ) - OnMei( N ).GetPitchClass() ).Represent()
の戻り値で定め、const HenKaKiGou& S
をm_N.GetHenKaKiGou()
の戻り値で定め、d < 6
ならばreturn HenKaKiGou( d ) + S
と定め、そうでないならばreturn HenKaKiGou( d - 12 ) + S
と定める。inline OnMei Chou::OnMeiTable_Body( const KaiMei& num , const KanOn& N ) const noexcept
はreturn OnMei( N , HenKaKiGouTable_Body( num , N ) )
と定める。- クラス
Chou
に対する等号演算子は自然なものである。