SDL_Mixer ライブラリで HRTF を使用してオーディオ ストリームを畳み込み、3D サウンドを作成しようとしています (コンパクト データセットに基づく MIT HRTF データベースをそれぞれ使用しています)。
MIX_CHANNEL_POST のコールバック関数にエフェクトを登録します。次に、エフェクトのコールバック関数で、オーディオ ストリームと HRTF のコンボリューションを作成します。
しかし、3D サウンドは得られませんでした。再生したいオーディオストリームは、それ自体が二重または三重にオーバーレイされているように聞こえ、3D 効果はありません。
これが私がやっていることです:
最初に wav をロードし、HRTF をロードしてオーディオを開始します。
if( Mix_OpenAudio( 44100, MIX_DEFAULT_FORMAT, 2, 16384 ) == -1 ) {
fprintf(stderr, "Couldn't open SDL_mixer", SDL_GetError()); return 0; }
myChunk = Mix_LoadWAV( "bombsBitrate176400Hz.wav" ); //load wav
if( myChunk == NULL) {
fprintf(stderr, "Couldn't load wav file", Mix_GetError()); return 0;
}
myLoadHRTF = new LoadHRTF;
myHRTFs = myLoadHRTF->getHRTF(90,0,44100);//load hrtf => works
Mix_RegisterEffect(MIX_CHANNEL_POST, HRTFEffect, NULL, &myHRTFs);
while(1){
if (canPlay){//virtual source is set and azimuth is calculated => I can start audio
playAudio();
canPlay = false;
}
}
playAudio():
void PlaySDLAudio::playAudio(){
int channel;
channel = Mix_PlayChannel(-1,myChunk,0); //play audio once}
登録したエフェクトのコールバック:
void HRTFEffect(int chan, void* stream, int len, void* udata){
Mix_Pause(-1);
short* Y;
short* X = (short*) stream;
LeftRightHRTF* myHRTFs = (LeftRightHRTF*) udata;
short* HL;
short* HR;
int m = len/2;//size= len/2 beause we use 2 bytes values (16 bit audio format => 2 byte), len is the size of stream in bytes
int n = myHRTFs->nTaps;
HL = new short[n+m];
HR = new short[n+m];
Y = new short[n+m-1];
for (int i = m/2; i < (m+n)/2; i++){// fill with 0
X[i*2] = 0;
X[i*2+1] = 0;
}
for( int i = 0 ; i < n; i++ ){
HL[i] = *myHRTFs->leftHRTF;
myHRTFs->leftHRTF++;
HR[i] = *myHRTFs->rightHRTF;
myHRTFs->rightHRTF++;
}
for ( int i = n; i < n+m; i++ ){//fill rest with 0
HL[i] = 0;
HR[i] = 0;
}
for ( int i = 0; i < (n+m)/2-1; i++ ) { // convolution
Y[i*2] = 0;
Y[i*2+1] = 0;
for ( int j = 0; j < m/2; j++ ) {
if (i-j>=0){
Y[i*2] = Y[i*2] + X[j*2] * HL[i-j];//stream for left speaker
Y[i*2+1] = Y[i*2+1] + X[j*2+1] * HR[i-j];//stream for right speaker
}
}
}
stream = Y; //set result of convolution to stream
Mix_Resume(-1);
delete[] Y;
Y = 0;
delete[] HL;
HL = 0;
delete[] HR;
HR = 0;}
stream = Y と言うだけで問題があると思います。畳み込みの結果 Y が元のストリーム (m+n-1、元のストリーム m) よりも長いためです。