• トップページ
  • project
    • 全ての作品
    • 全てのタグ
  • blog
    • 全ての記事
    • 全てのタグ
  • tag
    • 全てのタグ
    • 全ての作品タグ
    • 全ての記事タグ
  • about
    • p進大好きサークル photo

      p進大好きサークル

      p進大好きサークルのHPです。

    • もっと読む
    • Twitter
    • pixiv
    • 巨大数Wiki

機能和声の実装 - 調

2020/02/01

トップページ 前の記事 親記事 次の記事

twitter pixiv yukicoder お題箱 マシュマロ

数式での翻訳

音名と音階の文字列としての結合で与えられる文字列を、音名と音階の組と同一視します。音名と音階の組全体の集合 \[ \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} \] を以下のように定めます:

  1. \(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}\)と置く。
  2. \(\textrm{GetNum}(N_1) = \textrm{GetNum}(N_0) + n\)を満たす唯一の\(N_1 \in \textrm{KanOn}\)を取る。
  3. \(\overline{d} = \textrm{KanOnToPitchClass}(N_0) + \textrm{PitchClassTable}(s,n) - \textrm{KanOnToPitchClass}(N_1) \in \textrm{PitchClass}\)と置く。
  4. \(d = \textrm{Represent}(\overline{d}) \in \{0,1,2,3,4,5,6,7,8,9,10,11\}\)と置く。
  5. \(d \lneq 6\)ならば、\(\textrm{GetNum}(S_1) = d + \textrm{GetNum}(S_0)\)を満たす唯一の\(S_1 \in \textrm{HenKaKiGou}\)を取る。
  6. \(d \geq 6\)ならば、\(\textrm{GetNum}(S_1) = d - 12 + \textrm{GetNum}(S_0)\)を満たす唯一の\(S_1 \in \textrm{HenKaKiGou}\)を取る。
  7. \(\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に対する等号演算子は自然なものである。
トップページ 前の記事 親記事 次の記事

twitter pixiv yukicoder お題箱 マシュマロ