/** * @brief Main play routine - fill the buffer to be replayed by DirectSound subsystem. * @details This routine copies the received playback data from the 'userspace' to the * DirectSound provided buffer. This buffer will be then replayed by the DirectSound subsystem if such need * arises. * @param[in] p_buffer - pointer to the secondary buffer into which data will be replayed. * @param[in] p_fifo - pointer to the FIFO queue from which data will be fetched. * @param[in] idx - index of the part of the DirectSound chunk into which copy data. * @return returns S_OK on success, any other result indicates a failure. */ static HRESULT fill_buffer(LPDIRECTSOUNDBUFFER8 p_buffer, fifo_circular_buffer * p_fifo, size_t idx) { LPVOID lpvWrite1; DWORD dwLength1; HRESULT hr; DWORD dwOffset; dwOffset = idx * 1024; hr = p_buffer->Lock(dwOffset, // Offset at which to start lock. 1024, // Size of lock; (LPVOID*)&lpvWrite1, // Gets address of first part of lock. &dwLength1, // Gets size of first part of lock. NULL, /* Second part not needed as we will never wrap around - we lock equal buffer chunks */ NULL, 0); // Flag. if (SUCCEEDED(hr)) { size_t size; size = 1024; /* Copy as many items as you can, no more than chunk size, into the buffer */ if (fifo_circular_buffer_get_items_count(p_fifo)>0) { fifo_circular_buffer_fetch_item(p_fifo, (uint8_t*)lpvWrite1, &size); } hr = p_buffer->Unlock(lpvWrite1, dwLength1, NULL, 0); } else { debug_outputln("%4.4u %s : 0x%8.8x", __FILE__, __LINE__, hr); } return hr; }
BOOL WriteWAVData( LPDIRECTSOUNDBUFFER8 lpDSB, LPBYTE lpWaveData, DWORD dwWriteBytes ) { HRESULT dsval; if (lpDSB && lpWaveData && dwWriteBytes) { LPVOID lpAudioPtr1, lpAudioPtr2; DWORD dwAudioBytes1, dwAudioBytes2; dsval = lpDSB->Lock(0, dwWriteBytes, &lpAudioPtr1, &dwAudioBytes1, &lpAudioPtr2, &dwAudioBytes2, 0); if (dsval == DS_OK) { CopyMemory(lpAudioPtr1, lpWaveData, dwAudioBytes1); if( dwAudioBytes2 != 0) CopyMemory(lpAudioPtr2, lpWaveData + dwAudioBytes1, dwAudioBytes2); lpDSB->Unlock(lpAudioPtr1, dwAudioBytes1, lpAudioPtr2, dwAudioBytes2); return TRUE; } } return FALSE; }
BOOL HowToUseStreamBuffer(LPDIRECTSOUNDBUFFER8 lpDsb, DWORD dwOffset, LPBYTE lpbSoundData, DWORD dwSoundBytes) { LPVOID lpvPtr1; DWORD dwBytes1; LPVOID lpvPtr2; DWORD dwBytes2; HRESULT hr; //获得锁定内存的首地址 hr = lpDsb->Lock(dwOffset, dwSoundBytes, &lpvPtr1, &dwBytes1, &lpvPtr2, &dwBytes2, 0); //如果缓存丢失,要重新装载并重试锁定 if (DSERR_BUFFERLOST == hr){ lpDsb->Restore(); hr = lpDsb->Lock(dwOffset, dwSoundBytes, &lpvPtr1, &dwBytes1, &lpvPtr2, &dwBytes2, 0); } if (SUCCEEDED(hr)){ CopyMemory(lpvPtr1, lpbSoundData, dwBytes1); if (NULL != lpvPtr2){ CopyMemory(lpvPtr2, lpbSoundData+dwBytes1, dwBytes2); } hr = lpDsb->Unlock(lpvPtr1, dwBytes1, lpvPtr2, dwBytes2); if (SUCCEEDED(hr)){ return TRUE; } } //Lock, Unlock, or Restore failed return FALSE; }
UINT HandleNotifications(LPVOID) { DWORD hr = DS_OK; DWORD hRet = 0; thn=FALSE; thn1=FALSE; char* pdsb1; char* pdsb2; syukai=0; // char bufwav2[OUTPUT_BUFFER_SIZE]; HANDLE ev[] = {(HANDLE)og->timer}; // ULONG PlayCursor,WriteCursor=OUTPUT_BUFFER_SIZE*4,oldw=OUTPUT_BUFFER_SIZE*4; ULONG PlayCursor,WriteCursor=0,oldw=OUTPUT_BUFFER_SIZE*2,oldw2; m_dsb->SetCurrentPosition(0); if(mode==-10){ oldw=OUTPUT_BUFFER_SIZE*2; og->timer.SetEvent(); } fade1=0; for(;;){ DWORD dwDataLen = WAVDALen/10; if(syukai==2) {thn=TRUE;AfxEndThread(0);} if(syukai==1) {syukai2=1;continue;} // int ik; // for(ik=0;ik<60;ik++){ // if(syukai) ::WaitForMultipleObjects(1, ev, FALSE, 40); // else //Sleep(1); if (sek == 1) { if (m_dsb)m_dsb->Stop(); oldw = 0; if ((mode >= 10 && mode <= 20) || mode < -10) { playwavadpcm(bufwav3, oldw, OUTPUT_BUFFER_SIZE / 12 * wavch * 2, 0);//データ獲得 } else if (mode == -10) { playwavmp3(bufwav3, oldw, OUTPUT_BUFFER_SIZE / 12 * wavch * 2, 0);//データ獲得 } else if (mode == -3) { playwavkpi(bufwav3, oldw, OUTPUT_BUFFER_SIZE / 12 * wavch * 2, 0);//データ獲得 } else if (mode == -8) { playwavflac(bufwav3, oldw, OUTPUT_BUFFER_SIZE / 12 * wavch * 2, 0);//データ獲得 } else if (mode == -9) { playwavm4a(bufwav3, oldw, OUTPUT_BUFFER_SIZE / 12 * wavch * 2, 0);//データ獲得 } else { playwavds2(bufwav3, oldw, OUTPUT_BUFFER_SIZE / 12 * wavch * 2, 0);//データ獲得 } oldw = OUTPUT_BUFFER_SIZE / 12 * wavch * 2; WriteCursor = OUTPUT_BUFFER_SIZE / 12 * wavch * 2; if(m_dsb)m_dsb->SetCurrentPosition(0); if(m_dsb)m_dsb->Play(0,0,DSBPLAY_LOOPING); sek=FALSE; //break; } if(thn1) {thn=TRUE;AfxEndThread(0);} // } if(ps==1) continue; if(m_dsb)m_dsb->GetCurrentPosition(&PlayCursor, &WriteCursor);//再生位置取得 int len1=0,len2=0,len3,len4; // oldw = ((oldw / (wavch * 2)) * (wavch * 2)); len1=(int)WriteCursor-(int)oldw;//書き込み範囲取得10 len2=0; if (len1 == 0 && len2 == 0) continue; if(len1<0){ len1=OUTPUT_BUFFER_SIZE*OUTPUT_BUFFER_NUM-oldw; len2= WriteCursor;} if(len2<0) len2=0; //len1 = (len1 / (wavsam / 8)) * (wavsam / 8); //len2 = (len2 / (wavsam / 8)) * (wavsam / 8); len4=len1+len2; if((mode>=10 && mode<=20) || mode<-10) playwavadpcm(bufwav3,oldw,len1,len2);//データ獲得 else if(mode==-10) len4=playwavmp3(bufwav3,oldw,len1,len2);//データ獲得 else if(mode==-3) len4=playwavkpi(bufwav3,oldw,len1,len2);//データ獲得 else if (mode == -8) playwavflac(bufwav3, oldw, len1, len2);//データ獲得 else if (mode == -9) playwavm4a(bufwav3, oldw, len1, len2);//データ獲得 else playwavds2(bufwav3,oldw,len1,len2);//データ獲得 if(m_dsb){ m_dsb->Lock(oldw,len4,(LPVOID *)&pdsb1,(DWORD*)&len3,(LPVOID *)&pdsb2,(DWORD*)&len4,0); thn=FALSE; Sleep(20); thn=FALSE; memcpy(pdsb1,bufwav3+oldw,len3); if(len4!=0)memcpy(pdsb2,bufwav3,len4); if(m_dsb)m_dsb->Unlock(pdsb1,len3,pdsb2,len4); oldw2=oldw+len3; if(len4!=0)oldw2=len4; oldw=WriteCursor; // oldw+=(len3+len4); // oldw%=OUTPUT_BUFFER_SIZE*OUTPUT_BUFFER_NUM; } if(fade1){ // if(m_dsb){ // m_dsb->Lock(0,OUTPUT_BUFFER_SIZE*OUTPUT_BUFFER_NUM,(LPVOID *)&pdsb1,(DWORD*)&len3,(LPVOID *)&pdsb2,(DWORD*)&len4,0); // ZeroMemory(pdsb1,len3); // if(len4!=0)ZeroMemory(pdsb2,len4); // m_dsb->Unlock(pdsb1,len3,pdsb2,len4); // } // Sleep(750); oldw=oldw2-(wavbit); if(((int)oldw)<=0)oldw=wavbit; int flgn=0; playf = 1; thn = FALSE; if(m_dsb && thn==FALSE){ m_dsb->GetCurrentPosition(&PlayCursor, &WriteCursor); if(oldw<=PlayCursor) flgn=1; // DWORD time=timeGetTime()+3000; for(;;){ // if(time<timeGetTime()) break; DoEvent(); if(m_dsb)m_dsb->GetCurrentPosition(&PlayCursor, &WriteCursor); if(oldw>PlayCursor){flgn=0; continue;} if(oldw<=PlayCursor && flgn==0) break; } } // m_dsb->SetVolume(DSBVOLUME_MIN); // m_dsb->Stop(); og->OnPause(); playf=0; thn=TRUE; AfxEndThread(0); // for(int y=0;y<11;y++){ // CloseHandle(hNotifyEvent[y]);hNotifyEvent[y] = (HANDLE)NULL; // } return 0; } } } //handlenotifications()