#include <osc.h>
osc::CTableLookupに対する継承グラフ

内部の位相と周波数情報を元に、コサイン波、サイン波を生成する。 生成にはテーブル・ルックアップを使う。2πを256分割したテーブル と、2π/256をさらに256分割した二つのテーブルを用意する。それぞれ cosとsinのデータを持っている。この二つのテーブルを元に16bitイン デックスに対する三角関数を加法定理を元に計算する。
Public メソッド | |
| CTableLookup (int freq) | |
| コンストラクタ | |
| virtual void | run (shortfract i[], shortfract q[], int count) |
| 信号の生成 | |
| virtual void | run (shortfract i[], int count) |
| 複素信号の生成 | |
| virtual void | run (shortfract i[], int deviation[], int count) |
| FM信号の生成 | |
| osc::CTableLookup::CTableLookup | ( | int | freq | ) | [inline] |
コンストラクタ
周波数を指定する。内部位相は0になる。サンプル周波数 をfsとし、希望する周波数をfrとすると、コンストラクタに渡すべき値 freqは、 freq=fr*(2^32)/fs で得ることができる。
00107 : COscillator( freq ) {};
| void osc::CTableLookup::run | ( | shortfract | i[], | |
| shortfract | q[], | |||
| int | count | |||
| ) | [virtual] |
信号の生成
| i | コサイン波信号の出力配列 | |
| q | サイン波信号の出力配列 | |
| count | それぞれの配列に出力するサンプル数 |
osc::COscillatorを実装しています。
参照先 osc::co_h, osc::co_l, osc::si_h, と osc::si_l.
00050 { 00051 for ( int j=0; j<count; j++ ){ 00052 // 32bitの位相の内、上位16bitのみを使う。 00053 unsigned int hi = ( this->phase >> 24 ) & 0xFF; // 16bit位相の上位8bit 00054 unsigned int lo = ( this->phase >> 16 ) & 0xFF; // 8bit位相の下位8bit 00055 00056 // 加法定理 cos(A+B) = cos(A)cos(B) - sin(A)sin(B) 00057 // 加法定理 sin(A+B) = sin(A)cos(B) + cos(A)sin(B) 00058 // アセンブリ言語による実装 00059 asm( "a0 = %2*%3;\n" // cos_h*cos_l 00060 "%0=(a0-=%4*%5);\n" // sin_h*sin_l 00061 "a0 = %4*%3;\n" // sin_h*cos_l 00062 "%1=(a0+=%2*%5);\n" // cos_h*sin_l 00063 : "=&l"(i[j].v), "=&l"(q[j].v) 00064 : "l"(co_h[hi].v), "l"(co_l[lo].v), "l"(si_h[hi].v), "l"(si_l[lo].v) 00065 : "a0" 00066 ); 00067 // 位相の更新 00068 this->phase += this->frequency; 00069 } 00070 }
| void osc::CTableLookup::run | ( | shortfract | i[], | |
| int | count | |||
| ) | [virtual] |
複素信号の生成
| i | コサイン波信号の出力配列 | |
| count | 配列に出力するサンプル数 |
osc::COscillatorを実装しています。
参照先 osc::co_h, osc::co_l, osc::si_h, と osc::si_l.
00073 { 00074 for ( int j=0; j<count; j++ ){ 00075 // 32bitの位相の内、上位16bitのみを使う。 00076 unsigned int hi = ( this->phase >> 24 ) & 0xFF; // 16bit位相の上位8bit 00077 unsigned int lo = ( this->phase >> 16 ) & 0xFF; // 8bit位相の下位8bit 00078 00079 // 加法定理 cos(A+B) = cos(A)cos(B) - sin(A)sin(B) 00080 asm( "a0 = %1*%2;\n" 00081 "%0=(a0-=%3*%4);\n" 00082 : "=l"(i[j].v) 00083 : "l"(co_h[hi].v), "l"(co_l[lo].v), "l"(si_h[hi].v), "l"(si_l[lo].v) 00084 : "a0" 00085 ); 00086 // 位相の更新 00087 this->phase += this->frequency; 00088 00089 } 00090 }
| void osc::CTableLookup::run | ( | shortfract | i[], | |
| int | deviation[], | |||
| int | count | |||
| ) | [virtual] |
FM信号の生成
| i | コサイン波信号の出力配列 | |
| deviation | 周波数偏移を指定する配列 | |
| count | 配列に出力するサンプル数 |
osc::COscillatorを実装しています。
参照先 osc::co_h, osc::co_l, osc::si_h, と osc::si_l.
00093 { 00094 for ( int j=0; j<count; j++ ){ 00095 // 32bitの位相の内、上位16bitのみを使う。 00096 unsigned int hi = ( this->phase >> 24 ) & 0xFF; // 16bit位相の上位8bit 00097 unsigned int lo = ( this->phase >> 16 ) & 0xFF; // 8bit位相の下位8bit 00098 00099 // 加法定理 cos(A+B) = cos(A)cos(B) - sin(A)sin(B) 00100 asm( "a0 = %1*%2;\n" 00101 "%0=(a0-=%3*%4);\n" 00102 : "=l"(i[j].v) 00103 : "l"(co_h[hi].v), "l"(co_l[lo].v), "l"(si_h[hi].v), "l"(si_l[lo].v) 00104 : "a0" 00105 ); 00106 // 位相の更新 00107 this->phase += this->frequency + deviation[j]; 00108 00109 } 00110 }
1.5.2