#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.
00029 { 00030 for ( int j=0; j<count; j++ ){ 00031 // 32bitの位相の内、上位16bitのみを使う。 00032 unsigned int hi = ( this->phase >> 24 ) & 0xFF; // 16bit位相の上位8bit 00033 unsigned int lo = ( this->phase >> 16 ) & 0xFF; // 8bit位相の下位8bit 00034 #if 0 00035 // 加法定理 cos(A+B) = cos(A)cos(B) - sin(A)sin(B) 00036 i[j] = co_h[hi]*co_l[lo] - si_h[hi]*si_l[lo]; 00037 // 加法定理 sin(A+B) = sin(A)cos(B) + cos(A)sin(B) 00038 q[j] = si_h[hi]*co_l[lo] + co_h[hi]*si_l[lo]; 00039 #else 00040 // アセンブリ言語による実装 00041 asm( "a0 = %2*%3;\n" // cos_h*cos_l 00042 "%0=(a0-=%4*%5);\n" // sin_h*sin_l 00043 "a0 = %4*%3;\n" // sin_h*cos_l 00044 "%1=(a0+=%2*%5);\n" // cos_h*sin_l 00045 : "=&l"(i[j].v), "=&l"(q[j].v) 00046 : "l"(co_h[hi].v), "l"(co_l[lo].v), "l"(si_h[hi].v), "l"(si_l[lo].v) 00047 : "a0" 00048 ); 00049 #endif 00050 // 位相の更新 00051 this->phase += this->frequency; 00052 } 00053 }
| 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.
00056 { 00057 for ( int j=0; j<count; j++ ){ 00058 // 32bitの位相の内、上位16bitのみを使う。 00059 unsigned int hi = ( this->phase >> 24 ) & 0xFF; // 16bit位相の上位8bit 00060 unsigned int lo = ( this->phase >> 16 ) & 0xFF; // 8bit位相の下位8bit 00061 00062 // 加法定理 cos(A+B) = cos(A)cos(B) - sin(A)sin(B) 00063 #if 0 00064 i[j] = co_h[hi]*co_l[lo] - si_h[hi]*si_l[lo]; 00065 #else 00066 // アセンブリ言語による実装 00067 asm( "a0 = %1*%2;\n" 00068 "%0=(a0-=%3*%4);\n" 00069 : "=l"(i[j].v) 00070 : "l"(co_h[hi].v), "l"(co_l[lo].v), "l"(si_h[hi].v), "l"(si_l[lo].v) 00071 : "a0" 00072 ); 00073 #endif 00074 // 位相の更新 00075 this->phase += this->frequency; 00076 00077 } 00078 }
| 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.
00081 { 00082 for ( int j=0; j<count; j++ ){ 00083 // 32bitの位相の内、上位16bitのみを使う。 00084 unsigned int hi = ( this->phase >> 24 ) & 0xFF; // 16bit位相の上位8bit 00085 unsigned int lo = ( this->phase >> 16 ) & 0xFF; // 8bit位相の下位8bit 00086 00087 // 加法定理 cos(A+B) = cos(A)cos(B) - sin(A)sin(B) 00088 // アセンブリ言語による実装 00089 asm( "a0 = %1*%2;\n" 00090 "%0=(a0-=%3*%4);\n" 00091 : "=l"(i[j].v) 00092 : "l"(co_h[hi].v), "l"(co_l[lo].v), "l"(si_h[hi].v), "l"(si_l[lo].v) 00093 : "a0" 00094 ); 00095 // 位相の更新 00096 this->phase += this->frequency + deviation[j]; 00097 00098 } 00099 }
1.5.2