wav 스트리밍 서버 만들려고 하는데 도대체 갈피를 못 잡겠어요
글쓴이: kknd345 / 작성시간: 월, 2005/02/21 - 9:09오전
지금 어디서 잘못 됐는지 모르겠습니다.
이번에 wav파일의 스트리밍에 대해서 처음 해보는 거라서 책 보고 예제파일 보아도 각이 안 나오네요.
예제파일은 하드의 wav파일을 바로 플레이 하는거라 바로 스트리밍 시키는 거랑은 많이 차이가 나는 것 같습니다.
조언 부탁드립니다. 아님 비슷한 소스 파일이라도 ㅜㅜ..
밑에 소스 코드는 중요한 것만 올린거라.. 갑자기 등장하는게 있어도 이해해주세요.
BOOL m_bIsPlaying;
DWORD m_dwBufferBytes;
LPDIRECTSOUNDBUFFER m_lpDSBuffer;// Second Sound buffer
LPDIRECTSOUND m_pDSound;
LPDIRECTSOUNDBUFFER pDSBPrimary ;
//DlgDownWaveFormat가 서버로 부터 보낼 wav 파일의 WAVEFORMATEX 형태인 wav해더이고요.
//DlgDownWaveFormat 를 이용하여 아래 처럼 1차 2차 버퍼를 생성했습니다.
////////////////////////////////////////////////////////////////////////////////
// 1 차 버퍼 생성
WAVEFORMATEX wfx;
ZeroMemory( &wfx, sizeof(WAVEFORMATEX) );
wfx.cbSize = DlgDownWaveFormat.cbSize;
wfx.nAvgBytesPerSec =DlgDownWaveFormat.nAvgBytesPerSec;
wfx.nBlockAlign =DlgDownWaveFormat.nBlockAlign;
wfx.nChannels =DlgDownWaveFormat.nChannels;
wfx.nSamplesPerSec =DlgDownWaveFormat.nSamplesPerSec;
wfx.wBitsPerSample =DlgDownWaveFormat.wBitsPerSample;
wfx.wFormatTag =DlgDownWaveFormat.wFormatTag;
if( FAILED( hr = pDSBPrimary->SetFormat(&wfx) ) )
{
::AfxMessageBox("PRIMARY BUFFER의 포맷을 결정하지 못했습니다.");
return hr;
}
////////////////////////////////////////////////////////////////////////////////
// 2차 버퍼 생성
DSBUFFERDESC dsbd;
ZeroMemory( &dsbd, sizeof(DSBUFFERDESC) );
dsbd.dwSize = sizeof(DSBUFFERDESC);
dsbd.dwFlags = DSBCAPS_STICKYFOCUS;
dsbd.dwBufferBytes = 500; // 멀넣어야 할지 잘 몰라서 임의로 잡았습니다.
dsbd.lpwfxFormat = &DlgDownWaveFormat;
//dsbd.dwBufferBytes = DlgDownWaveFormat.cbSize;
//dsbd.lpwfxFormat = DlgDownWaveFormat.;
if( FAILED( hr = m_pDSound->CreateSoundBuffer( &dsbd, &m_lpDSBuffer, NULL ) ) )
{
::AfxMessageBox("DIRECT BUFFER를 생성하는데 실패했습니다.");
return hr;
}
// Remember how big the buffer is
m_dwBufferBytes = dsbd.dwBufferBytes;
////////////////////////////////////////////////////////////////////////////////
//예제 파일에 있던 함수 GetBufferControl를 실행 해주고요.
DWORD dwStatus;
if( FAILED( hr = m_lpDSBuffer->GetStatus( &dwStatus ) ) )
return hr;
if( dwStatus & DSBSTATUS_BUFFERLOST )
{
do
{
hr = m_lpDSBuffer->Restore();
if( hr == DSERR_BUFFERLOST )
Sleep( 10 );
}
while( hr = m_lpDSBuffer->Restore() );
}
////////////////////////////////////////////////////////////////////////////////
// 이렇게 Lock 하고 memcpy 하고 unlock 했는데요 음악이 다 꺠져서 들리네요 ㅜㅜ.
// 위에 과정까지 다 하고 나서 여기부터는 500 바이트 받아서 계속 반복 되는 구조입니다.
HRESULT hr;
VOID* pbData = NULL;
VOID* pbData2 = NULL;
DWORD dwLength;
DWORD dwLength2;
if( FAILED( hr = p_CDSound->m_lpDSBuffer->Lock( 0, p_CDSound->m_dwBufferBytes, &pbData, &dwLength, &pbData2, &dwLength2, 0L ) ) ) return hr;
// Copy the memory to it.
memcpy( pbData, &p_Data->p_Data, p_Data->nSize );
// Unlock the buffer, we don't need it anymore.
p_CDSound->m_lpDSBuffer->Unlock( pbData, p_CDSound->m_dwBufferBytes, NULL, 0 );
pbData = NULL;Forums:


버퍼 사이즈를 더 올리시는게 좋을것 같습니다.0x4000 정도로
버퍼 사이즈를 더 올리시는게 좋을것 같습니다.
0x4000 정도로 올려 보시기 바랍니다.
=================================
:: how about a cup of tea ? ::
=================================
[quote="kknd345"]서버가 해더 파일을 날리고 rewind해서
늘 같은 bitdepth, sampling rate의 wav를 보낸다고 가정했을 때, 헤더 내용은 스트리밍에 불필요합니다.
RIFF 헤더를 모두 뗀 PCM 정보만 보내고 받았을 때 PCM 스트리밍은 되시던가요? 아니면 헤더를 클라이언트가 해석 한 후 PCM만 재생시도를 한다거나 하시면요.
[code:1]if( FAILED( hr = p_CDSou
if( FAILED( hr = p_CDSound->m_lpDSBuffer->Lock( count*700, p_Data->nSize, &pbData, &dwLength, &pbData2, &dwLength2, 0L ) ) ) return hr; // Copy the memory to it. memcpy( pbData, p_Data->p_Data, dwLength ); if(dwLength2 > 0) memcpy(pbData2, p_Data->p_Data + dwLength, dwLength2); // Unlock the buffer, we don't need it anymore. p_CDSound->m_lpDSBuffer->Unlock( pbData, p_Data->nSize, pbData2, dwLength2 ); pbData = NULL; count++; if( count == 299 ){ if( start == false) hr = p_CDSound->m_lpDSBuffer->Play( 0, 0, DSBPLAY_LOOPING ); count = 0; }위처럼 해서 count를 올려서 해결했습니다.
lock이 무슨일을 하는지 잘 몰라서 안되었네요
lock의 첫번째 인자의 위치만큼 버퍼시작점에서 떨어진 포인터위치를 pbData에 넣어 주네요.
그런데 또 다른 문제가 ㅜㅜ..
버퍼에 데이터를 다 채우면 count가 0으로 돌아가서 다시 데이터를 쌓다가 재생하는 부분을 따라잡아 버려 노래가 나오지도 않았는데 그 부분을 겹쳐버리네요 ㅜㅜ..
혹시 directsound 가 세컨드 버퍼 어느지점만큼 재생하고 있는지 알수 없을까요?
1%의 가능성이면 충분하다!
최선을 다하자!
그런 질문은 윈도 관련 커뮤니티에 질문하셔야 좋지 않을까 생각합니다...
그런 질문은 윈도 관련 커뮤니티에 질문하셔야 좋지 않을까 생각합니다......
댓글 달기