00001 #pragma once 00002 #include <shortfract> 00003 /** \file 00004 * 発振器クラスの宣言 00005 */ 00006 00007 /** 発振器クラスの名前空間 00008 * 00009 */ 00010 00011 namespace osc{ 00012 /** 抽象発振器クラス 00013 * 00014 * 発振器クラスの親となる抽象クラス。現在の位相と周波数を内部に保持する。 00015 * 位相は2πを32bit符号なし整数にマッピングする。すなわち1周期を40億ステップ 00016 * に分解する。 00017 * 周波数は1サンプルに変化する量(dθ/dt)で指定する。32bit符号つき数である。 00018 */ 00019 class COscillator{ 00020 protected: 00021 /** 内部位相 00022 * 00023 * 内部位相は32ビット符号なし数である。この位相はrunメソッドで更新 00024 * していく。フルスケールが2πに相当する。 00025 */ 00026 unsigned int phase; 00027 /** 周波数 00028 * 00029 * 周波数は32ビット数である。周波数はコンストラクタで指定 00030 * するほかsetFreqメソッドで再設定することもできる。 00031 */ 00032 int frequency; 00033 public: 00034 /** コンストラクタ 00035 * 00036 * 周波数を指定する。内部位相は0になる。サンプル周波数 00037 * をfsとし、希望する周波数をfrとすると、コンストラクタに渡すべき値 00038 * freqは、 freq=fr*(2^32)/fs で得ることができる。 00039 */ 00040 COscillator( int freq ); 00041 /** 周波数の再設定 00042 * 00043 * \param freq 32bit 周波数。 00044 * 00045 * 内部位相を変更せずに周波数を再設定する。 00046 * サンプル周波数をfsとし、希望する周波数をfrとすると、 00047 * コンストラクタに渡すべき値 00048 * freqは、 freq=fr*(2^32)/fs で得ることができる。 00049 */ 00050 virtual void setFreq( int freq ); 00051 /** 位相の再設定 00052 * 00053 * \param phase 32bit の周波数。 00054 * 00055 * 内部周波数を変更せずに位相を再設定する。 00056 * 0から2^32-1の値で、0-2πを表現する。 00057 */ 00058 virtual void setPhase( unsigned int phase ); 00059 /** 複素信号の生成 00060 * 00061 * \param i コサイン波信号の出力配列 00062 * \param q サイン波信号の出力配列 00063 * \param count それぞれの配列に出力するサンプル数 00064 * 00065 * 発振器の内部位相をもとに、コサイン波とサイン波を生成する 00066 * 純粋仮想関数。 00067 */ 00068 virtual void run( shortfract i[], shortfract q[], int count ) = 0; 00069 /** 信号の生成 00070 * 00071 * \param i コサイン波信号の出力配列 00072 * \param count 配列に出力するサンプル数 00073 * 00074 * 発振器の内部位相をもとに、コサイン波を生成する純粋仮想関数。 00075 */ 00076 virtual void run( shortfract i[], int count ) = 0; 00077 /** FM信号の生成 00078 * 00079 * \param i コサイン波信号の出力配列 00080 * \param deviation 周波数偏移を指定する配列 00081 * \param count 配列に出力するサンプル数 00082 * 00083 * 発振器の内部位相をもとに、コサイン波を生成する純粋仮想関数。 00084 * deviation[]によって、サンプルごとに周波数偏移を指定することが 00085 * できる。偏移させたい周波数をfr、サンプル周波数をfsとすると、 00086 * deviation[i]に与える量は fr*(2^32)/fs である。 00087 */ 00088 virtual void run( shortfract i[], int deviation[], int count ) = 0; 00089 }; 00090 00091 /** 発振器クラス 00092 * 00093 * 内部の位相と周波数情報を元に、コサイン波、サイン波を生成する。 00094 * 生成にはテーブル・ルックアップを使う。2πを256分割したテーブル 00095 * と、2π/256をさらに256分割した二つのテーブルを用意する。それぞれ 00096 * cosとsinのデータを持っている。この二つのテーブルを元に16bitイン 00097 * デックスに対する三角関数を加法定理を元に計算する。 00098 */ 00099 class CTableLookup : public COscillator{ 00100 public: 00101 /** コンストラクタ 00102 * 00103 * 周波数を指定する。内部位相は0になる。サンプル周波数 00104 * をfsとし、希望する周波数をfrとすると、コンストラクタに渡すべき値 00105 * freqは、 freq=fr*(2^32)/fs で得ることができる。 00106 */ 00107 CTableLookup( int freq ) : COscillator( freq ) {}; 00108 /** 信号の生成 00109 * 00110 * \param i コサイン波信号の出力配列 00111 * \param q サイン波信号の出力配列 00112 * \param count それぞれの配列に出力するサンプル数 00113 * 00114 * 発振器の内部位相をもとに、コサイン波とサイン波を生成する。 00115 * 生成アルゴリズムはテーブル参照に基づく。 00116 */ 00117 virtual void run( shortfract i[], shortfract q[], int count ); 00118 /** 複素信号の生成 00119 * 00120 * \param i コサイン波信号の出力配列 00121 * \param count 配列に出力するサンプル数 00122 * 00123 * 発振器の内部位相をもとに、コサイン波を生成する。 00124 * 生成アルゴリズムはテーブル参照に基づく。 00125 */ 00126 virtual void run( shortfract i[], int count ); 00127 /** FM信号の生成 00128 * 00129 * \param i コサイン波信号の出力配列 00130 * \param deviation 周波数偏移を指定する配列 00131 * \param count 配列に出力するサンプル数 00132 * 00133 * 発振器の内部位相をもとに、コサイン波を生成する関数。 00134 * deviation[]によって、サンプルごとに周波数偏移を指定することが 00135 * できる。偏移させたい周波数をfr、サンプル周波数をfsとすると、 00136 * deviation[i]に与える量は fr*(2^32)/fs である。 00137 */ 00138 virtual void run( shortfract i[], int deviation[], int count ); 00139 }; 00140 00141 00142 00143 00144 /** cosの上位位相分 00145 * 00146 * 全周を256分割したコサイン・テーブル。 00147 */ 00148 extern shortfract co_h[]; 00149 /** cosの下位位相分 00150 * 00151 * 全周の256分の1をさらに256分割したコサイン・テーブル。 00152 */ 00153 extern shortfract co_l[]; 00154 /** sinの上位位相分 00155 * 00156 * 全周を256分割したサイン・テーブル。 00157 */ 00158 extern shortfract si_h[]; 00159 /** sinの下位位相分 00160 * 00161 * 全周の256分の1をさらに256分割したサイン・テーブル。 00162 */ 00163 extern shortfract si_l[]; 00164 };
1.5.2