
周期ごとの場合分けと、位相と周波数の考え方は前回の矩形波とほぼ一緒です。
では早速サンプリング間隔nInterval(ms)のデータにおけるデータ数:nDataNum
振幅:dbAmp(dBやVolt等) 周波数:dbFrequency(Hz) 位相:dbPhase(度) オフセット:dbOffset
ののこぎり波を作成してみます。
int nInterval // サンプリング間隔(ms)
double dbOffset // 縦軸オフセット(0点)
double dbAmp // 振幅(dBやVolt等)
double dbFrequency // 周波数(Hz)
double dbPhase // 位相(度)
for( nDataCnt = 0; nDataCnt < nDataNum; nDataCnt++ )
{
nRemain = (int)( nInterval * nDataCnt - 1000 * dbPhase / 360 ) % (int)( 1000 / dbFrequency );
if( 0 == nRemain || 500/dbFrequency == nRemain || -500/dbFrequency == nRemain )
adWaveData[ nDataCnt ] = dbOffset;
if( -1000 < nRemain && nRemain < -500/dbFrequency )
adWaveData[ nDataCnt ] = dbAmp * nRemain / ( 500 / dbFrequency ) + dbOffset + 2 * dbAmp;
else if( -500/dbFrequency < nRemain && nRemain < 0 )
adWaveData[ nDataCnt ] = dbAmp * nRemain / ( 500 / dbFrequency ) + dbOffset;
else if( 0 < nRemain && nRemain < 500/dbFrequency )
adWaveData[ nDataCnt ] = dbAmp * nRemain / ( 500 / dbFrequency ) + dbOffset;
else if( 500/dbFrequency < nRemain && nRemain < 1000/dbFrequency )
adWaveData[ nDataCnt ] = dbAmp * nRemain / ( 500 / dbFrequency ) + dbOffset - 2 * dbAmp;
}
nRemainが現在の横軸の点の位置になります。
nDataCntがインクリメントするごとにサンプリング間隔毎に点が移動するので、
nInterval * nDataCnt(ms)になります。
更に位相ずれ分を考慮した部分が - 1000 * dbPhase / 360 になります。
全体を最終的に % (int)( 1000 / dbFrequency ) してる部分が作成したい波形の
周期を考慮した部分です。
これにより、nInterval * nDataCnt(ms)部分が周期を超えたらnRemainが0に戻ります。
この部分が周期関数を実現している部分になります。
基本形は右上がりの一次式(y=ax+b)が連続しているだけなので
dbAmp / ( 500 / dbFrequency ) が傾き(a)の部分でそれに nRemain(x) をかけると
dbAmp * nRemain / ( 500 / dbFrequency )
となり、場合分け毎全ての式における共通の部分です。
問題は場合ごとに違う(b:一次式のy切片)の部分です。
dbOffsetは波形の縦軸方向中間位置を表し、波形全体を縦軸方向に平行移動させます。
場合分け毎全ての式において共通の部分です。
以下場合分け毎のy切片の説明です。
・-1000 < nRemain && nRemain < -500/dbFrequencyの時は
y軸(x=0)よりもマイナス方向にあるので、y切片は dbOffset + 2 * dbAmp となります。
・500/dbFrequency < nRemain && nRemain < 1000/dbFrequency の時は、
y軸(x=0)よりもプラス方向にあるので、y切片は dbOffset - 2 * dbAmp となります。
・-500/dbFrequency < nRemain && nRemain < 0 及び
0 < nRemain && nRemain < 500/dbFrequency の時はy軸を通るので、
dbOffset となります。
・0 == nRemain || 500/dbFrequency == nRemain || -500/dbFrequency == nRemain の時
前回矩形波同様丁度上下限になる瞬間の切れ目の部分
dbOffset となります。
これがないと、中途半端な周波数などの場合は上限値⇔下限値に
移行する際の点が未定義になって波形が切れたりするのでしたね。
(前回矩形波時と同様)
次回は更に別の波形の紹介をしたいと思います。
では、また。