数式での翻訳 |
---|
音名と音階の文字列としての結合で与えられる文字列を、音名と音階の組と同一視します。音名と音階の組全体の集合 \[ \textrm{Chou} = \textrm{OnMei} \times \textrm{OnKai} \] に属する文字列を調と呼びます。例えば\(\textrm{Do♭♭WaseiTekiTanOnKai}\)は調です。実際には音名と音階の間に\(\textrm{No}\)や\(\textrm{WoShuOnToSuru}\)等の文字列を挟んだり語順を逆にしたりするかもしれませんが、実装の都合上ここでは気にしないことにします。
第\(1\)射影と第\(2\)射影 \[ \begin{align} \textrm{Chou} & \to \textrm{OnMei} \\
\textrm{Chou} & \to \textrm{OnKai} \end{align} \] をそれぞれ\(\textrm{GetOnMei}\)と\(\textrm{GetOnKai}\)と置きます。
また写像 \[ \begin{align} \textrm{OnMeiTable} \colon \textrm{Chou} \times \textrm{KaiMei} & \to \textrm{OnMei} \\
(N,n) & \mapsto \textrm{OnMeiTable}(N,n) \end{align} \] を以下のように定めます:
- \(s = \textrm{GetOnKai}(N) \in \textrm{OnKai}\)と置き、\(N_0 = \textrm{GetKanOn}(\textrm{GetOnMei}(N)) \in \textrm{KanOn}\)と置き、\(S_0 = \textrm{GetHenKaKiGou}(\textrm{GetOnMei}(N)) \in \textrm{HenKaKiGou}\)と置く。
- \(\textrm{GetNum}(N_1) = \textrm{GetNum}(N_0) + n\)を満たす唯一の\(N_1 \in \textrm{KanOn}\)を取る。
- \(\overline{d} = \textrm{KanOnToPitchClass}(N_0) + \textrm{PitchClassTable}(s,n) - \textrm{KanOnToPitchClass}(N_1) \in \textrm{PitchClass}\)と置く。
- \(d = \textrm{Represent}(\overline{d}) \in \{0,1,2,3,4,5,6,7,8,9,10,11\}\)と置く。
- \(d \lneq 6\)ならば、\(\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
に対する等号演算子は自然なものである。