「ドップラー効果(Doppler Effect)-CPP」の編集履歴(バックアップ)一覧はこちら
「ドップラー効果(Doppler Effect)-CPP」(2009/09/26 (土) 19:43:15) の最新版変更点
追加された行は緑色になります。
削除された行は赤色になります。
*&this_page()
|&tags()|[[解説>ドップラー効果(Doppler Effect)]]|最終更新日 &date()|&link_pdf(text=PDFで表示)|[[ダウンロード>http://www20.atwiki.jp/yosilove?cmd=upload&act=open&pageid=23&file=Doppler.zip]]|View &counter(total)|
OpenALでドップラー効果を再現するサンプル。
ALUTが必要です。
#contents
*main.cpp
//OpenALを用いたドップラー効果のサンプル
#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#include <OpenAL/al.h>
#include <OpenAL/alc.h>
#include <AL/alut.h>
#include "keyboard.h"
ALuint Buffer;// Buffers hold sound data.
ALuint Source;// Sources are points of emitting sound.
/* 設定 */
//-- 音源(Source)の設定
ALfloat pitch = 1.0f;
ALfloat gain = 1.0f;
ALfloat SourcePos[] = { 0.0f, 0.0f, -50.0f };// Position of the source sound.
ALfloat SourceVel[] = { 0.0f, 0.0f, 40.0f };// Velocity of the source sound.
//単純にPosition += Velocityとすると時間が早すぎるので適当に補正値を掛けてみたり
//Position += revise*Velocity
const float revise = 0.000003;
//-- 観測者(Listener)の設定
ALfloat ListenerPos[] = { 0.0, 0.0, 0.0 };// Position of the listener.
ALfloat ListenerVel[] = { 0.0, 0.0, 0.0 };// Velocity of the listener.
// Orientation of the listener. (first 3 elements are "at", second 3 are "up")
ALfloat ListenerOri[] = { 0.0, 0.0, -1.0, 0.0, 1.0, 0.0 };
//-- その他の設定
ALfloat SourceMaxDist = 80.0;//これ以上離れると初期位置に戻る
//-- ドップラー効果の設定
//shift = DOPPLER_FACTOR * freq * (DOPPLER_VELOCITY - listener.velocity) / (DOPPLER_VELOCITY + source.velocity)
#define DOPPLER_FACTOR 0.5f
#define DOPPLER_VELOCITY 10.0f
/*
* ALboolean LoadALData()
*wavデータの読み込みと音源の初期設定
*/
ALboolean LoadALData()
{
ALenum format;
ALsizei size;
ALvoid* data;
ALsizei freq;
ALboolean loop;
// Load wav data into a buffer.
alGenBuffers(1, &Buffer);
if(alGetError() != AL_NO_ERROR) return AL_FALSE;
//wavファイルの読み込み
alutLoadWAVFile((ALbyte*)"wavdata/Ambulance.wav", &format, &data, &size, &freq);
alBufferData(Buffer, format, data, size, freq);
alutUnloadWAV(format, data, size, freq);
// Bind the buffer with the source.
alGenSources(1, &Source);
if(alGetError() != AL_NO_ERROR) return AL_FALSE;
//ソースの初期設定
alSourcei (Source, AL_BUFFER, Buffer );//音源
alSourcef (Source, AL_PITCH, pitch );//ピッチ
alSourcef (Source, AL_GAIN, gain );//ゲイン
alSourcefv(Source, AL_POSITION, SourcePos);//座標
alSourcefv(Source, AL_VELOCITY, SourceVel);//移動
alSourcei (Source, AL_LOOPING, AL_TRUE );//繰り返す
// Do an error check and return.
if(alGetError() != AL_NO_ERROR) return AL_FALSE;
return AL_TRUE;
}
/*
* void SetListenerValues()
* 観測者の設定
*/
void SetListenerValues()
{
alListenerfv(AL_POSITION, ListenerPos);
alListenerfv(AL_VELOCITY, ListenerVel);
alListenerfv(AL_ORIENTATION, ListenerOri);
}
/*
* void KillALData()
* お掃除
*/
void KillALData()
{
alDeleteBuffers(1, &Buffer);
alDeleteSources(1, &Source);
alutExit();
}
int main(int argc, char *argv[]) {
int i;//カウンタ
ALboolean far=AL_FALSE;//遠いかどうかのフラグ
printf("Doppler Effect\n");
printf("(Press any key to quit.)\n");
// 初期化
alutInit(NULL,0);
alGetError();
// ソースの設定
if(LoadALData() == AL_FALSE)
{
printf("Error loading data.");
return 0;
}
//観測者の設定
SetListenerValues();
// お掃除関数の指定
atexit(KillALData);
// 再生開始
alSourcePlay(Source);
//初期値を保存
ALfloat SourceDefPos[] = { SourcePos[0], SourcePos[1], SourcePos[2] };
//ドップラー効果の設定
alDopplerFactor(DOPPLER_FACTOR);
alDopplerVelocity(DOPPLER_VELOCITY);
while(!kbhit()){
far=AL_FALSE;
for(i=0;i<3;i++){
//座標を更新
SourcePos[i] += revise*SourceVel[i];
//遠い?
if( sqrt(abs(pow(SourcePos[i],2)+pow(ListenerPos[i],2)) ) > SourceMaxDist) far = AL_TRUE;
}
//遠かったらはじめの位置に戻る
if(far) for(i=0;i<3;i++) SourcePos[i]=SourceDefPos[i];
alSourcefv(Source, AL_POSITION, SourcePos);
}
return 0;
}
*keyboard.cpp
/*
This is the unix code for kbhit I found on google at
http://www.linuxquestions.org/questions/archive/9/2002/10/4/34027
*/
#include "keyboard.h"
void init_keyboard()
{
tcgetattr(0,&initial_settings);
new_settings = initial_settings;
new_settings.c_lflag &= ~ICANON;
new_settings.c_lflag &= ~ECHO;
new_settings.c_lflag &= ~ISIG;
new_settings.c_cc[VMIN] = 1;
new_settings.c_cc[VTIME] = 0;
tcsetattr(0, TCSANOW, &new_settings);
}
void close_keyboard()
{
tcsetattr(0, TCSANOW, &initial_settings);
}
int kbhit()
{
char ch;
int nread;
if(peek_character != -1)
return 1;
new_settings.c_cc[VMIN]=0;
tcsetattr(0, TCSANOW, &new_settings);
nread = read(0,&ch,1);
new_settings.c_cc[VMIN]=1;
tcsetattr(0, TCSANOW, &new_settings);
if(nread == 1)
{
peek_character = ch;
return 1;
}
return 0;
}
int readch()
{
char ch;
if(peek_character != -1)
{
ch = peek_character;
peek_character = -1;
return ch;
}
read(0,&ch,1);
return ch;
}
*keyboad.h
/*
This is the unix code for kbhit I found on google at
http://www.linuxquestions.org/questions/archive/9/2002/10/4/34027
*/
#include <stdio.h>
#include <termios.h>
#include <term.h>
#include <curses.h>
#include <unistd.h>
static struct termios initial_settings, new_settings;
static int peek_character = -1;
void init_keyboard();
void close_keyboard();
int kbhit();
int readch();
*Makefile
**Mac
CC = g++
TARGET = doppler
COMPILEFLAGS = -framework OpenAL -lalut
$(TARGET): main.o keyboard.o
$(CC) -o $(TARGET) main.o keyboard.o $(COMPILEFLAGS)
main.o: main.cpp
$(CC) -c main.cpp -Wno-deprecated
keyboard.o: keyboard.h keyboard.cpp
$(CC) -c keyboard.cpp -Wno-deprecated
clean:
rm -f $(TARGET) main.o
*実行方法
コンパイルして
make
実行
./doppler
*実行結果
[[Doppler.mp3>http://www20.atwiki.jp/yosilove?cmd=upload&act=open&pageid=23&file=doppler.mp3]]
*メモ
makeすると以下のようなメッセージが出たりするかもしれません。
main.cpp:57: warning: ‘alutUnloadWAV’ is deprecated (declared at /usr/local/include/AL/alut.h:116)
これは「alutLoadWAVFile」は今後のバージョンアップで使えなくなるかもよというメッセージです。
ALUTがバージョンアップすると、この関数は別の関数で置き換える必要がでるかも知れないので注意!
*テスト環境
|MacOSX 10.5.8|
|i686-apple-darwin9-g++-4.0.1 (GCC) 4.0.1|
|OpenAL|
|ALUT 1.1.0|
*Tanks
[[OpenAL Lesson 3: Multiple Sources>http://www.devmaster.net/articles/openal-tutorials/lesson3.php]]
----
*&this_page()
|&tags()|[[解説>ドップラー効果(Doppler Effect)]]|最終更新日 &date()|&link_pdf(text=PDFで表示)|[[ダウンロード>http://www20.atwiki.jp/yosilove?cmd=upload&act=open&pageid=23&file=Doppler.zip]]|View &counter(total)|
OpenALでドップラー効果を再現するサンプル。
ALUTが必要です。
#contents
*main.cpp
//OpenALを用いたドップラー効果のサンプル
#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#include <OpenAL/al.h>
#include <OpenAL/alc.h>
#include <AL/alut.h>
#include "keyboard.h"
ALuint Buffer;// Buffers hold sound data.
ALuint Source;// Sources are points of emitting sound.
/* 設定 */
//-- 音源(Source)の設定
ALfloat pitch = 1.0f;
ALfloat gain = 1.0f;
ALfloat SourcePos[] = { 0.0f, 0.0f, -50.0f };// Position of the source sound.
ALfloat SourceVel[] = { 0.0f, 0.0f, 40.0f };// Velocity of the source sound.
//単純にPosition += Velocityとすると時間が早すぎるので適当に補正値を掛けてみたり
//Position += revise*Velocity
const float revise = 0.000003;
//-- 観測者(Listener)の設定
ALfloat ListenerPos[] = { 0.0, 0.0, 0.0 };// Position of the listener.
ALfloat ListenerVel[] = { 0.0, 0.0, 0.0 };// Velocity of the listener.
// Orientation of the listener. (first 3 elements are "at", second 3 are "up")
ALfloat ListenerOri[] = { 0.0, 0.0, -1.0, 0.0, 1.0, 0.0 };
//-- その他の設定
ALfloat SourceMaxDist = 80.0;//これ以上離れると初期位置に戻る
//-- ドップラー効果の設定
//shift = DOPPLER_FACTOR * freq * (DOPPLER_VELOCITY - listener.velocity) / (DOPPLER_VELOCITY + source.velocity)
#define DOPPLER_FACTOR 0.5f
#define DOPPLER_VELOCITY 10.0f
/*
* ALboolean LoadALData()
*wavデータの読み込みと音源の初期設定
*/
ALboolean LoadALData()
{
ALenum format;
ALsizei size;
ALvoid* data;
ALsizei freq;
ALboolean loop;
// Load wav data into a buffer.
alGenBuffers(1, &Buffer);
if(alGetError() != AL_NO_ERROR) return AL_FALSE;
//wavファイルの読み込み
alutLoadWAVFile((ALbyte*)"wavdata/Ambulance.wav", &format, &data, &size, &freq);
alBufferData(Buffer, format, data, size, freq);
alutUnloadWAV(format, data, size, freq);
// Bind the buffer with the source.
alGenSources(1, &Source);
if(alGetError() != AL_NO_ERROR) return AL_FALSE;
//ソースの初期設定
alSourcei (Source, AL_BUFFER, Buffer );//音源
alSourcef (Source, AL_PITCH, pitch );//ピッチ
alSourcef (Source, AL_GAIN, gain );//ゲイン
alSourcefv(Source, AL_POSITION, SourcePos);//座標
alSourcefv(Source, AL_VELOCITY, SourceVel);//移動
alSourcei (Source, AL_LOOPING, AL_TRUE );//繰り返す
// Do an error check and return.
if(alGetError() != AL_NO_ERROR) return AL_FALSE;
return AL_TRUE;
}
/*
* void SetListenerValues()
* 観測者の設定
*/
void SetListenerValues()
{
alListenerfv(AL_POSITION, ListenerPos);
alListenerfv(AL_VELOCITY, ListenerVel);
alListenerfv(AL_ORIENTATION, ListenerOri);
}
/*
* void KillALData()
* お掃除
*/
void KillALData()
{
alDeleteBuffers(1, &Buffer);
alDeleteSources(1, &Source);
alutExit();
}
int main(int argc, char *argv[]) {
int i;//カウンタ
ALboolean far=AL_FALSE;//遠いかどうかのフラグ
printf("Doppler Effect\n");
printf("(Press any key to quit.)\n");
// 初期化
alutInit(NULL,0);
alGetError();
// ソースの設定
if(LoadALData() == AL_FALSE)
{
printf("Error loading data.");
return 0;
}
//観測者の設定
SetListenerValues();
// お掃除関数の指定
atexit(KillALData);
// 再生開始
alSourcePlay(Source);
//初期値を保存
ALfloat SourceDefPos[] = { SourcePos[0], SourcePos[1], SourcePos[2] };
//ドップラー効果の設定
alDopplerFactor(DOPPLER_FACTOR);
alDopplerVelocity(DOPPLER_VELOCITY);
while(!kbhit()){
far=AL_FALSE;
for(i=0;i<3;i++){
//座標を更新
SourcePos[i] += revise*SourceVel[i];
//遠い?
if( sqrt(abs(pow(SourcePos[i],2)+pow(ListenerPos[i],2)) ) > SourceMaxDist) far = AL_TRUE;
}
//遠かったらはじめの位置に戻る
if(far) for(i=0;i<3;i++) SourcePos[i]=SourceDefPos[i];
alSourcefv(Source, AL_POSITION, SourcePos);
}
return 0;
}
*keyboard.cpp
/*
This is the unix code for kbhit I found on google at
http://www.linuxquestions.org/questions/archive/9/2002/10/4/34027
*/
#include "keyboard.h"
void init_keyboard()
{
tcgetattr(0,&initial_settings);
new_settings = initial_settings;
new_settings.c_lflag &= ~ICANON;
new_settings.c_lflag &= ~ECHO;
new_settings.c_lflag &= ~ISIG;
new_settings.c_cc[VMIN] = 1;
new_settings.c_cc[VTIME] = 0;
tcsetattr(0, TCSANOW, &new_settings);
}
void close_keyboard()
{
tcsetattr(0, TCSANOW, &initial_settings);
}
int kbhit()
{
char ch;
int nread;
if(peek_character != -1)
return 1;
new_settings.c_cc[VMIN]=0;
tcsetattr(0, TCSANOW, &new_settings);
nread = read(0,&ch,1);
new_settings.c_cc[VMIN]=1;
tcsetattr(0, TCSANOW, &new_settings);
if(nread == 1)
{
peek_character = ch;
return 1;
}
return 0;
}
int readch()
{
char ch;
if(peek_character != -1)
{
ch = peek_character;
peek_character = -1;
return ch;
}
read(0,&ch,1);
return ch;
}
*keyboad.h
/*
This is the unix code for kbhit I found on google at
http://www.linuxquestions.org/questions/archive/9/2002/10/4/34027
*/
#include <stdio.h>
#include <termios.h>
#include <term.h>
#include <curses.h>
#include <unistd.h>
static struct termios initial_settings, new_settings;
static int peek_character = -1;
void init_keyboard();
void close_keyboard();
int kbhit();
int readch();
*Makefile
**Mac
CC = g++
TARGET = doppler
COMPILEFLAGS = -framework OpenAL -lalut
$(TARGET): main.o keyboard.o
$(CC) -o $(TARGET) main.o keyboard.o $(COMPILEFLAGS)
main.o: main.cpp
$(CC) -c main.cpp -Wno-deprecated
keyboard.o: keyboard.h keyboard.cpp
$(CC) -c keyboard.cpp -Wno-deprecated
clean:
rm -f $(TARGET) main.o
*実行方法
コンパイルして
make
実行
./doppler
*実行結果
[[Doppler.mp3>http://www20.atwiki.jp/yosilove?cmd=upload&act=open&pageid=23&file=doppler.mp3]]
*メモ
makeすると以下のようなメッセージが出たりするかもしれません。
main.cpp:57: warning: ‘alutUnloadWAV’ is deprecated (declared at /usr/local/include/AL/alut.h:116)
これは「alutLoadWAVFile」は今後のバージョンアップで使えなくなるかもよというメッセージです。
ALUTがバージョンアップすると、この関数は別の関数で置き換える必要がでるかも知れないので注意!
*テスト環境
|MacOSX 10.5.8|
|i686-apple-darwin9-g++-4.0.1 (GCC) 4.0.1|
|OpenAL|
|ALUT 1.1.0|
*Tanks
[[ドップラー効果>http://ja.wikipedia.org/wiki/ドップラー効果]]
[[OpenAL Lesson 7: The Doppler Effec>http://www.devmaster.net/articles/openal-tutorials/lesson7.php]]
[[WEB WAVE LIB>http://www.s-t-t.com/wwl/]]
このプログラムに同梱されているwavファイルを頂きました。wavファイル「Ambulance.wav」を他のプログラムに利用する際には、必ずWEB WAVE LIBさんの規約に従ってください。
----
表示オプション
横に並べて表示:
変化行の前後のみ表示: