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
위처럼 해서 count를 올려서 해결했습니다.
lock이 무슨일을 하는지 잘 몰라서 안되었네요
lock의 첫번째 인자의 위치만큼 버퍼시작점에서 떨어진 포인터위치를 pbData에 넣어 주네요.
그런데 또 다른 문제가 ㅜㅜ..
버퍼에 데이터를 다 채우면 count가 0으로 돌아가서 다시 데이터를 쌓다가 재생하는 부분을 따라잡아 버려 노래가 나오지도 않았는데 그 부분을 겹쳐버리네요 ㅜㅜ..
혹시 directsound 가 세컨드 버퍼 어느지점만큼 재생하고 있는지 알수 없을까요?
1%의 가능성이면 충분하다!
최선을 다하자!
그런 질문은 윈도 관련 커뮤니티에 질문하셔야 좋지 않을까 생각합니다...
그런 질문은 윈도 관련 커뮤니티에 질문하셔야 좋지 않을까 생각합니다......
댓글 달기