static void MME_CloseDevice(_THIS) { if (this->hidden != NULL) { MMRESULT result; if (this->hidden->mixbuf) { result = mmeFreeBuffer(this->hidden->mixbuf); if (result != MMSYSERR_NOERROR) SetMMerror("mmeFreeBuffer", result); this->hidden->mixbuf = NULL; } if (this->hidden->shm) { if (this->hidden->shm->sound) { result = waveOutClose(this->hidden->shm->sound); if (result != MMSYSERR_NOERROR) SetMMerror("waveOutClose()", result); mmeProcessCallbacks(); } result = mmeFreeMem(this->hidden->shm); if (result != MMSYSERR_NOERROR) SetMMerror("mmeFreeMem()", result); this->hidden->shm = NULL; } SDL_free(this->hidden); this->hidden = NULL; } }
static void MME_CloseAudio(_THIS) { MMRESULT result; if ( mixbuf ) { result = mmeFreeBuffer(mixbuf); if (result != MMSYSERR_NOERROR ) SetMMerror("mmeFreeBuffer", result); mixbuf = NULL; } if ( shm ) { if ( shm->sound ) { result = waveOutClose(shm->sound); if (result != MMSYSERR_NOERROR ) SetMMerror("waveOutClose()", result); mmeProcessCallbacks(); } result = mmeFreeMem(shm); if (result != MMSYSERR_NOERROR ) SetMMerror("mmeFreeMem()", result); shm = NULL; } }
static void MME_WaitDone(_THIS) { MMRESULT result; int i; if ( shm->sound ) { for (i = 0; i < NUM_BUFFERS; i++) while ( inUse[i] ) { mmeWaitForCallbacks(); mmeProcessCallbacks(); } result = waveOutReset(shm->sound); if ( result != MMSYSERR_NOERROR ) SetMMerror("waveOutReset()", result); mmeProcessCallbacks(); } }
int DIB_OpenAudio(_THIS, SDL_AudioSpec *spec) { MMRESULT result; int i; WAVEFORMATEX waveformat; /* Initialize the wavebuf structures for closing */ sound = NULL; audio_sem = NULL; for ( i = 0; i < NUM_BUFFERS; ++i ) wavebuf[i].dwUser = 0xFFFF; mixbuf = NULL; /* Set basic WAVE format parameters */ SDL_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; waveformat.wBitsPerSample = 8; break; case 16: /* Signed 16 bit audio data */ spec->format = AUDIO_S16; 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; /* Check the buffer size -- minimum of 1/4 second (word aligned) */ if ( spec->samples < (spec->freq/4) ) spec->samples = ((spec->freq/4)+3)&~3; /* Update the fragment size as size in bytes */ SDL_CalculateAudioSpec(spec); /* Open the audio device */ result = waveOutOpen(&sound, WAVE_MAPPER, &waveformat, (DWORD_PTR)FillSound, (DWORD_PTR)this, CALLBACK_FUNCTION); if ( result != MMSYSERR_NOERROR ) { SetMMerror("waveOutOpen()", result); return(-1); } #ifdef SOUND_DEBUG /* Check the sound device we retrieved */ { WAVEOUTCAPS caps; result = waveOutGetDevCaps((UINT)sound, &caps, sizeof(caps)); if ( result != MMSYSERR_NOERROR ) { SetMMerror("waveOutGetDevCaps()", result); return(-1); } printf("Audio device: %s\n", caps.szPname); } #endif /* Create the audio buffer semaphore */ #if defined(_WIN32_WCE) && (_WIN32_WCE < 300) audio_sem = CreateSemaphoreCE(NULL, NUM_BUFFERS-1, NUM_BUFFERS, NULL); #else audio_sem = CreateSemaphore(NULL, NUM_BUFFERS-1, NUM_BUFFERS, NULL); #endif if ( audio_sem == NULL ) { SDL_SetError("Couldn't create semaphore"); return(-1); } /* Create the sound buffers */ mixbuf = (Uint8 *)SDL_malloc(NUM_BUFFERS*spec->size); if ( mixbuf == NULL ) { SDL_SetError("Out of memory"); return(-1); } for ( i = 0; i < NUM_BUFFERS; ++i ) { SDL_memset(&wavebuf[i], 0, sizeof(wavebuf[i])); wavebuf[i].lpData = (LPSTR) &mixbuf[i*spec->size]; wavebuf[i].dwBufferLength = spec->size; wavebuf[i].dwFlags = WHDR_DONE; result = waveOutPrepareHeader(sound, &wavebuf[i], sizeof(wavebuf[i])); if ( result != MMSYSERR_NOERROR ) { SetMMerror("waveOutPrepareHeader()", result); return(-1); } } /* Ready to go! */ next_buffer = 0; return(0); }
static int WINMM_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) { SDL_AudioFormat test_format = SDL_FirstAudioFormat(this->spec.format); int valid_datatype = 0; MMRESULT result; WAVEFORMATEX waveformat; UINT devId = WAVE_MAPPER; /* WAVE_MAPPER == choose system's default */ UINT i; if (handle != NULL) { /* specific device requested? */ /* -1 because we increment the original value to avoid NULL. */ const size_t val = ((size_t) handle) - 1; devId = (UINT) val; } /* Initialize all variables that we clean on shutdown */ this->hidden = (struct SDL_PrivateAudioData *) SDL_malloc((sizeof *this->hidden)); if (this->hidden == NULL) { return SDL_OutOfMemory(); } SDL_memset(this->hidden, 0, (sizeof *this->hidden)); /* Initialize the wavebuf structures for closing */ for (i = 0; i < NUM_BUFFERS; ++i) this->hidden->wavebuf[i].dwUser = 0xFFFF; if (this->spec.channels > 2) this->spec.channels = 2; /* !!! FIXME: is this right? */ while ((!valid_datatype) && (test_format)) { switch (test_format) { case AUDIO_U8: case AUDIO_S16: case AUDIO_S32: case AUDIO_F32: this->spec.format = test_format; if (PrepWaveFormat(this, devId, &waveformat, iscapture)) { valid_datatype = 1; } else { test_format = SDL_NextAudioFormat(); } break; default: test_format = SDL_NextAudioFormat(); break; } } if (!valid_datatype) { WINMM_CloseDevice(this); return SDL_SetError("Unsupported audio format"); } /* Update the fragment size as size in bytes */ SDL_CalculateAudioSpec(&this->spec); /* Open the audio device */ if (iscapture) { result = waveInOpen(&this->hidden->hin, devId, &waveformat, (DWORD_PTR) CaptureSound, (DWORD_PTR) this, CALLBACK_FUNCTION); } else { result = waveOutOpen(&this->hidden->hout, devId, &waveformat, (DWORD_PTR) FillSound, (DWORD_PTR) this, CALLBACK_FUNCTION); } if (result != MMSYSERR_NOERROR) { WINMM_CloseDevice(this); return SetMMerror("waveOutOpen()", result); } #ifdef SOUND_DEBUG /* Check the sound device we retrieved */ { WAVEOUTCAPS caps; result = waveOutGetDevCaps((UINT) this->hidden->hout, &caps, sizeof(caps)); if (result != MMSYSERR_NOERROR) { WINMM_CloseDevice(this); return SetMMerror("waveOutGetDevCaps()", result); } printf("Audio device: %s\n", caps.szPname); } #endif /* Create the audio buffer semaphore */ this->hidden->audio_sem = CreateSemaphore(NULL, NUM_BUFFERS - 1, NUM_BUFFERS, NULL); if (this->hidden->audio_sem == NULL) { WINMM_CloseDevice(this); return SDL_SetError("Couldn't create semaphore"); } /* Create the sound buffers */ this->hidden->mixbuf = (Uint8 *) SDL_malloc(NUM_BUFFERS * this->spec.size); if (this->hidden->mixbuf == NULL) { WINMM_CloseDevice(this); return SDL_OutOfMemory(); } for (i = 0; i < NUM_BUFFERS; ++i) { SDL_memset(&this->hidden->wavebuf[i], 0, sizeof(this->hidden->wavebuf[i])); this->hidden->wavebuf[i].dwBufferLength = this->spec.size; this->hidden->wavebuf[i].dwFlags = WHDR_DONE; this->hidden->wavebuf[i].lpData = (LPSTR) & this->hidden->mixbuf[i * this->spec.size]; result = waveOutPrepareHeader(this->hidden->hout, &this->hidden->wavebuf[i], sizeof(this->hidden->wavebuf[i])); if (result != MMSYSERR_NOERROR) { WINMM_CloseDevice(this); return SetMMerror("waveOutPrepareHeader()", result); } } return 0; /* Ready to go! */ }
/* Function to update the state of a joystick - called as a device poll. * This function shouldn't update the joystick structure directly, * but instead should call SDL_PrivateJoystick*() to deliver events * and update joystick device state. */ void SDL_SYS_JoystickUpdate(SDL_Joystick * joystick) { MMRESULT result; int i; DWORD flags[MAX_AXES] = { JOY_RETURNX, JOY_RETURNY, JOY_RETURNZ, JOY_RETURNR, JOY_RETURNU, JOY_RETURNV }; DWORD pos[MAX_AXES]; struct _transaxis *transaxis; int value, change; JOYINFOEX joyinfo; joyinfo.dwSize = sizeof(joyinfo); joyinfo.dwFlags = JOY_RETURNALL | JOY_RETURNPOVCTS; if (!joystick->hats) { joyinfo.dwFlags &= ~(JOY_RETURNPOV | JOY_RETURNPOVCTS); } result = joyGetPosEx(joystick->hwdata->id, &joyinfo); if (result != JOYERR_NOERROR) { SetMMerror("joyGetPosEx", result); return; } /* joystick motion events */ pos[0] = joyinfo.dwXpos; pos[1] = joyinfo.dwYpos; pos[2] = joyinfo.dwZpos; pos[3] = joyinfo.dwRpos; pos[4] = joyinfo.dwUpos; pos[5] = joyinfo.dwVpos; transaxis = joystick->hwdata->transaxis; for (i = 0; i < joystick->naxes; i++) { if (joyinfo.dwFlags & flags[i]) { value = (int) (((float) pos[i] + transaxis[i].offset) * transaxis[i].scale); change = (value - joystick->axes[i]); if ((change < -JOY_AXIS_THRESHOLD) || (change > JOY_AXIS_THRESHOLD)) { SDL_PrivateJoystickAxis(joystick, (Uint8) i, (Sint16) value); } } } /* joystick button events */ if (joyinfo.dwFlags & JOY_RETURNBUTTONS) { for (i = 0; i < joystick->nbuttons; ++i) { if (joyinfo.dwButtons & JOY_BUTTON_FLAG(i)) { if (!joystick->buttons[i]) { SDL_PrivateJoystickButton(joystick, (Uint8) i, SDL_PRESSED); } } else { if (joystick->buttons[i]) { SDL_PrivateJoystickButton(joystick, (Uint8) i, SDL_RELEASED); } } } } /* joystick hat events */ if (joyinfo.dwFlags & JOY_RETURNPOV) { Uint8 pos; pos = TranslatePOV(joyinfo.dwPOV); if (pos != joystick->hats[0]) { SDL_PrivateJoystickHat(joystick, 0, pos); } } }
static int MME_OpenDevice(_THIS, const char *devname, int iscapture) { int valid_format = 0; MMRESULT result; Uint8 *mixbuf = NULL; int i; /* 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)); /* Set basic WAVE format parameters */ this->hidden->shm = mmeAllocMem(sizeof(*this->hidden->shm)); if (this->hidden->shm == NULL) { MME_CloseDevice(this); SDL_OutOfMemory(); return 0; } SDL_memset(this->hidden->shm, '\0', sizeof(*this->hidden->shm)); this->hidden->shm->sound = 0; this->hidden->shm->wFmt.wf.wFormatTag = WAVE_FORMAT_PCM; /* Determine the audio parameters from the AudioSpec */ /* Try for a closest match on audio format */ for (test_format = SDL_FirstAudioFormat(this->spec.format); !valid_format && test_format;) { valid_format = 1; switch (test_format) { case AUDIO_U8: case AUDIO_S16: case AUDIO_S32: break; default: valid_format = 0; test_format = SDL_NextAudioFormat(); } } if (!valid_format) { MME_CloseDevice(this); SDL_SetError("Unsupported audio format"); return 0; } this->spec.format = test_format; this->hidden->shm->wFmt.wBitsPerSample = SDL_AUDIO_BITSIZE(test_format); /* !!! FIXME: Can this handle more than stereo? */ this->hidden->shm->wFmt.wf.nChannels = this->spec.channels; this->hidden->shm->wFmt.wf.nSamplesPerSec = this->spec.freq; this->hidden->shm->wFmt.wf.nBlockAlign = this->hidden->shm->wFmt.wf.nChannels * this->hidden->shm->wFmt.wBitsPerSample / 8; this->hidden->shm->wFmt.wf.nAvgBytesPerSec = this->hidden->shm->wFmt.wf.nSamplesPerSec * this->hidden->shm->wFmt.wf.nBlockAlign; /* Check the buffer size -- minimum of 1/4 second (word aligned) */ if (this->spec.samples < (this->spec.freq / 4)) this->spec.samples = ((this->spec.freq / 4) + 3) & ~3; /* Update the fragment size as size in bytes */ SDL_CalculateAudioSpec(&this->spec); /* Open the audio device */ result = waveOutOpen(&(this->hidden->shm->sound), WAVE_MAPPER, &(this->hidden->shm->wFmt.wf), MME_Callback, NULL, (CALLBACK_FUNCTION | WAVE_OPEN_SHAREABLE)); if (result != MMSYSERR_NOERROR) { MME_CloseDevice(this); SetMMerror("waveOutOpen()", result); return 0; } /* Create the sound buffers */ mixbuf = (Uint8 *) mmeAllocBuffer(NUM_BUFFERS * (this->spec.size)); if (mixbuf == NULL) { MME_CloseDevice(this); SDL_OutOfMemory(); return 0; } this->hidden->mixbuf = mixbuf; for (i = 0; i < NUM_BUFFERS; i++) { this->hidden->shm->wHdr[i].lpData = &mixbuf[i * (this->spec.size)]; this->hidden->shm->wHdr[i].dwBufferLength = this->spec.size; this->hidden->shm->wHdr[i].dwFlags = 0; this->hidden->shm->wHdr[i].dwUser = i; this->hidden->shm->wHdr[i].dwLoops = 0; /* loop control counter */ this->hidden->shm->wHdr[i].lpNext = NULL; /* reserved for driver */ this->hidden->shm->wHdr[i].reserved = 0; inUse[i] = FALSE; } this->hidden->next_buffer = 0; return 1; }
static int WINMM_OpenDevice(_THIS, const char *devname, int iscapture) { SDL_AudioFormat test_format = SDL_FirstAudioFormat(this->spec.format); int valid_datatype = 0; MMRESULT result; WAVEFORMATEX waveformat; UINT_PTR devId = WAVE_MAPPER; /* WAVE_MAPPER == choose system's default */ char *utf8 = NULL; int i; if (devname != NULL) { /* specific device requested? */ if (iscapture) { const int devcount = (int) waveInGetNumDevs(); WAVEINCAPS caps; for (i = 0; (i < devcount) && (devId == WAVE_MAPPER); i++) { result = waveInGetDevCaps(i, &caps, sizeof (caps)); if (result != MMSYSERR_NOERROR) continue; else if ((utf8 = WIN_StringToUTF8(caps.szPname)) == NULL) continue; else if (SDL_strcmp(devname, utf8) == 0) devId = (UINT_PTR) i; SDL_free(utf8); } } else { const int devcount = (int) waveOutGetNumDevs(); WAVEOUTCAPS caps; for (i = 0; (i < devcount) && (devId == WAVE_MAPPER); i++) { result = waveOutGetDevCaps(i, &caps, sizeof (caps)); if (result != MMSYSERR_NOERROR) continue; else if ((utf8 = WIN_StringToUTF8(caps.szPname)) == NULL) continue; else if (SDL_strcmp(devname, utf8) == 0) devId = (UINT_PTR) i; SDL_free(utf8); } } if (devId == WAVE_MAPPER) { SDL_SetError("Requested device not found"); return 0; } } /* 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)); /* Initialize the wavebuf structures for closing */ for (i = 0; i < NUM_BUFFERS; ++i) this->hidden->wavebuf[i].dwUser = 0xFFFF; while ((!valid_datatype) && (test_format)) { valid_datatype = 1; this->spec.format = test_format; switch (test_format) { case AUDIO_U8: case AUDIO_S16: case AUDIO_S32: break; /* valid. */ default: valid_datatype = 0; test_format = SDL_NextAudioFormat(); break; } } if (!valid_datatype) { WINMM_CloseDevice(this); SDL_SetError("Unsupported audio format"); return 0; } /* Set basic WAVE format parameters */ SDL_memset(&waveformat, '\0', sizeof(waveformat)); waveformat.wFormatTag = WAVE_FORMAT_PCM; waveformat.wBitsPerSample = SDL_AUDIO_BITSIZE(this->spec.format); if (this->spec.channels > 2) this->spec.channels = 2; /* !!! FIXME: is this right? */ waveformat.nChannels = this->spec.channels; waveformat.nSamplesPerSec = this->spec.freq; waveformat.nBlockAlign = waveformat.nChannels * (waveformat.wBitsPerSample / 8); waveformat.nAvgBytesPerSec = waveformat.nSamplesPerSec * waveformat.nBlockAlign; /* Check the buffer size -- minimum of 1/4 second (word aligned) */ if (this->spec.samples < (this->spec.freq / 4)) this->spec.samples = ((this->spec.freq / 4) + 3) & ~3; /* Update the fragment size as size in bytes */ SDL_CalculateAudioSpec(&this->spec); /* Open the audio device */ if (iscapture) { result = waveInOpen(&this->hidden->hin, devId, &waveformat, (DWORD_PTR) CaptureSound, (DWORD_PTR) this, CALLBACK_FUNCTION); } else { result = waveOutOpen(&this->hidden->hout, devId, &waveformat, (DWORD_PTR) FillSound, (DWORD_PTR) this, CALLBACK_FUNCTION); } if (result != MMSYSERR_NOERROR) { WINMM_CloseDevice(this); SetMMerror("waveOutOpen()", result); return 0; } #ifdef SOUND_DEBUG /* Check the sound device we retrieved */ { WAVEOUTCAPS caps; result = waveOutGetDevCaps((UINT) this->hidden->hout, &caps, sizeof(caps)); if (result != MMSYSERR_NOERROR) { WINMM_CloseDevice(this); SetMMerror("waveOutGetDevCaps()", result); return 0; } printf("Audio device: %s\n", caps.szPname); } #endif /* Create the audio buffer semaphore */ this->hidden->audio_sem = CreateSemaphore(NULL, NUM_BUFFERS - 1, NUM_BUFFERS, NULL); if (this->hidden->audio_sem == NULL) { WINMM_CloseDevice(this); SDL_SetError("Couldn't create semaphore"); return 0; } /* Create the sound buffers */ this->hidden->mixbuf = (Uint8 *) SDL_malloc(NUM_BUFFERS * this->spec.size); if (this->hidden->mixbuf == NULL) { WINMM_CloseDevice(this); SDL_OutOfMemory(); return 0; } for (i = 0; i < NUM_BUFFERS; ++i) { SDL_memset(&this->hidden->wavebuf[i], 0, sizeof(this->hidden->wavebuf[i])); this->hidden->wavebuf[i].dwBufferLength = this->spec.size; this->hidden->wavebuf[i].dwFlags = WHDR_DONE; this->hidden->wavebuf[i].lpData = (LPSTR) & this->hidden->mixbuf[i * this->spec.size]; result = waveOutPrepareHeader(this->hidden->hout, &this->hidden->wavebuf[i], sizeof(this->hidden->wavebuf[i])); if (result != MMSYSERR_NOERROR) { WINMM_CloseDevice(this); SetMMerror("waveOutPrepareHeader()", result); return 0; } } return 1; /* Ready to go! */ }
static int MME_OpenAudio(_THIS, SDL_AudioSpec *spec) { MMRESULT result; int i; mixbuf = NULL; /* Set basic WAVE format parameters */ shm = mmeAllocMem(sizeof(*shm)); if ( shm == NULL ) { SDL_SetError("Out of memory: shm"); return(-1); } shm->sound = 0; shm->wFmt.wf.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; shm->wFmt.wBitsPerSample = 8; break; case 16: /* Signed 16 bit audio data */ spec->format = AUDIO_S16; shm->wFmt.wBitsPerSample = 16; break; default: SDL_SetError("Unsupported audio format"); return(-1); } shm->wFmt.wf.nChannels = spec->channels; shm->wFmt.wf.nSamplesPerSec = spec->freq; shm->wFmt.wf.nBlockAlign = shm->wFmt.wf.nChannels * shm->wFmt.wBitsPerSample / 8; shm->wFmt.wf.nAvgBytesPerSec = shm->wFmt.wf.nSamplesPerSec * shm->wFmt.wf.nBlockAlign; /* Check the buffer size -- minimum of 1/4 second (word aligned) */ if ( spec->samples < (spec->freq/4) ) spec->samples = ((spec->freq/4)+3)&~3; /* Update the fragment size as size in bytes */ SDL_CalculateAudioSpec(spec); /* Open the audio device */ result = waveOutOpen(&(shm->sound), WAVE_MAPPER, &(shm->wFmt.wf), MME_CALLBACK, NULL, (CALLBACK_FUNCTION|WAVE_OPEN_SHAREABLE)); if ( result != MMSYSERR_NOERROR ) { SetMMerror("waveOutOpen()", result); return(-1); } /* Create the sound buffers */ mixbuf = (Uint8 *)mmeAllocBuffer(NUM_BUFFERS * (spec->size)); if ( mixbuf == NULL ) { SDL_SetError("Out of memory: mixbuf"); return(-1); } for (i = 0; i < NUM_BUFFERS; i++) { shm->wHdr[i].lpData = &mixbuf[i * (spec->size)]; shm->wHdr[i].dwBufferLength = spec->size; shm->wHdr[i].dwFlags = 0; shm->wHdr[i].dwUser = i; shm->wHdr[i].dwLoops = 0; /* loop control counter */ shm->wHdr[i].lpNext = NULL; /* reserved for driver */ shm->wHdr[i].reserved = 0; inUse[i] = FALSE; } next_buffer = 0; return 0; }