logo

English

이곳의 프로그래밍관련 정보와 소스는 마음대로 활용하셔도 좋습니다. 다만 쓰시기 전에 통보 정도는 해주시는 것이 예의 일것 같습니다. 질문이나 오류 수정은 siseong@gmail.com 으로 주세요. 감사합니다.

OpenAL 사용법 정리

by digipine posted Nov 01, 2017
?

Shortcut

PrevPrev Article

NextNext Article

Larger Font Smaller Font Up Down Go comment Print
?

Shortcut

PrevPrev Article

NextNext Article

Larger Font Smaller Font Up Down Go comment Print

OpenAL이란?

○ 게임이나 또 다른 오디오 어플리케이션을 위해 고안된 3D Audio API로 플랫폼 독립적인 라이브러리다.

○ 사용법이 그리 어렵지 않기 때문에 누구나 조금만 보면 금방 사용할 수 있다.

○ 공식 사이트 : http://connect.creativelabs.com/openal/default.aspx

 

 

 

 OpenAL 사용을 위한 사전 작업

○ OpenAL을 사용하기 위해서는 먼저 사이트로부터 oalinst.exe 를 다운받아 설치해줘야 한다.

○ oalinst.exe  다운로드 :

http://connect.creativelabs.com/openal/Downloads/Forms/AllItems.aspx

 

 

 

 

 공통된 작업

 

 생성 : OpenAL을 사용하기 위한 초기화 작업이다. 부가적인 코드는 모두 생략했다.

 

bool OpenAlInterface::Create()

{

    ALFWInit();

    if( AL_FALSE == ALFWInitOpenAL() )

    {

           ALFWShutdown();

           return false;

    }

 

    return true;

}

 

 해제 : OpenAL을 해제한다. 어플리케이션이 끝나기 전에 반드시 해줘야 한다.

 

void OpenAlInterface::Destroy()

{

    UnloadWave();  // 로드된 Wave데이터가 있다면 해제 시켜주는 함수다.

 

    ALFWShutdownOpenAL();

    ALFWShutdown();

}

 

// 로드된 Wave데이터가 있다면 해제 시켜주는 함수다.

void OpenAlInterface::UnloadWave()

{

    // Stream Data 해제

    if( m_pStreamData )

    {

           delete m_pStreamData;

           m_pStreamData = 0;

    }

 

    // Stream Play에 사용된 Wave Loader 해제

    if( m_pWaveLoader )

    {

           m_pWaveLoader->DeleteWaveFile(m_waveID);

           delete m_pWaveLoader;

           m_pWaveLoader = 0;

    }

 

    // OpenAL은 각 사운드를 ID로 관리한다.

// 하나의 Sound Data가 생성되면 그 Sound Data를 대표하는 하나의 ID가 보여되고,

// 그 ID를 통해 접근 할 수 있다.

// 현재 로드된 Sound Data가 있다면 해제한다.

    if( m_uiSourceID )

    {

           alDeleteSources(m_uiSourceSize, &m_uiSourceID);

           m_uiSourceID = 0;

           m_uiSourceSize = 1;

    }

 

    // Sound Data가 채워질 버퍼를 대표하는 ID들의 리스트를 해제한다.

    if( m_pBuffersID )

    {

           alDeleteBuffers(m_uiBufferSize, m_pBuffersID);

           delete[] m_pBuffersID;

           m_pBuffersID = 0;

           m_uiBufferSize = 1;

    }

}

 

 

 

 Static Play를 위한 작업 : Static Play에 필요한 기본적인 함수들이다.

 

// Wave 파일을 로드한다.

bool OpenAlInterface::LoadWaveStatic(std::string strFilename)

{

    m_pBuffersID = new unsigned int[m_uiBufferSize];

 

    alGenBuffers(m_uiBufferSize, m_pBuffersID);

    alGenSources(m_uiSourceSize, &m_uiSourceID);

 

    if( AL_FALSE == ALFWLoadWaveToBuffer(strFilename.c_str(), m_pBuffersID[0]) )

           return false;

 

    // Source ID의 Sound Data가 채워질 BufferID를 설정한다.

    alSourcei(m_uiSourceID, AL_BUFFER, m_pBuffersID[0]);

 

    return true;

}

 

bool OpenAlInterface::UpdateStatic()

{

    if( m_iState != AL_PLAYING )

           return false;

 

    Sleep(100);

 

    // 현재 Source의 상태를 플레이 중인지 아닌지를 얻는다.

    alGetSourcei( m_uiSourceID, AL_SOURCE_STATE, &m_iState);

 

    return true;

}

 

// 플레이 시키는 함수

void OpenAlInterface::PlayStatic()

{

    // Play Source

    alSourcePlay( m_uiSourceID );

    m_iState = AL_PLAYING;

}

 

// 스톱 시키는 함수

void OpenAlInterface::StopStatic()

{

    alSourceStop(m_uiSourceID);

    m_iState = AL_INITIAL;

}

 

 

 

 Stream Play를 위한 작업 : 다음은 Stream Play를 위한 함수들이다. 아무래도 기본적인 Static Play보다는 좀더 복잡하다.

 

bool OpenAlInterface::LoadWaveStream(std::string strFilename, unsigned int uiBufferSize)

{

    // static에서는 BufferID가 하나만 잇으면 되엇지만

    // Stream Play시는 적어도 4개 정도의 Buffer가 필요하다.

    m_uiBufferSize = uiBufferSize;

    m_pBuffersID = new unsigned int[m_uiBufferSize];

   

    alGenBuffers(m_uiBufferSize, m_pBuffersID);

    alGenSources(m_uiSourceSize, &m_uiSourceID);

 

    m_pWaveLoader = new CWaves();

   

    // WaveLoader를 통해 WaveFile을 오픈한다.

    // WaveLoader는 직접 만들어도 되고 OpenAL 샘플에서 제공하는 것을 가져다 써도 된다.

    if( WR_OK != m_pWaveLoader->OpenWaveFile(strFilename.c_str(), &m_waveID) )

           return false;

 

    // WaveLoader의 임무 중 하나는 이렇게 Wave의 정보를 얻는대 있다.

    m_pWaveLoader->GetWaveSize(m_waveID, &m_ulStreamDataSize);

    m_pWaveLoader->GetWaveFrequency(m_waveID, &m_ulStreamFrequency);

    m_pWaveLoader->GetWaveALBufferFormat(m_waveID, &alGetEnumValue, &m_ulStreamFormat);

    m_pWaveLoader->GetWaveFormatExHeader(m_waveID, &m_waveFormatEx);

 

    m_uiStreamBufferSize = m_waveFormatEx.nAvgBytesPerSec >> 2;

    m_uiStreamBufferSize -= (m_uiStreamBufferSize % m_waveFormatEx.nBlockAlign);

 

    if( 0 == m_ulStreamFormat )

           return false;

 

    m_pStreamData = malloc(m_uiStreamBufferSize);

    if( 0 == m_pStreamData )

           return false;

 

    // Audio Data의첫번째부터읽도록세팅

    m_pWaveLoader->SetWaveDataOffset(m_waveID, 0);

 

    // Buffer를audio data로채운다.

    unsigned long ulBytesWritten;

    for(int index=0 ; index<m_uiBufferSize ; ++index)

    {

           if( WR_OK == m_pWaveLoader->ReadWaveData(m_waveID, m_pStreamData, m_uiStreamBufferSize, &ulBytesWritten) )

           {

                   alBufferData(m_pBuffersID[index], m_ulStreamFormat, m_pStreamData, ulBytesWritten, m_ulStreamFrequency);

                   alSourceQueueBuffers(m_uiSourceID, 1, &m_pBuffersID[index]);

           }

    }

 

    m_bStreamPlay = false;

 

    return true;

}

 

// 다음은 매 틱마다 플레이시켜주기 위한 함수다.

bool OpenAlInterface::UpdateStream()

{

    if( false == m_bStreamPlay )

           return false;

 

    if( m_iState != AL_PLAYING )

           return false;

 

    Sleep(20);

 

    int iBuffersProcessed = 0;

    alGetSourcei(m_uiSourceID, AL_BUFFERS_PROCESSED, &iBuffersProcessed);

 

    unsigned long ulBytesWritten;

    while( iBuffersProcessed )

    {

           unsigned int uiBuffer = 0;

           alSourceUnqueueBuffers(m_uiSourceID, 1, &uiBuffer);

 

           m_pWaveLoader->ReadWaveData(m_waveID, m_pStreamData, m_uiStreamBufferSize, &ulBytesWritten);

           if( ulBytesWritten )

           {

                   alBufferData(uiBuffer, m_ulStreamFormat, m_pStreamData, ulBytesWritten, m_ulStreamFrequency);

                   alSourceQueueBuffers(m_uiSourceID, 1, &uiBuffer);

           }

 

           iBuffersProcessed--;

    }

 

    alGetSourcei(m_uiSourceID, AL_SOURCE_STATE, &m_iState);

    if( m_iState != AL_PLAYING )

    {

           int iQueuedBuffers;

           alGetSourcei(m_uiSourceID, AL_BUFFERS_QUEUED, &iQueuedBuffers);

           if( iQueuedBuffers )

           {

                   alSourcePlay(m_uiSourceID);

                   m_iState = AL_PLAYING;

           }

           else

           {

                   StopStream();

           }

    }

 

    return true;

}

 

// 플레이 시켜주는 함수.

void OpenAlInterface::PlayStream()

{

    alSourcePlay(m_uiSourceID);

 

    m_bStreamPlay = true;

    m_iState = AL_PLAYING;

}

 

// 스톱 시켜주는 함수

void OpenAlInterface::StopStream()

{

    alSourceStop(m_uiSourceID);

    alSourcei(m_uiSourceID, AL_BUFFER, 0);

 

    m_bStreamPlay = false;

    m_iState = AL_INITIAL;

}

TAG •

List of Articles
No. Subject Author Date Views
44 Phabricator Ubuntu Installation Guide digipine 2022.01.26 440
» OpenAL 사용법 정리 1 digipine 2017.11.01 3398
42 OBS Studio for Http Interface EXE lizard2019 2023.02.15 248
41 NMEA-0183을 이용한 GPS 애플리케이션 제작 digipine 2017.10.28 446
40 mongoose 3.8 싱글 파일 소스 코드 file digipine 2020.09.01 335
39 MongoDB 설치 및 C 개발 도구 설정 1 digipine 2020.09.03 449
38 MacOS 10.12.2 (OSX) 보안 취약점 공격 코드 2 file digipine 2017.11.02 1556
37 MacOS 10.12.2 (OSX) 보안 취약점 공격 코드 digipine 2017.11.02 606
36 MacOS 10.12.2 (OSX) 보안 취약점 공격 기초 digipine 2017.11.02 663
35 MacOS 10.12.2 (OSX) KERNEL DEBUGGING file digipine 2017.11.02 1470
34 MAC Screen Sharing을 위한 VNC 접속을 위한 Port 변경 방법 digipine 2022.09.05 383
33 Mac Address 를 String 으로 변환하는 간편한 방법 digipine 2017.11.02 437
32 Linux/OSX bash에서 source 명령어 lizard2019 2019.01.07 779
31 Linux(리눅스) 파일 시스템 정리 (ext, ext2, ext3, ext4) digipine 2017.10.29 1109
30 Linux Kernel 컴파일 및 Patch 방법 digipine 2017.11.02 1099
29 Linux init.d 에서 등록하기. 부팅 시 자동실행 설정 digipine 2017.11.03 12631
28 Linux /dev/random vs /dev/urandom 삽질 후기 엉뚱도마뱀 2017.11.22 957
27 LibVLC 미디어 재생기 프로그래밍 방법 C++, QT 엉뚱도마뱀 2018.04.20 2504
26 Let's Encrypt SSL 인증서 자동 갱신 설정 방법 digipine 2020.09.03 742
25 JDK Install ubuntu digipine 2017.11.02 355
Board Pagination Prev 1 2 3 4 5 6 Next
/ 6