私はAubioライブラリを使用しています。これは、aubio.orgのドキュメントやインターネットのどこにも見つかりません。処理(特に私の場合はピッチ検出aubio_pitch_detect
)を行うとき、Aubioはウィンドウ処理に関して着信オーディオアレイに対して何かを行いますか、それとも自分で実装する必要がありますか?
追加する必要がある場合は、簡単なウィンドウコードサンプル(またはリンク)を歓迎します。
私はAubioライブラリを使用しています。これは、aubio.orgのドキュメントやインターネットのどこにも見つかりません。処理(特に私の場合はピッチ検出aubio_pitch_detect
)を行うとき、Aubioはウィンドウ処理に関して着信オーディオアレイに対して何かを行いますか、それとも自分で実装する必要がありますか?
追加する必要がある場合は、簡単なウィンドウコードサンプル(またはリンク)を歓迎します。
Performousでこれを見つけました:
// Hamming window
for (size_t i=0; i < FFT_N; i++) {
m_window[i] = 0.53836 - 0.46164 * std::cos(2.0 * M_PI * i / (FFT_N - 1));
}
編集:「ああ、それは+または-または何ですか」という質問に対処するには、もう少し調べて、sinまたはcosのどちらを掛けているかを確認する必要がありますπ*i/FFT_N
。sin(0) = 0 および cos(0) = 1 であるため、(おおよそ!) 次のようなウィンドウの違いを見ています。
またはこのように:
1 つずつ並べると、両方とも次のようになることに注意してください。
したがって、ウィンドウ処理後に信号に対して実行する特定の処理は、選択するウィンドウ処理オプションに影響を与える可能性がありますが、実際には基本的に反対ではなく、単に異なる方法で調整されています。
aubio_pitch_do
オーディオ サンプルのベクトルを入力として受け取り、必要なウィンドウ処理を行います。
ドキュメントは、ヘッダー ファイルにあります。この場合、pitch.h
ファイルをチェックアウトします。
ウィンドウを作成する必要がある場合は、 で作成できますnew_aubio_window ( size, type )
。
例えば:
fvec_t * my_new_window = new_aubio_window ( 1024, "hanningz" );
これまでに利用可能なウィンドウの種類のリストは次のとおりです。
/** Window types */
typedef enum
{
aubio_win_rectangle,
aubio_win_hamming,
aubio_win_hanning,
aubio_win_hanningz,
aubio_win_blackman,
aubio_win_blackman_harris,
aubio_win_gaussian,
aubio_win_welch,
aubio_win_parzen,
aubio_win_default = aubio_win_hanningz,
} aubio_window_type;
これは回答というよりは質問ですが、初心者のステータスのため、他の回答にコメントすることはできません。
Flavien Volkenとbuildsucceededの回答に関しては、どちらもハミング係数に関して同じことを述べています。
0.54 または 0.53836、および 0.46 または 0.46164。
両方の回答の間に「-」があります: 0.54 - 0.46。
ここまでは順調ですね。これを見てください:
(1)ジョンズ・ホプキンス大学によると: 0.54 + 0.46
(2)カリフォルニア大学によると: 0.54 - 0.46
(3) DSP に関する本によると: 0.54 + 0.46
(4) ウィキペディアによると: 0.54 + 0.46
(5) mathworks によると: 0.54 - 0.46
(6) あるフォーラム ユーザーの意見: 1.07672 - 0.92328
完全に混乱しています。何が本当に正しいのか、どうすればわかりますか?
リンクは次のとおりです(ここでは初心者ステータスのため、実際のリンクを2つ以上投稿することはできません):
(1): www.jhu.edu/signals/phasors/hpfs7.htm
(2): www.ece.uci.edu/docs/hspice/hspice_2001_2-220.html
(3): books.google.de/books?id=ytuUKKVeR88C&pg=PT442&lpg=PT442&dq=hamming%20window%200.54%200.46&source=bl&ots=ecdP7pU8-w&sig=yv9QiCvuWv8vShO-6CjZATx37lA&hl=en&sa=X&ei=M4IJUfvBLsTFtAbQ54GwCw&ved=0CDAQ6AEwATgK
(4): de.wikipedia.org/wiki/Hamming-Fenster#Hamming-Fenster
(5): www.mathworks.de/de/help/signal/ref/hamming.html
(6): forums.oracle.com/forums/message.jspa?messageID=9244422#9244422
これは、ウィンドウ ベクトルを初期化するためのいくつかのウィンドウ メソッドのポートです。
include <math.h>
enum {
WINDOW_RECTANGULAR,
WINDOW_HANN,
WINDOW_HAMMING,
WINDOW_COSINE,
WINDOW_LANCZOS,
WINDOW_TRIANGULAR,
WINDOW_BARTLETT,
WINDOW_GAUSSIAN,
WINDOW_BARTLETT_HANN,
WINDOW_BLACKMAN,
WINDOW_NUTALL,
WINDOW_BLACKMAN_HARRIS,
WINDOW_BLACKMAN_NUTALL,
WINDOW_FLATTOP,
WINDOW_NB
};
template <class T_Real>
void computeWindow(T_Real*buffer, int length, int type)
{
switch (type)
{
case WINDOW_RECTANGULAR :
for (int n = 0; n < length; n++){ buffer[n] = 1.0; } break;
case WINDOW_HANN :
for (int n = 0; n < length; n++){ buffer[n] = 0.5*(1.0 - cos(M_PI*2.0*n/(length-1))); } break;
case WINDOW_HAMMING :
for (int n = 0; n < length; n++){ buffer[n] = 0.54-0.46*cos(M_PI*2.0*n/(length-1)); } break;
case WINDOW_COSINE :
for (int n = 0; n < length; n++){ buffer[n] = sin(M_PI*n/(length-1)); } break;
case WINDOW_LANCZOS :
for (int n = 0; n < length; n++){ double x = (2.0*n/(length-1)-1.0); buffer[n] = sin(M_PI*x)/(x*M_PI); } break;
case WINDOW_TRIANGULAR :
for (int n = 0; n < length; n++){ buffer[n] = (2.0/(length+1))*((0.5*(length-1.0))-fabs(n-0.5*(length-1.0))) ; } break;
case WINDOW_BARTLETT :
for (int n = 0; n < length; n++){ buffer[n] = (2.0/(length-1))*((0.5*(length-1.0))-fabs(n-0.5*(length-1.0))) ; } break;
case WINDOW_GAUSSIAN :
{
double fi = 0.5;
for (int n = 0; n < length; n++)
{
double inner = (n-0.5*(length-1))/(0.5*fi*(length-1));
double indice = -0.5*inner*inner;
buffer[n] = exp(indice);
}
break;
}
case WINDOW_BARTLETT_HANN :
for (int n = 0; n < length; n++){ buffer[n] = 0.62-0.48*fabs((double)n/(length-1.0)-0.5)-0.48*cos(M_PI*2.0*n/(length-1));} break;
case WINDOW_BLACKMAN :
{
double alpha = 0.16;
double a0 = 0.5*(1.0-alpha);
double a1 = 0.5;
double a2 = 0.5*alpha;
for (int n = 0; n < length; n++){ buffer[n] = a0 - a1*cos(M_PI*2.0*n/(length-1)) + a2*cos(M_PI*4.0*n/(length-1));} break;
}
case WINDOW_NUTALL :
{
double a0 = 0.355768;
double a1 = 0.487396;
double a2 = 0.144232;
double a3 = 0.012604;
for (int n = 0; n < length; n++){ buffer[n] = a0 - a1*cos(M_PI*2.0*n/(length-1)) + a2*cos(M_PI*4.0*n/(length-1)) - a3*cos(M_PI*6.0*n/(length-1));} break;
}
case WINDOW_BLACKMAN_HARRIS :
{
double a0 = 0.35875;
double a1 = 0.48829;
double a2 = 0.14128;
double a3 = 0.01168;
for (int n = 0; n < length; n++){ buffer[n] = a0 - a1*cos(M_PI*2.0*n/(length-1)) + a2*cos(M_PI*4.0*n/(length-1)) - a3*cos(M_PI*6.0*n/(length-1));} break;
}
case WINDOW_BLACKMAN_NUTALL :
{
double a0 = 0.3635819;
double a1 = 0.4891775;
double a2 = 0.1365995;
double a3 = 0.0106411;
for (int n = 0; n < length; n++){ buffer[n] = a0 - a1*cos(M_PI*2.0*n/(length-1)) + a2*cos(M_PI*4.0*n/(length-1)) - a3*cos(M_PI*6.0*n/(length-1));} break;
}
case WINDOW_FLATTOP :
{
double a0 = 1.0;
double a1 = 1.93;
double a2 = 1.29;
double a3 = 0.388;
double a4 = 0.032;
for (int n = 0; n < length; n++)
{ buffer[n] =
a0 - a1*cos(M_PI*2.0*n/(length-1)) +
a2*cos(M_PI*4.0*n/(length-1)) -
a3*cos(M_PI*6.0*n/(length-1)) +
a4*cos(M_PI*8.0*n/(length-1));
} break;
}
default: break;
}
}
使用例:
computeWindow<float>(myFloatWindowBuffer, windowLength, WINDOW_NUTALL);