※上記の広告は60日以上更新のないWIKIに表示されています。更新することで広告が下部へ移動します。

音源の移動-CPP

ALUT CPP Mac OpenAL ソースコード 解説 最終更新日 2009-09-25 : View -
link_pdfプラグインはご利用いただけなくなりました。
ダウンロード View -

OpenALで音源が移動してゆくサンプル。
ALUTが必要です。


main.cpp

#include <time.h>
#include <stdlib.h>
#include <stdio.h>

#include <OpenAL/al.h>
#include <OpenAL/alc.h>
#include <AL/alut.h>

#include "keyboard.h"

// Buffers hold sound data.
ALuint Buffer;

// Sources are points of emitting sound.
ALuint Source;

// Position of the source sound.
ALfloat SourcePos[] = { 0.0f, 0.0f, 0.0f };

// Velocity of the source sound.
ALfloat SourceVel[] = { 0.0f, 0.0f, 0.5f };

// Position of the listener.
ALfloat ListenerPos[] = { 0.0, 0.0, 0.0 };

// Velocity of the listener.
ALfloat ListenerVel[] = { 0.0, 0.0, 0.0 };

// 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 };


/*
 * ALboolean LoadALData()
 *
 *	This function will load our sample data from the disk using the alut
 *	utility and send the data into OpenAL as a buffer. A source is then
 *	also created to play that buffer.
 */
ALboolean LoadALData()
{
	// Variables to load into.

	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/Footsteps.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,    1.0f     );//ピッチ
	alSourcef (Source, AL_GAIN,     1.0f     );//ゲイン
	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()
 *
 *	We already defined certain values for the listener, but we need
*	to tell OpenAL to use that data. This function does just that.
* リスナーの設定
 */
void SetListenerValues()
{
	alListenerfv(AL_POSITION,    ListenerPos);
	alListenerfv(AL_VELOCITY,    ListenerVel);
	alListenerfv(AL_ORIENTATION, ListenerOri);
}

/*
 * void KillALData()
 *
 *	We have allocated memory for our buffers and sources which needs
*	to be returned to the system. This function frees that memory.
* お掃除
 */
void KillALData()
{
	alDeleteBuffers(1, &Buffer);
	alDeleteSources(1, &Source);
	alutExit();
}



int main(int argc, char *argv[]) {

	printf("MindCode's OpenAL Lesson 2: Looping and Fadeaway\n\n");
	printf("Footsteps will slowly start to fade into the distance.\n");
	printf("(Press any key to quit.)\n");
	

	// Initialize OpenAL and clear the error bit.
	alutInit(NULL,0);
	alGetError();

	// ソースの設定
	if(LoadALData() == AL_FALSE)
	{
	    printf("Error loading data.");
		return 0;
	}
	
	//リスなの設定
	SetListenerValues();

	// Setup an exit procedure.
	atexit(KillALData);

	// Begin the source playing.
	alSourcePlay(Source);

	// Loop
	ALint time = 0;//経過時間
	ALint elapse = 0;//カウンタ
	
	
	while(!kbhit())
	{
		elapse += (clock()/CLOCKS_PER_SEC) - time;
		time += elapse;

		if(elapse > 1)//2秒に一回実行
		{
			elapse = 0;
			//座標を更新
			SourcePos[0] += SourceVel[0];
			SourcePos[1] += SourceVel[1];
			SourcePos[2] += SourceVel[2];
			printf("Source (%f,%f,%f) \n",SourcePos[0],SourcePos[1],SourcePos[2]);
			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 = lesson2

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

実行
./lesson2

実行結果


Move.mp3
音量が小さいので注意。

メモ

「座標は表示されるのに音が鳴らない」という人
→音源の位置が遠すぎて音が聞こえない場合があります
→main.cppの「if(elapse > 1)」の部分や「ALfloat SourceVel[] = { 0.0f, 0.0f, 0.5f };」の部分を編集してみましょう。

makeすると以下のようなメッセージが出たりするかもしれません。
g++ -c main.cpp -Wno-deprecated
main.cpp: In function ‘ALboolean LoadALData()’:
main.cpp:54: warning: ‘alutLoadWAVFile’ is deprecated (declared at /usr/local/include/AL/alut.h:110)
main.cpp:54: warning: ‘alutLoadWAVFile’ is deprecated (declared at /usr/local/include/AL/alut.h:110)
main.cpp:56: warning: ‘alutUnloadWAV’ is deprecated (declared at /usr/local/include/AL/alut.h:116)
main.cpp:56: warning: ‘alutUnloadWAV’ is deprecated (declared at /usr/local/include/AL/alut.h:116)
g++ -o lesson2 main.o keyboard.o -framework OpenAL -lalut
これは「alutLoadWAVFile」と「alutUnloadWAV」は今後のバージョンアップで使えなくなるかもよというメッセージです。
ALUTがバージョンアップすると、この二つの関数は別の関数で置き換える必要がでるかも知れないので注意!

テスト環境

MacOSX 10.5.8
i686-apple-darwin9-g++-4.0.1 (GCC) 4.0.1
OpenAL
ALUT 1.1.0

Tanks



添付ファイル