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; }
/** * @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 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; }
void COggDlg::Closeds() { // fade1=1; if(m_dsb){ m_dsb->Stop(); if(m_dsb3d != NULL){m_dsb3d->Release();m_dsb3d =NULL;} if(m_dsb != NULL){m_dsb->Release();m_dsb =NULL;} } }
//设置声音特效 HRESULT SetEcho(LPDIRECTSOUNDBUFFER8 pDSBuffer){ HRESULT hr; DWORD dwResult[1]; DSEFFECTDESC dsEffect; memset(&dsEffect, 0, sizeof(DSEFFECTDESC)); dsEffect.dwSize = sizeof(DSEFFECTDESC); dsEffect.dwFlags = 0; dsEffect.guidDSFXClass = GUID_DSFX_STANDARD_ECHO; if (SUCCEEDED(hr = pDSBuffer->SetFX(1, &dsEffect, dwResult))){ switch (dwResult[0]) { case DSFXR_LOCHARDWARE: cout << "Effect was placed in hardware" << endl; break; case DSFXR_LOCSOFTWARE: cout << "Effect was placed in software" << endl; break; case DSFXR_UNALLOCATED: cout << "Effect was not allocated in hardware or software" << endl; break; } } return hr; }
int GlobalSoundManager::getAvailableBufferIndex(SoundPriority priority) { int available_buffer = -1; // index of a buffer that could be overwritten if no // empty one is found for (int buffer = 0; buffer < NUMBER_OF_SOUND_BUFFERS; ++buffer) { if (sound_buffers_[buffer] == NULL) return buffer; if (sound_buffer_priority_[buffer] <= priority) { available_buffer = buffer; } } if (available_buffer < 0) return -1; LPDIRECTSOUNDBUFFER8 buffer = sound_buffers_[available_buffer]; buffer->Stop(); buffer->Release(); sound_buffers_[available_buffer] = NULL; sound_buffer_priority_[available_buffer] = SOUNDPRIORITY_AMBIENT; return available_buffer; }
//设置播放通知,一般用处有二: //1. 通知程序写入下一段声音数据 //2. 通知做某一个操作 HRESULT SetStopNotification(HANDLE hEvent, LPDIRECTSOUNDBUFFER8 lpDsbSecondary){ LPDIRECTSOUNDNOTIFY8 lpDsNotify; DSBPOSITIONNOTIFY PositionNotify; HRESULT hr; if (SUCCEEDED(hr = lpDsbSecondary->QueryInterface(IID_IDirectSoundNotify8, (LPVOID*)lpDsNotify) )){ PositionNotify.dwOffset = DSBPN_OFFSETSTOP; PositionNotify.hEventNotify = hEvent; hr = lpDsNotify->SetNotificationPositions(1, &PositionNotify); lpDsNotify->Release(); } return hr; }
/** * @brief Configures the replay buffer so that at appropriate positions of replay, a notification is sent. * @details * @param[in] p_secondary_buffer * @param[in] notify_array * @param[in] notify_array_count * @return */ static HRESULT set_play_notifications(LPDIRECTSOUNDBUFFER8 p_secondary_buffer, DSBPOSITIONNOTIFY * notify_array, size_t notify_array_count) { HRESULT hr; LPDIRECTSOUNDNOTIFY8 p_notify_itf = NULL; hr = p_secondary_buffer->QueryInterface(IID_IDirectSoundNotify8, (LPVOID*)&p_notify_itf); if (SUCCEEDED(hr)) { hr = p_notify_itf->SetNotificationPositions(notify_array_count, notify_array); p_notify_itf->Release(); debug_outputln("%4.4u %s : 0x%8.8x %u", __LINE__, __FILE__, hr, notify_array_count); for (size_t idx = 0; idx < notify_array_count; ++idx) { debug_outputln("%4.4u %s : 0x%8.8x %u", __LINE__, __FILE__, notify_array[idx].hEventNotify, notify_array[idx].dwOffset); } } return hr; }
BOOL COggDlg::ReleaseDXSound(void) { if(m_ds){ Closeds(); if(m_dsb3d != NULL){m_dsb3d->Release();m_dsb3d =NULL;} if(m_dsb != NULL) {m_dsb->Release();m_dsb=NULL;} if (m_dsb1 != NULL) { m_dsb1->Release(); m_dsb1 = NULL; } if(m_lpDS3DBuffer != NULL){m_lpDS3DBuffer->Release();} m_dsb =NULL; m_lpDS3DBuffer= NULL; if(m_p!=NULL){m_p->Release();m_p=NULL;} if(m_ds){ m_ds->Release(); m_ds = NULL; } } return TRUE; }
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()
/* void DoEvent() { MSG msg; for(;;){ if(PeekMessage(&msg,NULL,0,0,PM_REMOVE)) { TranslateMessage(&msg); DispatchMessage(&msg); }else return; } } */ void COggDlg::Vol(int vol) { m_dsb->SetVolume(vol); }