static int DX5_OpenAudio(_THIS, SDL_AudioSpec *spec) { HRESULT result; WAVEFORMATEX waveformat; /* Set basic WAVE format parameters */ memset(&waveformat, 0, sizeof(waveformat)); waveformat.wFormatTag = WAVE_FORMAT_PCM; /* Determine the audio parameters from the AudioSpec */ switch ( spec->format & 0xFF ) { case 8: /* Unsigned 8 bit audio data */ spec->format = AUDIO_U8; silence = 0x80; waveformat.wBitsPerSample = 8; break; case 16: /* Signed 16 bit audio data */ spec->format = AUDIO_S16; silence = 0x00; waveformat.wBitsPerSample = 16; break; default: SDL_SetError("Unsupported audio format"); return(-1); } waveformat.nChannels = spec->channels; waveformat.nSamplesPerSec = spec->freq; waveformat.nBlockAlign = waveformat.nChannels * (waveformat.wBitsPerSample/8); waveformat.nAvgBytesPerSec = waveformat.nSamplesPerSec * waveformat.nBlockAlign; /* Update the fragment size as size in bytes */ SDL_CalculateAudioSpec(spec); /* Open the audio device */ result = DSoundCreate(NULL, &sound, NULL); if ( result != DS_OK ) { SetDSerror("DirectSoundCreate", result); return(-1); } /* Create the audio buffer to which we write */ NUM_BUFFERS = -1; #ifdef USE_PRIMARY_BUFFER if ( mainwin ) { NUM_BUFFERS = CreatePrimary(sound, mainwin, &mixbuf, &waveformat, spec->size); } #endif /* USE_PRIMARY_BUFFER */ if ( NUM_BUFFERS < 0 ) { NUM_BUFFERS = CreateSecondary(sound, mainwin, &mixbuf, &waveformat, spec->size); if ( NUM_BUFFERS < 0 ) { return(-1); } #ifdef DEBUG_SOUND fprintf(stderr, "Using secondary audio buffer\n"); #endif } #ifdef DEBUG_SOUND else fprintf(stderr, "Using primary audio buffer\n"); #endif /* The buffer will auto-start playing in DX5_WaitAudio() */ playing = 0; mixlen = spec->size; #ifdef USE_POSITION_NOTIFY /* See if we can use DirectX 6 event notification */ if ( CreateAudioEvent(this) == 0 ) { this->WaitAudio = DX6_WaitAudio_EventWait; } else { this->WaitAudio = DX5_WaitAudio_BusyWait; } #endif return(0); }
static int DSOUND_OpenDevice(_THIS, const char *devname, int iscapture) { HRESULT result; WAVEFORMATEX waveformat; int valid_format = 0; SDL_AudioFormat test_format = SDL_FirstAudioFormat(this->spec.format); /* !!! FIXME: handle devname */ /* !!! FIXME: handle iscapture */ /* Initialize all variables that we clean on shutdown */ this->hidden = (struct SDL_PrivateAudioData *) SDL_malloc((sizeof *this->hidden)); if (this->hidden == NULL) { SDL_OutOfMemory(); return 0; } SDL_memset(this->hidden, 0, (sizeof *this->hidden)); while ((!valid_format) && (test_format)) { switch (test_format) { case AUDIO_U8: case AUDIO_S16: case AUDIO_S32: this->spec.format = test_format; valid_format = 1; break; } test_format = SDL_NextAudioFormat(); } if (!valid_format) { DSOUND_CloseDevice(this); SDL_SetError("DirectSound: Unsupported audio format"); return 0; } SDL_memset(&waveformat, 0, sizeof(waveformat)); waveformat.wFormatTag = WAVE_FORMAT_PCM; waveformat.wBitsPerSample = SDL_AUDIO_BITSIZE(this->spec.format); waveformat.nChannels = this->spec.channels; waveformat.nSamplesPerSec = this->spec.freq; waveformat.nBlockAlign = waveformat.nChannels * (waveformat.wBitsPerSample / 8); waveformat.nAvgBytesPerSec = waveformat.nSamplesPerSec * waveformat.nBlockAlign; /* Update the fragment size as size in bytes */ SDL_CalculateAudioSpec(&this->spec); /* Open the audio device */ result = DSoundCreate(NULL, &this->hidden->sound, NULL); if (result != DS_OK) { DSOUND_CloseDevice(this); SetDSerror("DirectSoundCreate", result); return 0; } /* Create the audio buffer to which we write */ this->hidden->num_buffers = CreateSecondary(this, mainwin, &waveformat); if (this->hidden->num_buffers < 0) { DSOUND_CloseDevice(this); return 0; } /* The buffer will auto-start playing in DSOUND_WaitDevice() */ this->hidden->mixlen = this->spec.size; return 1; /* good to go. */ }
bool DirectSound::init() { HRESULT hr; dsoundDLL = LoadLibrary("DSOUND.DLL"); HRESULT (WINAPI *DSoundCreate)(LPCGUID,LPDIRECTSOUND *,IUnknown *); if(dsoundDLL != NULL) { DSoundCreate = (HRESULT (WINAPI *)(LPCGUID,LPDIRECTSOUND *,IUnknown *)) GetProcAddress(dsoundDLL, "DirectSoundCreate"); if(DSoundCreate == NULL) { theApp.directXMessage("DirectSoundCreate"); return false; } } else { theApp.directXMessage("DSOUND.DLL"); return false; } if((hr = DSoundCreate(NULL,&pDirectSound,NULL) != DS_OK)) { // errorMessage(myLoadString(IDS_ERROR_SOUND_CREATE), hr); systemMessage(IDS_CANNOT_CREATE_DIRECTSOUND, "Cannot create DirectSound %08x", hr); pDirectSound = NULL; dsbSecondary = NULL; return false; } if((hr=pDirectSound->SetCooperativeLevel((HWND)*theApp.m_pMainWnd, DSSCL_EXCLUSIVE)) != DS_OK) { // errorMessage(myLoadString(IDS_ERROR_SOUND_LEVEL), hr); systemMessage(IDS_CANNOT_SETCOOPERATIVELEVEL, "Cannot SetCooperativeLevel %08x", hr); return false; } DSBUFFERDESC dsbdesc; ZeroMemory(&dsbdesc,sizeof(DSBUFFERDESC)); dsbdesc.dwSize=sizeof(DSBUFFERDESC); dsbdesc.dwFlags = DSBCAPS_PRIMARYBUFFER; if((hr=pDirectSound->CreateSoundBuffer(&dsbdesc, &dsbPrimary, NULL) != DS_OK)) { // errorMessage(myLoadString(IDS_ERROR_SOUND_BUFFER),hr); systemMessage(IDS_CANNOT_CREATESOUNDBUFFER, "Cannot CreateSoundBuffer %08x", hr); return false; } // Set primary buffer format memset(&wfx, 0, sizeof(WAVEFORMATEX)); wfx.wFormatTag = WAVE_FORMAT_PCM; wfx.nChannels = 2; switch(soundQuality) { case 2: wfx.nSamplesPerSec = 22050; soundBufferLen = 736*2; soundBufferTotalLen = 7360*2; break; case 4: wfx.nSamplesPerSec = 11025; soundBufferLen = 368*2; soundBufferTotalLen = 3680*2; break; default: soundQuality = 1; wfx.nSamplesPerSec = 44100; soundBufferLen = 1470*2; soundBufferTotalLen = 14700*2; } wfx.wBitsPerSample = 16; wfx.nBlockAlign = (wfx.wBitsPerSample / 8) * wfx.nChannels; wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign; if((hr = dsbPrimary->SetFormat(&wfx)) != DS_OK) { // errorMessage(myLoadString(IDS_ERROR_SOUND_PRIMARY),hr); systemMessage(IDS_CANNOT_SETFORMAT_PRIMARY, "Cannot SetFormat for primary %08x", hr); return false; } ZeroMemory(&dsbdesc,sizeof(DSBUFFERDESC)); dsbdesc.dwSize = sizeof(DSBUFFERDESC); dsbdesc.dwFlags = DSBCAPS_GETCURRENTPOSITION2|DSBCAPS_CTRLPOSITIONNOTIFY; dsbdesc.dwBufferBytes = soundBufferTotalLen; dsbdesc.lpwfxFormat = &wfx; if((hr = pDirectSound->CreateSoundBuffer(&dsbdesc, &dsbSecondary, NULL)) != DS_OK) { dsbdesc.dwFlags = DSBCAPS_GETCURRENTPOSITION2; if((hr = pDirectSound->CreateSoundBuffer(&dsbdesc, &dsbSecondary, NULL)) != DS_OK) { systemMessage(IDS_CANNOT_CREATESOUNDBUFFER_SEC, "Cannot CreateSoundBuffer secondary %08x", hr); return false; } } dsbSecondary->SetCurrentPosition(0); if(!theApp.useOldSync) { hr = dsbSecondary->QueryInterface(IID_IDirectSoundNotify, (void **)&dsbNotify); if(!FAILED(hr)) { dsbEvent = CreateEvent(NULL, FALSE, FALSE, NULL); DSBPOSITIONNOTIFY notify[10]; for(int i = 0; i < 10; i++) { notify[i].dwOffset = i*soundBufferLen; notify[i].hEventNotify = dsbEvent; } if(FAILED(dsbNotify->SetNotificationPositions(10, notify))) { dsbNotify->Release(); dsbNotify = NULL; CloseHandle(dsbEvent); dsbEvent = NULL; } } } hr = dsbPrimary->Play(0,0,DSBPLAY_LOOPING); if(hr != DS_OK) { // errorMessage(myLoadString(IDS_ERROR_SOUND_PLAYPRIM), hr); systemMessage(IDS_CANNOT_PLAY_PRIMARY, "Cannot Play primary %08x", hr); return false; } systemSoundOn = true; return true; }