OpenAL의 시작
Openal에 대한 정보가 너무 없네요... 특히 한국어로 된 정보는 찾기 너무 힘듬..ㅜ;;
어떻게 제가 찾은 정보라도 번역해서 포스트 해봅니다.
1. Opanal 구조
OPENAL이 초기화 될 때, 적어도 하나의 Device가 초기화 되야 하고, Device하나가 초기화 될 때, 적어도 하나의 Context가 초기화 되어야 합니다. 그리고 Context가 초기화 될 때, 하나의 Listener 객체가 생성되고, 여러개의 Source객체를 생성할 수 있게 되고, 그것에 하나 또는 추가적인 Buffer객체를 연결할 수 있습니다. 여기서 Buffer는 Context의 일부가 아니라 하나의 Device에 있는 모든 Context에 섞여 나뉘어져 있는 것입니다.
2. Device 초기화
// 초기화
Device = alcOpenDevice(NULL); // 운영체제에서 사용하고 있는 오디오 장치를 사용
if (Device)
{
Context=alcCreateContext(Device,NULL);
alcMakeContextCurrent(Context);
}
// Check for EAX 2.0 support
g_bEAX = alIsExtensionPresent("EAX2.0");
// Buffer객체 생성
alGetError(); // error code를 비움
alGenBuffers(NUM_BUFFERS, g_Buffers);
if ((error = alGetError()) != AL_NO_ERROR)
{
DisplayALError("alGenBuffers :", error);
return;
}
// test.wav 불러옴
loadWAVFile("test.wav",&format,&data,&size,&freq,&loop);
if ((error = alGetError()) != AL_NO_ERROR)
{
DisplayALError("alutLoadWAVFile test.wav : ", error);
alDeleteBuffers(NUM_BUFFERS, g_Buffers);
return;
}
// test.wav 데이터를 AL Buffer 0로 복사함
alBufferData(g_Buffers[0],format,data,size,freq);
if ((error = alGetError()) != AL_NO_ERROR)
{
DisplayALError("alBufferData buffer 0 : ", error);
alDeleteBuffers(NUM_BUFFERS, g_Buffers);
return;
}
// test.wav 내보냄
unloadWAV(format,data,size,freq);
if ((error = alGetError()) != AL_NO_ERROR)
{
DisplayALError("alutUnloadWAV : ", error);
alDeleteBuffers(NUM_BUFFERS, g_Buffers);
return;
}
// Source객체 생성
alGenSources(1,source);
if ((error = alGetError()) != AL_NO_ERROR)
{
DisplayALError("alGenSources 1 : ", error);
return;
}
// buffer 0과 source를 연결
alSourcei(source[0], AL_BUFFER, g_Buffers[0]);
if ((error = alGetError()) != AL_NO_ERROR)
{
DisplayALError("alSourcei AL_BUFFER 0 : ", error);
}
// 나가기
Context=alcGetCurrentContext();
Device=alcGetContextsDevice(Context);
alcMakeContextCurrent(NULL);
alcDestroyContext(Context);
alcCloseDevice(Device);
3. Listener 속성
ALfloat listenerPos[]={0.0,0.0,0.0};
ALfloat listenerVel[]={0.0,0.0,0.0};
ALfloat listenerOri[]={0.0,0.0,-1.0, 0.0,1.0,0.0};
// Listener의 좌표...
alListenerfv(AL_POSITION,listenerPos);
if ((error = alGetError()) != AL_NO_ERROR)
{
DisplayALError("alListenerfv POSITION : ", error);
return;
}
// Listener의 속력...
// velocity is essentially the speed of sound
alListenerfv(AL_VELOCITY,listenerVel);
if ((error = alGetError()) != AL_NO_ERROR)
{
DisplayALError("alListenerfv VELOCITY : ", error);
return;
}
// Listen의 방위...
//orientation expressed as “at” and “up” vectors
alListenerfv(AL_ORIENTATION,listenerOri);
if ((error = alGetError()) != AL_NO_ERROR)
{
DisplayALError("alListenerfv ORIENTATION : ", error);
return;
}
속성 | 데이터 타입 | 설명 |
AL_GAIN | f, fv | “master gain(patch volume)” 소리의 크기를 설정한다. 값은 정수여야 한다. |
AL_POSITION | fv, 3f, iv, 3i | X, Y, Z 좌표 |
AL_VELOCITY | fv, 3f, iv, 3i | 속도 벡터 |
AL_ORIENTATION | fv, iv | orientation은 at벡터와up벡터를 표현한다. |
4. Buffer의 속성
// Buffer의 주파수를 재 설정함.
alBufferi(g_Buffers[0], AL_FREQUENCY, iFreq);
속성 | 데이터 타입 | 설명 |
AL_ FREQUENCY | i, iv | 버퍼의 주파수(단위 Hz) |
AL_ BITS | i, iv | 버퍼의 깊이(bit) |
AL_ CHANNELS | i, iv | 버퍼의 채널 갯수 > 1개가 유효하지만 버퍼가 재생될 때, 설정할 수 없습니다. |
AL_ SIZE | i, iv | 버퍼의 사이즈(bytes) |
AL_DATA | i, iv | original location where data was copied from generally useless, as was probably freed after buffer creation |
5. Source의 속성
alGetError(); // 에러버퍼를 비움
alSourcef(source[0],AL_PITCH,1.0f);
if ((error = alGetError()) != AL_NO_ERROR)
DisplayALError("alSourcef 0 AL_PITCH : \n", error);
alGetError(); // 에러버퍼를 비움
alSourcef(source[0],AL_GAIN,1.0f);
if ((error = alGetError()) != AL_NO_ERROR)
DisplayALError("alSourcef 0 AL_GAIN : \n", error);
alGetError(); // 에러버퍼를 비움
alSourcefv(source[0],AL_POSITION,source0Pos);
if ((error = alGetError()) != AL_NO_ERROR)
DisplayALError("alSourcefv 0 AL_POSITION : \n", error);
alGetError(); // 에러버퍼를 비움
alSourcefv(source[0],AL_VELOCITY,source0Vel);
if ((error = alGetError()) != AL_NO_ERROR)
DisplayALError("alSourcefv 0 AL_VELOCITY : \n", error);
alGetError(); // 에러버퍼를 비움
alSourcei(source[0],AL_LOOPING,AL_FALSE);
if ((error = alGetError()) != AL_NO_ERROR)
DisplayALError("alSourcei 0 AL_LOOPING true: \n", error);
Property | Data Type | Description |
AL_PITCH | f, fv | pitch를 설정 정수를 입력해야 한다. |
AL_GAIN | f, fv | source의 볼륨 설정 정수만 입력해야 한다. |
AL_MAX_DISTANCE | f, fv, i, iv | 소리가 들리는 범위의 최대 거리를 설정. |
AL_ROLLOFF_FACTOR | f, fv, i, iv | the rolloff rate for the source 기본값이 1.0 |
AL_REFERENCE_DISTANCE | f, fv, i, iv | the distance under which the volume for the source would normally drop by half (before being influenced by rolloff factor or AL_MAX_DISTANCE) |
AL_MIN_GAIN | f, fv | 이 source의 최소 볼륨을 설정 |
AL_MAX_GAIN | f, fv | 이 source의 최대 볼륨을 설정 |
AL_CONE_OUTER_GAIN | f, fv | the gain when outside the oriented cone |
AL_CONE_INNER_ANGLE | f, fv, i, iv | the gain when inside the oriented cone |
AL_CONE_OUTER_ANGLE | f, fv, i, iv | outer angle of the sound cone, in degrees 기본값이 360 |
AL_POSITION | fv, 3f | X, Y, Z 좌표 |
AL_VELOCITY | fv, 3f | 속도 벡터 |
AL_DIRECTION | fv, 3f, iv, 3i | 방향 벡터 |
AL_SOURCE_RELATIVE | i, iv | determines if the positions are relative to the listener 기본값이 AL_FALSE |
AL_SOURCE_TYPE | i, iv | source 타입– AL_UNDETERMINED, AL_STATIC, 또는AL_STREAMING |
AL_LOOPING | i, iv | 반복을 on (AL_TRUE) 또는 off (AL_FALSE)로 바꾼다. |
AL_BUFFER | i, iv | the ID of the attached buffer |
AL_SOURCE_STATE | i, iv | source의 속성 (AL_STOPPED, AL_PLAYING, …) |
AL_BUFFERS_QUEUED | i, iv | the number of buffers queued on this source |
AL_BUFFERS_PROCESSED | i, iv | the number of buffers in the queue that have been processed |
AL_SEC_OFFSET | f, fv, i, iv | 초(second) 단위로 플레이 위치를 |
AL_SAMPLE_OFFSET | f, fv, i, iv | 셈플(samples) 단위로 플레이 위치를 바꾼다. |
AL_BYTE_OFFSET | f, fv, i, iv | 바이트(Bytes) 단위로 플레이 위치를 바꾼다. |
6. 에러 핸들링
// 버퍼를 생성
if ((error = alGetError()) != AL_NO_ERROR)
{
DisplayALError("alGenBuffers :", error);
exit(-1);
}
Error Code | Description |
AL_NO_ERROR | 에러가 발생하지 않았음. |
AL_INVALID_NAME | OpenAL 함수에 잘못된 이름이(ID) 전달됨. |
AL_INVALID_ENUM | OepanAL 함수에 잘못된 enum값이 전달됨. |
AL_INVALID_VALUE | OpenAL 함수에 잘못된 매개변수를 전달됨. |
AL_INVALID_OPERATION | 요청한 작업이 유효하지 않음. |
AL_OUT_OF_MEMORY | 요청한 작업에 대해 사용할 메모리가 부족할 때, |