CVoiceクラスの実装
ここでは
前項で定義したCVoiceクラスについて説明する。
CVoiceクラスの初期化
CVoiceクラスではコンストラクタで初期化するためにinit()関数を呼び出している
init()関数はメンバー変数に初期値を代入している。
なお、終了処理はないため、デストラクタでは何もしていない。
CVoice::CVoice()
{
// 初期化を実施
init();
}
CVoice::~CVoice()
{
}
void CVoice::init()
{
// メンバ変数を初期化する
elapsedFrames = 0.0;
status = VOICE_STATE_OFF;
noteNo = 0;
sampleRate =44100.0f;
}
CVoiceクラス start()関数、stop()関数
start()関数が呼び出されるとCVoiceクラスは自身が発音している状態であることを示すため、メンバー変数statusをONの状態(VOICE_STATE_ON)にする。
同時にMIDI ノートOnメッセージのノートナンバーを保存し、amplitude()関数が呼び出された際に振幅値が計算できるようにする。
void CVoice::start(int note)
{
init();
status = VOICE_STATE_ON;
noteNo = note;
}
stop()関数が呼び出されると自身が停止している状態であることを示すためstatusをOFFの状態(OSC_OFF)にする。
ここではオシレータを初期化することでstatusをOFFの状態(OSC_OFF)にしている。
void CVoice::stop()
{
init();
}
CVoiceクラス amplitude()関数
amplitude()関数が呼び出されると現在の振幅値を返すようにする。
statusがON(VOICE_STATE_ON)の場合はstart()関数で与えられたノートナンバーと経過時間から振幅を計算しその値を返している。
statusがOFF(VOICE_STATE_OFF)の場合は0を返している。
float CVoice::amplitude()
{
// オシレータの振幅を返す
if(status == VOICE_STATE_ON)
{
// オシレータの状態がONの時
// ノートNoから周波数を計算する
float freq = (float)(440.0 * pow(2.0, ((double)noteNo - 69.0)/12.0));;
// 現在の振幅量を返す
float pi = 3.14159265f;
return (float)sin(2.0 * pi * freq * elapsedFrames / sampleRate);
}
else
{
// オシレータの状態がOFFの時
// 0を返す
return 0.0f;
}
}
なお、振幅を求めるにはsin関数を用いている。
振幅と周波数・経過時間の関係は以下となる。
f(t) = sin(2πft)
π = 3.14159265…
t = 経過したフレーム数÷サンプルレート = elapsedFrames / sampleRate
f = 周波数 = freq
また、freqはノートナンバーから求める。
ノートナンバーがA3(数値で69)のとき440Hzで、オクターブ上がる(ノートナンバーが12増える)ごとに周波数は2倍になるので以下で求めることができる。
440Hz × 2^((69-ノートナンバー)/12)
CVoiceクラス update()関数
update()関数が呼び出されるとCVoiceクラスの経過時間を進め、CVoiceクラスの状態を更新する。
void CVoice::update()
{
// 経過時間を進める
if(status != VOICE_STATE_OFF)
{
elapsedFrames += 1.0f;
}
}
同一カテゴリのTips
javascript plugin Error : このプラグインで利用できない命令または文字列が入っています。
最終更新:2011年04月17日 23:33