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%의 가능성이면 충분하다!
최선을 다하자!
그런 질문은 윈도 관련 커뮤니티에 질문하셔야 좋지 않을까 생각합니다...
그런 질문은 윈도 관련 커뮤니티에 질문하셔야 좋지 않을까 생각합니다......
댓글 달기