?? dsdrv2.c
字號:
LPDIRECTSOUNDBUFFER lpSoundBuffer; DSBUFFERDESC dsbd; DSBCAPS dsbc; WAVEFORMATEX wfx; if (lpWave != NULL) { lpWave->dwHandle = 0; /* setup waveform format */ wfx.wFormatTag = WAVE_FORMAT_PCM; wfx.nChannels = 1; wfx.wBitsPerSample = lpWave->wFormat & AUDIO_FORMAT_16BITS ? 16 : 8; wfx.nSamplesPerSec = lpWave->nSampleRate; wfx.nAvgBytesPerSec = lpWave->nSampleRate; wfx.nBlockAlign = 1; wfx.cbSize = 0; if (lpWave->wFormat & AUDIO_FORMAT_16BITS) { wfx.nAvgBytesPerSec <<= 1; wfx.nBlockAlign <<= 1; } /* setup sound buffer description */ dsbd.dwSize = sizeof(dsbd); dsbd.dwFlags = DSBCAPS_CTRLPAN | DSBCAPS_CTRLVOLUME | DSBCAPS_CTRLFREQUENCY | DSBCAPS_STICKYFOCUS | DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_LOCSOFTWARE; dsbd.dwBufferBytes = lpWave->dwLength; dsbd.dwReserved = 0; dsbd.lpwfxFormat = &wfx; /* create sound buffer object */ if (DS.lpDirectSound->lpVtbl->CreateSoundBuffer(DS.lpDirectSound, &dsbd, &lpSoundBuffer, NULL) != DS_OK) { MSGBOX("Can't create DirectSoundBuffer object"); return AUDIO_ERROR_NOMEMORY; } lpWave->dwHandle = (DWORD) lpSoundBuffer; return AUDIO_ERROR_NONE; } return AUDIO_ERROR_INVALPARAM;}static UINT AIAPI DestroyAudioData(LPAUDIOWAVE lpWave){ LPDIRECTSOUNDBUFFER lpSoundBuffer; if (lpWave != NULL && lpWave->dwHandle != 0) { lpSoundBuffer = (LPDIRECTSOUNDBUFFER) lpWave->dwHandle; lpSoundBuffer->lpVtbl->Stop(lpSoundBuffer); lpSoundBuffer->lpVtbl->Release(lpSoundBuffer); lpWave->dwHandle = 0; return AUDIO_ERROR_NONE; } return AUDIO_ERROR_INVALPARAM;}static UINT AIAPI WriteAudioData(LPAUDIOWAVE lpWave, DWORD dwOffset, UINT nCount){ LPDIRECTSOUNDBUFFER lpSoundBuffer; LPVOID lpPtr1, lpPtr2; DWORD dwBytes1, dwBytes2; UINT i; if (lpWave != NULL && lpWave->dwHandle != 0 && lpWave->lpData != NULL) { if (dwOffset + nCount <= lpWave->dwLength) { lpSoundBuffer = (LPDIRECTSOUNDBUFFER) lpWave->dwHandle; /* lock sound buffer in memory */ if (lpSoundBuffer->lpVtbl->Lock(lpSoundBuffer, dwOffset, nCount, &lpPtr1, &dwBytes1, &lpPtr2, &dwBytes2, 0) == DS_OK) { /* copy samples to the sound buffer (convert to unsigned) */ if (lpWave->wFormat & AUDIO_FORMAT_16BITS) { memcpy(lpPtr1, lpWave->lpData + dwOffset, dwBytes1); } else { for (i = 0; i < dwBytes1; i++) ((LPBYTE)lpPtr1)[i] = lpWave->lpData[dwOffset++] ^ 0x80; } /* unlock the sound buffer from memory */ lpSoundBuffer->lpVtbl->Unlock(lpSoundBuffer, lpPtr1, dwBytes1, lpPtr2, dwBytes2); return AUDIO_ERROR_NONE; } else { MSGBOX("Can't lock DirectSoundBuffer memory"); lpSoundBuffer->lpVtbl->Restore(lpSoundBuffer); } } return AUDIO_ERROR_INVALPARAM; } return AUDIO_ERROR_INVALHANDLE;}static UINT AIAPI PrimeVoice(UINT nVoice, LPAUDIOWAVE lpWave){ LPDIRECTSOUNDBUFFER lpSoundBuffer; if (nVoice < AUDIO_MAX_VOICES && lpWave != NULL) { lpSoundBuffer = (LPDIRECTSOUNDBUFFER) lpWave->dwHandle; /* release the sound buffer for this voice */ if (DS.aSoundBuffer[nVoice] != NULL) { DS.aSoundBuffer[nVoice]->lpVtbl->Stop(DS.aSoundBuffer[nVoice]); DS.aSoundBuffer[nVoice]->lpVtbl->Release(DS.aSoundBuffer[nVoice]); DS.aSoundBuffer[nVoice] = NULL; } /* create a duplicate sound buffer */ if (DS.lpDirectSound->lpVtbl->DuplicateSoundBuffer(DS.lpDirectSound, lpSoundBuffer, &DS.aSoundBuffer[nVoice]) != DS_OK) { MSGBOX("Can't duplicate DirectSoundBuffer object"); return AUDIO_ERROR_NOMEMORY; } /* setup frequency, volume and panning */ DS.aSoundBuffer[nVoice]->lpVtbl->SetCurrentPosition(DS.aSoundBuffer[nVoice], 0); DS.aSoundBuffer[nVoice]->lpVtbl->SetFrequency(DS.aSoundBuffer[nVoice], DS.aFrequencyTable[nVoice]); DS.aSoundBuffer[nVoice]->lpVtbl->SetVolume(DS.aSoundBuffer[nVoice], DS.aLogVolumeTable[DS.aVolumeTable[nVoice]]); DS.aSoundBuffer[nVoice]->lpVtbl->SetPan(DS.aSoundBuffer[nVoice], DS.aLogPanningTable[DS.aPanningTable[nVoice]]); /* save format of the sound buffer */ DS.aFormatTable[nVoice] = lpWave->wFormat; return AUDIO_ERROR_NONE; } return AUDIO_ERROR_INVALHANDLE;}static UINT AIAPI StartVoice(UINT nVoice){ DWORD dwFlags; if (nVoice < AUDIO_MAX_VOICES) { // FIXME: handle looping samples! if (DS.aSoundBuffer[nVoice] != NULL) { dwFlags = (DS.aFormatTable[nVoice] & AUDIO_FORMAT_LOOP ? DSBPLAY_LOOPING : 0); if (DS.aSoundBuffer[nVoice]->lpVtbl->Play(DS.aSoundBuffer[nVoice], 0, 0, dwFlags) != DS_OK) { MSGBOX("Can't play DirectSoundBuffer object"); return AUDIO_ERROR_INVALHANDLE; } } return AUDIO_ERROR_NONE; } return AUDIO_ERROR_INVALHANDLE;}static UINT AIAPI StopVoice(UINT nVoice){ if (nVoice < AUDIO_MAX_VOICES) { if (DS.aSoundBuffer[nVoice] != NULL) { if (DS.aSoundBuffer[nVoice]->lpVtbl->Stop(DS.aSoundBuffer[nVoice]) != DS_OK) { MSGBOX("Can't stop DirectSoundBuffer object"); return AUDIO_ERROR_INVALHANDLE; } } return AUDIO_ERROR_NONE; } return AUDIO_ERROR_INVALHANDLE;}static UINT AIAPI SetVoicePosition(UINT nVoice, LONG dwPosition){ if (nVoice < AUDIO_MAX_VOICES) { if (dwPosition >= AUDIO_MIN_POSITION && dwPosition <= AUDIO_MAX_POSITION) { // FIXME: adjust position for 16-bit samples if (DS.aSoundBuffer[nVoice] != NULL) { DS.aSoundBuffer[nVoice]->lpVtbl->SetCurrentPosition(DS.aSoundBuffer[nVoice], dwPosition); } return AUDIO_ERROR_NONE; } return AUDIO_ERROR_INVALPARAM; } return AUDIO_ERROR_INVALHANDLE;}static UINT AIAPI SetVoiceFrequency(UINT nVoice, LONG dwFrequency){ if (nVoice < AUDIO_MAX_VOICES) { if (dwFrequency >= AUDIO_MIN_FREQUENCY && dwFrequency <= AUDIO_MAX_FREQUENCY) { DS.aFrequencyTable[nVoice] = dwFrequency; if (DS.aSoundBuffer[nVoice] != NULL) { if (DS.aSoundBuffer[nVoice]->lpVtbl->SetFrequency(DS.aSoundBuffer[nVoice], dwFrequency) != DS_OK) MSGBOX("Can't change DirectSoundBuffer frequency"); } return AUDIO_ERROR_NONE; } return AUDIO_ERROR_INVALPARAM; } return AUDIO_ERROR_INVALHANDLE;}static UINT AIAPI SetVoiceVolume(UINT nVoice, UINT nVolume){ if (nVoice < AUDIO_MAX_VOICES) { if (nVolume < AUDIO_MAX_VOLUME) { DS.aVolumeTable[nVoice] = nVolume; if (DS.aSoundBuffer[nVoice] != NULL) { if (DS.aSoundBuffer[nVoice]->lpVtbl->SetVolume(DS.aSoundBuffer[nVoice], DS.aLogVolumeTable[nVolume]) != DS_OK) MSGBOX("Can't change DirectSoundBuffer volume"); } return AUDIO_ERROR_NONE; } return AUDIO_ERROR_INVALPARAM; } return AUDIO_ERROR_INVALHANDLE;}static UINT AIAPI SetVoicePanning(UINT nVoice, UINT nPanning){ if (nVoice < AUDIO_MAX_VOICES) { if (nPanning < AUDIO_MAX_PANNING) { DS.aPanningTable[nVoice] = nPanning; if (DS.aSoundBuffer[nVoice] != NULL) { if (DS.aSoundBuffer[nVoice]->lpVtbl->SetPan(DS.aSoundBuffer[nVoice], DS.aLogPanningTable[nPanning]) != DS_OK) MSGBOX("Can't change DirectSoundBuffer panning"); } return AUDIO_ERROR_NONE; } return AUDIO_ERROR_INVALPARAM; } return AUDIO_ERROR_INVALHANDLE;}static UINT AIAPI GetVoicePosition(UINT nVoice, LPLONG lpdwPosition){ DWORD dwWritePosition; if (nVoice < AUDIO_MAX_VOICES) { if (lpdwPosition != NULL) { *lpdwPosition = 0L; if (DS.aSoundBuffer[nVoice] != NULL) { if (DS.aSoundBuffer[nVoice]->lpVtbl->GetCurrentPosition( DS.aSoundBuffer[nVoice], lpdwPosition, &dwWritePosition) != DS_OK) *lpdwPosition = 0L; } return AUDIO_ERROR_NONE; } return AUDIO_ERROR_INVALPARAM; } return AUDIO_ERROR_INVALHANDLE;}static UINT AIAPI GetVoiceFrequency(UINT nVoice, LPLONG lpdwFrequency){ if (nVoice < AUDIO_MAX_VOICES) { if (lpdwFrequency != NULL) { *lpdwFrequency = DS.aFrequencyTable[nVoice]; return AUDIO_ERROR_NONE; } return AUDIO_ERROR_INVALPARAM; } return AUDIO_ERROR_INVALHANDLE;}static UINT AIAPI GetVoiceVolume(UINT nVoice, LPUINT lpnVolume){ if (nVoice < AUDIO_MAX_VOICES) { if (lpnVolume != NULL) { *lpnVolume = DS.aVolumeTable[nVoice]; return AUDIO_ERROR_NONE; } return AUDIO_ERROR_INVALPARAM; } return AUDIO_ERROR_INVALHANDLE;}static UINT AIAPI GetVoicePanning(UINT nVoice, LPUINT lpnPanning){ if (nVoice < AUDIO_MAX_VOICES) { if (lpnPanning != NULL) { *lpnPanning = DS.aPanningTable[nVoice]; return AUDIO_ERROR_NONE; } return AUDIO_ERROR_INVALPARAM; } return AUDIO_ERROR_INVALHANDLE;}static UINT AIAPI GetVoiceStatus(UINT nVoice, LPBOOL lpnStatus){ if (nVoice < AUDIO_MAX_VOICES) { if (lpnStatus != NULL) { *lpnStatus = 1; if (DS.aSoundBuffer[nVoice] != NULL) { if (DS.aSoundBuffer[nVoice]->lpVtbl->GetStatus(DS.aSoundBuffer[nVoice], lpnStatus) != DS_OK) MSGBOX("Can't getDirectSoundBuffer status");; *lpnStatus = (*lpnStatus & DSBSTATUS_PLAYING ? 0 : 1); } return AUDIO_ERROR_NONE; } return AUDIO_ERROR_INVALPARAM; } return AUDIO_ERROR_INVALHANDLE;}/* * DirectSound audio driver public interface */static AUDIOWAVEDRIVER DirectSoundWaveDriver ={ GetAudioCaps, PingAudio, OpenAudio, CloseAudio, UpdateAudio, SetAudioCallback};static AUDIOSYNTHDRIVER DirectSoundSynthDriver ={ GetAudioCaps, PingAudio, OpenAudio, CloseAudio, UpdateAudioSynth, OpenVoices, CloseVoices, SetAudioTimerProc, SetAudioTimerRate, SetAudioMixerValue, GetAudioDataAvail, CreateAudioData, DestroyAudioData, WriteAudioData, PrimeVoice, StartVoice, StopVoice, SetVoicePosition, SetVoiceFrequency, SetVoiceVolume, SetVoicePanning, GetVoicePosition, GetVoiceFrequency, GetVoiceVolume, GetVoicePanning, GetVoiceStatus};AUDIODRIVER DirectSoundAccelDriver ={ &DirectSoundWaveDriver, &DirectSoundSynthDriver};
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -