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
64 NMEA-0183을 이용한 GPS 애플리케이션 제작 digipine 2017.10.28 446
63 OBS Studio for Http Interface EXE lizard2019 2023.02.15 248
» OpenAL 사용법 정리 1 digipine 2017.11.01 3398
61 Phabricator Ubuntu Installation Guide digipine 2022.01.26 440
60 Phabricator 설치 가이드 우분투 12.04 기준 digipine 2017.11.02 1229
59 Phabricator 설치 가이드 우분투 16.04 기준 digipine 2017.11.02 6193
58 Photoshop CC 2018 한글 영문 변환 언어팩, 포토샵 언어변경 file 엉뚱도마뱀 2018.07.04 8531
57 QCAD 1.1 한국 최초의 2D CAD 소프트웨어 file digipine 2017.11.01 831
56 Remove all .git files, recursively digipine 2021.11.26 366
55 RSA 암호화 알고리즘 개요 file 엉뚱도마뱀 2017.11.17 1036
54 select 와 epoll 엉뚱도마뱀 2017.12.11 828
53 TCP/IP State Transition - TCP 스택 포팅 시 참조 file digipine 2017.11.02 195241
52 Thread간 동기화관리자 digipine 2017.10.28 572
51 Ubuntu 12.0.4 LTS에 Nabi 나비 설치하기 digipine 2017.11.03 620
50 Ubuntu 16 에 JAVA 1.7.0 jdk 설치 하기 digipine 2017.11.07 1417
49 Ubuntu 16 에 mysql 5.7 설치 및 원격 설정 file digipine 2017.11.08 1484
48 Ubuntu 18.04 에서 vsftpd 설치하기 lizard2019 2021.03.02 373
47 Ubuntu Git - Latest Version Install digipine 2017.11.02 375
46 Ubuntu Server OS 한국어 모드로 설치 후 서버 콘솔에서 한글 깨짐 해결 방법 digipine 2017.10.31 2248
45 Ubuntu 우분투 설치 가이드 lizard2019 2019.01.29 781
Board Pagination Prev 1 2 3 4 5 6 Next
/ 6