프로그래밍 관련/사운드

GPG DIRECT SOUND 다중 사운드 출력 관련 질문 답변

AlrepondTech 2020. 9. 13. 21:43
반응형

 

 

 

 

=================================

=================================

=================================

 

 

 

 


추가 링크 사이트 (GPG 질문/답변)
- http://www.gpgstudy.com/forum/viewtopic.php?p=74088&sid=627408e7c2deaea25c1eb959f36da22e
- http://www.gpgstudy.com/forum/viewtopic.php?t=14708&sid=0e9487c41d5c6b12b53caa65c4bf6f26
- http://www.gpgstudy.com/forum/viewtopic.php?p=81705
- http://www.gpgstudy.com/forum/viewtopic.php?topic=2526
- http://www.gpgstudy.com/forum/viewtopic.php?topic=5057
- http://www.gpgstudy.com/forum/viewtopic.php?t=16014


다중 사운드 플레이에 관심이 있어서 구현해보려고 합니다. 

Ogg, Wav 두가지 포멧을 LPDIRECTSOUNDBUFFER 로 여러 리소스를 관리할 수 있도록 구현을 했습니다만, 

중요한 다중출력이 되지 않았습니다. 


IDirectSound 1개에 여러 리소스를 저장해도 보았고, 

혹시나 해서 IDirectSound 자체를 리소스 개수만큼 만들어내기도(-_-; 했습니다만, 

음원을 출력할 때 이전에 재생되던 녀석이 침묵하는 것 같았습니다. 


단순하게 Play(0,0,0) 시켜본것인데 문제가 발생하니 느낌이 찜찜합니다. 


플레이시키는 함수의 내용입니다. 

LPDIRECTSOUNDBUFFER sound = Get_SoundResource(Key);
DWORD start = Get_SoundStartPoint(Key);
if (!sound) return;
 
sound->SetCurrentPosition (start);
sound->Play (0, 0, 0);

LPDIRECTSOUNDBUFFER는 Primary Buffer 인지라 프로그램 1개당 1개만 사용할 수 있다고합니다. 

DirectSound는 LPDIRECTSOUNDBUFFER8 형태의 Secondary Buffer를 여러개 만들어서 관리한후, 

플레이를 하면, DSound가 알아서 Primary Buffer에 합성을 해서 출력을 해준다고 합니다. 

아직 정말로 저런걸지, 또 합성을 하는 과정을 거쳐야하는지 모르겠습니다만, 관리 자료형을 바꿔야 동시발음이 가능하다는 이야기군요. 


다음과 같은 코드로 LPDIRECTSOUNDBUFFER에서 LPDIRECTSOUNDBUFFER8로 변경할 수 있습니다. 

hr = lpDirectSound->CreateSoundBuffer(&dsbdesc, &pDsb, NULL);
if (SUCCEEDED(hr)) 
{ 
   hr = pDsb->QueryInterface(IID_IDirectSoundBuffer8, (LPVOID*) ppDsb8);
   pDsb->Release();
} 

 

답변 감사드립니다. ~ 

조언주신대로 DuplicateSoundBuffer를 이용하여 사운드를 재생해 보았습니다. 

일단 DSBCAPS_LOCHARDWARE 설정에서는 무리없이 잘 돌아가는것을 확인했습니다. 

하지만 버퍼 생성에 제한이 있더군요.. 

그래서 BGM으로 사용될 사운드는 DSBCAPS_LOCHARDWARE의 설정으로 스트리밍 방식으로 

재생하고 SOUNDEFFECT로 사용될 사운드는 DSBCAPS_LOCSOFTWARE로 설정하여 재생을 

해 보았습니다. 살짝살짝 딜레이가 발생합니다. 이상한 점은 같은 종류의 사운드 이펙트를 

연속으로 재생할때는 딜레이가 많이 발생하지 않지만 다른종류의 사운드를 재생할때는 

약간씩 딜레이가 있었습니다. 

DSBCAPS_LOCHARDWARE와 DSBCAPS_LOCSOFTWARE의 설정차가 

이런 딜레이를 발생시킬수 있나요? 

게시판에 글들을 읽어 본바로는 두개의 차이는 별로 없는 것처럼 보이는데 

원인이 무언지 감이 잡히질 않네요 

아시는분 계시면 답변 부탁드립니다. 

참고로 DirectX 7.0을 이용해서 작업중입니다. (요놈 찾는데 하루 꼬박 걸렸다는 ㅜㅜ) 

기본적인 설정에서 재생까지 과정을 간략하게 소스를 추가해보겠습니다. 

uint32 nFlags =  DSBCAPS_GETCURRENTPOSITION2 | 
        DSBCAPS_CTRLFREQUENCY | 
        DSBCAPS_CTRLVOLUME |
        DSBCAPS_GLOBALFOCUS |
                                DSBCAPS_CTRLPAN;
 
       if(nType == AUD_EFFECT)
    nFlags |= DSBCAPS_LOCSOFTWARE;
       else
    nFlags |= DSBCAPS_LOCHARDWARE;
 
       if(m_Init.m_nType == AUD_EFFECT)
    m_pDSBuffer = new LPDIRECTSOUNDBUFFER[MAX_EFFECT_BUFFER];      
       else
    m_pDSBuffer = new LPDIRECTSOUNDBUFFER;
 
       desc.dwFlags = nFlags;
       desc.lpwfxFormat = &m_WaveFormat;
       desc.dwBufferBytes = nBufferSize;
 
       IDirectSoundBuffer* pDSBuffer;
       HRESULT hr = m_pDS->CreateSoundBuffer(&desc, &pDSBuffer, NULL);
       hr = pDSBuffer->QueryInterface(IID_IDirectSoundBuffer, (void**)&m_pDSBuffer[0]);
       pDSBuffer->Release();
 
       FillBuffer()                    
 
       if(nType == AUD_EFFECT)
       {
    for(int i = 1;i <MAX_EFFECT_BUFFER>;i++)
                       m_pDS->DuplicateSoundBuffer(m_pDSBuffer[0], &m_pDSBuffer[i]);
       }
 
 
::재생함수
 
           int nCurrentBuffer = GetFreeBuffer();
           if(nCurrentBuffer == -1)
          {
                m_nBufferPriority++;
                if(m_nBufferPriority == 4)
                       m_nBufferPriority = 0;
                m_pDSBuffer[m_nBufferPriority]->GetStatus(&dwStatus);
    if(dwStatus & DSBSTATUS_PLAYING)
           hr = m_pDSBuffer[m_nBufferPriority]->SetCurrentPosition(0);
    hr = m_pDSBuffer[m_nBufferPriority]->Play(0, 0, 0);
          }
          else
          {
    hr = m_pDSBuffer[nCurrentBuffer]->Play(0, 0, 0);
          }

 



=================================

=================================

=================================

 

 

 

 

API 함수 PlaySound는 동시에 두 개 이상의 사운드를 출력할 수 없습니다. 
sync 옵션 조절하시면 '두' 앞머리가 짤리는건 막을 수 있는데 대신 뒷부분(~)이 잘려나가기 때문에 여전히 어색하죠. 

두두두두두두두두두~ 를 안끊기게 만드시려면 

DirectSound 를 배워서 직접 라이브러리를 짜거나 (오질라게 복잡해요 ㅡ,.ㅡ) 
사운드 라이브러리를 구해서 쓰셔야 됩니다. 

짤막한 사운드 몇 개 반복해서 내는 정도로 충분하다면 제가 간단하게 만들어 둔 것도 있습니다. 
http://blog.naver.c...m/itioma/40033639361 


P.S. 전 예전에 PlaySound만 가지고 이 문제 해결할 때 
두두두두두두두두두~ 를 통째로 웨이브 파일로 만들어서 썼던 아픈 기억이...

-----------------------------------------------------------------------------------------------------------------------------------------------

다이렉트 사운드 객체를 
음 하나마다 1개씩 만들어서 .. 

DirectSound 예제 보시면 
DirectSoundManager 가 DirectSound 객체를 만들고 
DirectSound 가 wav 하나를 로딩해서 하는 식으로 되어 있더라구요. 

저의 경우는 
DirectSound 객체를 두두두~ 일 경우 
두~ 
두~ 
두~ 

음 3개 각각에 대해 객체를 만든 후에 
각각 플레이 시켰습니다. 

즉 두두두~ 를 플레이 하기 위해서 
DirectSound 객체 3개를 쓴 셈이죠. 

실제는 초당 10발 정도라서 
10개의 객체를 만들어서 사용했습니다. 

물론 메모리는 많이 먹겠지만 
총소리에 한해서 그렇게 했구요. 

근데 이렇게 해도 괜찬은지 모르겠네요. 

그리고 그렇게 해도 두두두두~ 잠시멈춤 두두두두~ 
이렇게 되더라구요. 

그래서 신기해서요.

 

=================================

=================================

=================================

 

 

 

반응형