mirror of
				https://github.com/Ryujinx/SDL.git
				synced 2025-11-04 13:54:49 +00:00 
			
		
		
		
	directsound: Implemented audio capture support.
This commit is contained in:
		
							parent
							
								
									21c7fe0060
								
							
						
					
					
						commit
						b78ec97496
					
				| 
						 | 
				
			
			@ -24,6 +24,7 @@
 | 
			
		|||
 | 
			
		||||
/* Allow access to a raw mixing buffer */
 | 
			
		||||
 | 
			
		||||
#include "SDL_assert.h"
 | 
			
		||||
#include "SDL_timer.h"
 | 
			
		||||
#include "SDL_loadso.h"
 | 
			
		||||
#include "SDL_audio.h"
 | 
			
		||||
| 
						 | 
				
			
			@ -36,11 +37,13 @@
 | 
			
		|||
 | 
			
		||||
/* DirectX function pointers for audio */
 | 
			
		||||
static void* DSoundDLL = NULL;
 | 
			
		||||
typedef HRESULT(WINAPI*fnDirectSoundCreate8)(LPGUID,LPDIRECTSOUND*,LPUNKNOWN);
 | 
			
		||||
typedef HRESULT(WINAPI*fnDirectSoundEnumerateW)(LPDSENUMCALLBACKW, LPVOID);
 | 
			
		||||
typedef HRESULT(WINAPI*fnDirectSoundCaptureEnumerateW)(LPDSENUMCALLBACKW,LPVOID);
 | 
			
		||||
typedef HRESULT (WINAPI *fnDirectSoundCreate8)(LPGUID,LPDIRECTSOUND*,LPUNKNOWN);
 | 
			
		||||
typedef HRESULT (WINAPI *fnDirectSoundEnumerateW)(LPDSENUMCALLBACKW, LPVOID);
 | 
			
		||||
typedef HRESULT (WINAPI *fnDirectSoundCaptureCreate8)(LPCGUID,LPDIRECTSOUNDCAPTURE8 *,LPUNKNOWN);
 | 
			
		||||
typedef HRESULT (WINAPI *fnDirectSoundCaptureEnumerateW)(LPDSENUMCALLBACKW,LPVOID);
 | 
			
		||||
static fnDirectSoundCreate8 pDirectSoundCreate8 = NULL;
 | 
			
		||||
static fnDirectSoundEnumerateW pDirectSoundEnumerateW = NULL;
 | 
			
		||||
static fnDirectSoundCaptureCreate8 pDirectSoundCaptureCreate8 = NULL;
 | 
			
		||||
static fnDirectSoundCaptureEnumerateW pDirectSoundCaptureEnumerateW = NULL;
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
| 
						 | 
				
			
			@ -48,6 +51,7 @@ DSOUND_Unload(void)
 | 
			
		|||
{
 | 
			
		||||
    pDirectSoundCreate8 = NULL;
 | 
			
		||||
    pDirectSoundEnumerateW = NULL;
 | 
			
		||||
    pDirectSoundCaptureCreate8 = NULL;
 | 
			
		||||
    pDirectSoundCaptureEnumerateW = NULL;
 | 
			
		||||
 | 
			
		||||
    if (DSoundDLL != NULL) {
 | 
			
		||||
| 
						 | 
				
			
			@ -76,6 +80,7 @@ DSOUND_Load(void)
 | 
			
		|||
        loaded = 1;  /* will reset if necessary. */
 | 
			
		||||
        DSOUNDLOAD(DirectSoundCreate8);
 | 
			
		||||
        DSOUNDLOAD(DirectSoundEnumerateW);
 | 
			
		||||
        DSOUNDLOAD(DirectSoundCaptureCreate8);
 | 
			
		||||
        DSOUNDLOAD(DirectSoundCaptureEnumerateW);
 | 
			
		||||
        #undef DSOUNDLOAD
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -197,7 +202,7 @@ DSOUND_WaitDevice(_THIS)
 | 
			
		|||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    while ((cursor / this->hidden->mixlen) == this->hidden->lastchunk) {
 | 
			
		||||
    while ((cursor / this->spec.size) == this->hidden->lastchunk) {
 | 
			
		||||
        /* FIXME: find out how much time is left and sleep that long */
 | 
			
		||||
        SDL_Delay(1);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -239,9 +244,8 @@ DSOUND_PlayDevice(_THIS)
 | 
			
		|||
    if (this->hidden->locked_buf) {
 | 
			
		||||
        IDirectSoundBuffer_Unlock(this->hidden->mixbuf,
 | 
			
		||||
                                  this->hidden->locked_buf,
 | 
			
		||||
                                  this->hidden->mixlen, NULL, 0);
 | 
			
		||||
                                  this->spec.size, NULL, 0);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static Uint8 *
 | 
			
		||||
| 
						 | 
				
			
			@ -265,7 +269,7 @@ DSOUND_GetDeviceBuf(_THIS)
 | 
			
		|||
        SetDSerror("DirectSound GetCurrentPosition", result);
 | 
			
		||||
        return (NULL);
 | 
			
		||||
    }
 | 
			
		||||
    cursor /= this->hidden->mixlen;
 | 
			
		||||
    cursor /= this->spec.size;
 | 
			
		||||
#ifdef DEBUG_SOUND
 | 
			
		||||
    /* Detect audio dropouts */
 | 
			
		||||
    {
 | 
			
		||||
| 
						 | 
				
			
			@ -281,17 +285,17 @@ DSOUND_GetDeviceBuf(_THIS)
 | 
			
		|||
#endif
 | 
			
		||||
    this->hidden->lastchunk = cursor;
 | 
			
		||||
    cursor = (cursor + 1) % this->hidden->num_buffers;
 | 
			
		||||
    cursor *= this->hidden->mixlen;
 | 
			
		||||
    cursor *= this->spec.size;
 | 
			
		||||
 | 
			
		||||
    /* Lock the audio buffer */
 | 
			
		||||
    result = IDirectSoundBuffer_Lock(this->hidden->mixbuf, cursor,
 | 
			
		||||
                                     this->hidden->mixlen,
 | 
			
		||||
                                     this->spec.size,
 | 
			
		||||
                                     (LPVOID *) & this->hidden->locked_buf,
 | 
			
		||||
                                     &rawlen, NULL, &junk, 0);
 | 
			
		||||
    if (result == DSERR_BUFFERLOST) {
 | 
			
		||||
        IDirectSoundBuffer_Restore(this->hidden->mixbuf);
 | 
			
		||||
        result = IDirectSoundBuffer_Lock(this->hidden->mixbuf, cursor,
 | 
			
		||||
                                         this->hidden->mixlen,
 | 
			
		||||
                                         this->spec.size,
 | 
			
		||||
                                         (LPVOID *) & this->
 | 
			
		||||
                                         hidden->locked_buf, &rawlen, NULL,
 | 
			
		||||
                                         &junk, 0);
 | 
			
		||||
| 
						 | 
				
			
			@ -310,7 +314,7 @@ DSOUND_WaitDone(_THIS)
 | 
			
		|||
 | 
			
		||||
    /* Wait for the playing chunk to finish */
 | 
			
		||||
    if (stream != NULL) {
 | 
			
		||||
        SDL_memset(stream, this->spec.silence, this->hidden->mixlen);
 | 
			
		||||
        SDL_memset(stream, this->spec.silence, this->spec.size);
 | 
			
		||||
        DSOUND_PlayDevice(this);
 | 
			
		||||
    }
 | 
			
		||||
    DSOUND_WaitDevice(this);
 | 
			
		||||
| 
						 | 
				
			
			@ -319,83 +323,106 @@ DSOUND_WaitDone(_THIS)
 | 
			
		|||
    IDirectSoundBuffer_Stop(this->hidden->mixbuf);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int
 | 
			
		||||
DSOUND_CaptureFromDevice(_THIS, void *buffer, int buflen)
 | 
			
		||||
{
 | 
			
		||||
    struct SDL_PrivateAudioData *h = this->hidden;
 | 
			
		||||
    DWORD junk, cursor, ptr1len, ptr2len;
 | 
			
		||||
    VOID *ptr1, *ptr2;
 | 
			
		||||
 | 
			
		||||
    SDL_assert(buflen == this->spec.size);
 | 
			
		||||
 | 
			
		||||
    while (SDL_TRUE) {
 | 
			
		||||
        if (SDL_AtomicGet(&this->shutdown)) {  /* in case the buffer froze... */
 | 
			
		||||
            SDL_memset(buffer, this->spec.silence, buflen);
 | 
			
		||||
            return buflen;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (IDirectSoundCaptureBuffer_GetCurrentPosition(h->capturebuf, &junk, &cursor) != DS_OK) {
 | 
			
		||||
            return -1;
 | 
			
		||||
        }
 | 
			
		||||
        if ((cursor / this->spec.size) == h->lastchunk) {
 | 
			
		||||
            SDL_Delay(1);  /* FIXME: find out how much time is left and sleep that long */
 | 
			
		||||
        } else {
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (IDirectSoundCaptureBuffer_Lock(h->capturebuf, h->lastchunk * this->spec.size, this->spec.size, &ptr1, &ptr1len, &ptr2, &ptr2len, 0) != DS_OK) {
 | 
			
		||||
        return -1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    SDL_assert(ptr1len == this->spec.size);
 | 
			
		||||
    SDL_assert(ptr2 == NULL);
 | 
			
		||||
    SDL_assert(ptr2len == 0);
 | 
			
		||||
 | 
			
		||||
    SDL_memcpy(buffer, ptr1, ptr1len);
 | 
			
		||||
 | 
			
		||||
    if (IDirectSoundCaptureBuffer_Unlock(h->capturebuf, ptr1, ptr1len, ptr2, ptr2len) != DS_OK) {
 | 
			
		||||
        return -1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    h->lastchunk = (h->lastchunk + 1) % h->num_buffers;
 | 
			
		||||
 | 
			
		||||
    return ptr1len;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
DSOUND_FlushCapture(_THIS)
 | 
			
		||||
{
 | 
			
		||||
    struct SDL_PrivateAudioData *h = this->hidden;
 | 
			
		||||
    DWORD junk, cursor;
 | 
			
		||||
    if (IDirectSoundCaptureBuffer_GetCurrentPosition(h->capturebuf, &junk, &cursor) == DS_OK) {
 | 
			
		||||
        h->lastchunk = cursor / this->spec.size;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
DSOUND_CloseDevice(_THIS)
 | 
			
		||||
{
 | 
			
		||||
    if (this->hidden->mixbuf != NULL) {
 | 
			
		||||
        IDirectSoundBuffer_Stop(this->hidden->mixbuf);
 | 
			
		||||
        IDirectSoundBuffer_Release(this->hidden->mixbuf);
 | 
			
		||||
    }
 | 
			
		||||
    if (this->hidden->sound != NULL) {
 | 
			
		||||
        IDirectSound_Release(this->hidden->sound);
 | 
			
		||||
    }
 | 
			
		||||
    if (this->hidden->capturebuf != NULL) {
 | 
			
		||||
        IDirectSoundCaptureBuffer_Stop(this->hidden->capturebuf);
 | 
			
		||||
        IDirectSoundCaptureBuffer_Release(this->hidden->capturebuf);
 | 
			
		||||
    }
 | 
			
		||||
    if (this->hidden->capture != NULL) {
 | 
			
		||||
        IDirectSoundCapture_Release(this->hidden->capture);
 | 
			
		||||
    }
 | 
			
		||||
    SDL_free(this->hidden);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* This function tries to create a secondary audio buffer, and returns the
 | 
			
		||||
   number of audio chunks available in the created buffer.
 | 
			
		||||
   number of audio chunks available in the created buffer. This is for
 | 
			
		||||
   playback devices, not capture.
 | 
			
		||||
*/
 | 
			
		||||
static int
 | 
			
		||||
CreateSecondary(_THIS, HWND focus)
 | 
			
		||||
CreateSecondary(_THIS, const DWORD bufsize, WAVEFORMATEX *wfmt)
 | 
			
		||||
{
 | 
			
		||||
    LPDIRECTSOUND sndObj = this->hidden->sound;
 | 
			
		||||
    LPDIRECTSOUNDBUFFER *sndbuf = &this->hidden->mixbuf;
 | 
			
		||||
    Uint32 chunksize = this->spec.size;
 | 
			
		||||
    const int numchunks = 8;
 | 
			
		||||
    HRESULT result = DS_OK;
 | 
			
		||||
    DSBUFFERDESC format;
 | 
			
		||||
    LPVOID pvAudioPtr1, pvAudioPtr2;
 | 
			
		||||
    DWORD dwAudioBytes1, dwAudioBytes2;
 | 
			
		||||
    WAVEFORMATEX wfmt;
 | 
			
		||||
 | 
			
		||||
    SDL_zero(wfmt);
 | 
			
		||||
 | 
			
		||||
    if (SDL_AUDIO_ISFLOAT(this->spec.format)) {
 | 
			
		||||
        wfmt.wFormatTag = WAVE_FORMAT_IEEE_FLOAT;
 | 
			
		||||
    } else {
 | 
			
		||||
        wfmt.wFormatTag = WAVE_FORMAT_PCM;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    wfmt.wBitsPerSample = SDL_AUDIO_BITSIZE(this->spec.format);
 | 
			
		||||
    wfmt.nChannels = this->spec.channels;
 | 
			
		||||
    wfmt.nSamplesPerSec = this->spec.freq;
 | 
			
		||||
    wfmt.nBlockAlign = wfmt.nChannels * (wfmt.wBitsPerSample / 8);
 | 
			
		||||
    wfmt.nAvgBytesPerSec = wfmt.nSamplesPerSec * wfmt.nBlockAlign;
 | 
			
		||||
 | 
			
		||||
    /* Try to set primary mixing privileges */
 | 
			
		||||
    if (focus) {
 | 
			
		||||
        result = IDirectSound_SetCooperativeLevel(sndObj,
 | 
			
		||||
                                                  focus, DSSCL_PRIORITY);
 | 
			
		||||
    } else {
 | 
			
		||||
        result = IDirectSound_SetCooperativeLevel(sndObj,
 | 
			
		||||
                                                  GetDesktopWindow(),
 | 
			
		||||
                                                  DSSCL_NORMAL);
 | 
			
		||||
    }
 | 
			
		||||
    if (result != DS_OK) {
 | 
			
		||||
        return SetDSerror("DirectSound SetCooperativeLevel", result);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* Try to create the secondary buffer */
 | 
			
		||||
    SDL_zero(format);
 | 
			
		||||
    format.dwSize = sizeof(format);
 | 
			
		||||
    format.dwFlags = DSBCAPS_GETCURRENTPOSITION2;
 | 
			
		||||
    if (!focus) {
 | 
			
		||||
    format.dwFlags |= DSBCAPS_GLOBALFOCUS;
 | 
			
		||||
    } else {
 | 
			
		||||
        format.dwFlags |= DSBCAPS_STICKYFOCUS;
 | 
			
		||||
    }
 | 
			
		||||
    format.dwBufferBytes = numchunks * chunksize;
 | 
			
		||||
    if ((format.dwBufferBytes < DSBSIZE_MIN) ||
 | 
			
		||||
        (format.dwBufferBytes > DSBSIZE_MAX)) {
 | 
			
		||||
        return SDL_SetError("Sound buffer size must be between %d and %d",
 | 
			
		||||
                            DSBSIZE_MIN / numchunks, DSBSIZE_MAX / numchunks);
 | 
			
		||||
    }
 | 
			
		||||
    format.dwReserved = 0;
 | 
			
		||||
    format.lpwfxFormat = &wfmt;
 | 
			
		||||
    format.dwBufferBytes = bufsize;
 | 
			
		||||
    format.lpwfxFormat = wfmt;
 | 
			
		||||
    result = IDirectSound_CreateSoundBuffer(sndObj, &format, sndbuf, NULL);
 | 
			
		||||
    if (result != DS_OK) {
 | 
			
		||||
        return SetDSerror("DirectSound CreateSoundBuffer", result);
 | 
			
		||||
    }
 | 
			
		||||
    IDirectSoundBuffer_SetFormat(*sndbuf, &wfmt);
 | 
			
		||||
    IDirectSoundBuffer_SetFormat(*sndbuf, wfmt);
 | 
			
		||||
 | 
			
		||||
    /* Silence the initial audio buffer */
 | 
			
		||||
    result = IDirectSoundBuffer_Lock(*sndbuf, 0, format.dwBufferBytes,
 | 
			
		||||
| 
						 | 
				
			
			@ -410,17 +437,64 @@ CreateSecondary(_THIS, HWND focus)
 | 
			
		|||
    }
 | 
			
		||||
 | 
			
		||||
    /* We're ready to go */
 | 
			
		||||
    return (numchunks);
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* This function tries to create a capture buffer, and returns the
 | 
			
		||||
   number of audio chunks available in the created buffer. This is for
 | 
			
		||||
   capture devices, not playback.
 | 
			
		||||
*/
 | 
			
		||||
static int
 | 
			
		||||
CreateCaptureBuffer(_THIS, const DWORD bufsize, WAVEFORMATEX *wfmt)
 | 
			
		||||
{
 | 
			
		||||
    LPDIRECTSOUNDCAPTURE capture = this->hidden->capture;
 | 
			
		||||
    LPDIRECTSOUNDCAPTUREBUFFER *capturebuf = &this->hidden->capturebuf;
 | 
			
		||||
    DSCBUFFERDESC format;
 | 
			
		||||
//    DWORD junk, cursor;
 | 
			
		||||
    HRESULT result;
 | 
			
		||||
 | 
			
		||||
    SDL_zero(format);
 | 
			
		||||
    format.dwSize = sizeof (format);
 | 
			
		||||
    format.dwFlags = DSCBCAPS_WAVEMAPPED;
 | 
			
		||||
    format.dwBufferBytes = bufsize;
 | 
			
		||||
    format.lpwfxFormat = wfmt;
 | 
			
		||||
 | 
			
		||||
    result = IDirectSoundCapture_CreateCaptureBuffer(capture, &format, capturebuf, NULL);
 | 
			
		||||
    if (result != DS_OK) {
 | 
			
		||||
        return SetDSerror("DirectSound CreateCaptureBuffer", result);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    result = IDirectSoundCaptureBuffer_Start(*capturebuf, DSCBSTART_LOOPING);
 | 
			
		||||
    if (result != DS_OK) {
 | 
			
		||||
        IDirectSoundCaptureBuffer_Release(*capturebuf);
 | 
			
		||||
        return SetDSerror("DirectSound Start", result);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#if 0
 | 
			
		||||
    /* presumably this starts at zero, but just in case... */
 | 
			
		||||
    result = IDirectSoundCaptureBuffer_GetCurrentPosition(*capturebuf, &junk, &cursor);
 | 
			
		||||
    if (result != DS_OK) {
 | 
			
		||||
        IDirectSoundCaptureBuffer_Stop(*capturebuf);
 | 
			
		||||
        IDirectSoundCaptureBuffer_Release(*capturebuf);
 | 
			
		||||
        return SetDSerror("DirectSound GetCurrentPosition", result);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    this->hidden->lastchunk = cursor / this->spec.size;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int
 | 
			
		||||
DSOUND_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
 | 
			
		||||
{
 | 
			
		||||
    const DWORD numchunks = 8;
 | 
			
		||||
    HRESULT result;
 | 
			
		||||
    SDL_bool valid_format = SDL_FALSE;
 | 
			
		||||
    SDL_bool tried_format = SDL_FALSE;
 | 
			
		||||
    SDL_AudioFormat test_format = SDL_FirstAudioFormat(this->spec.format);
 | 
			
		||||
    LPGUID guid = (LPGUID) handle;
 | 
			
		||||
	DWORD bufsize;
 | 
			
		||||
	
 | 
			
		||||
    /* Initialize all variables that we clean on shutdown */
 | 
			
		||||
    this->hidden = (struct SDL_PrivateAudioData *)
 | 
			
		||||
| 
						 | 
				
			
			@ -431,9 +505,22 @@ DSOUND_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
 | 
			
		|||
    SDL_zerop(this->hidden);
 | 
			
		||||
 | 
			
		||||
    /* Open the audio device */
 | 
			
		||||
    if (iscapture) {
 | 
			
		||||
        result = pDirectSoundCaptureCreate8(guid, &this->hidden->capture, NULL);
 | 
			
		||||
        if (result != DS_OK) {
 | 
			
		||||
            return SetDSerror("DirectSoundCaptureCreate8", result);
 | 
			
		||||
        }
 | 
			
		||||
    } else {
 | 
			
		||||
        result = pDirectSoundCreate8(guid, &this->hidden->sound, NULL);
 | 
			
		||||
        if (result != DS_OK) {
 | 
			
		||||
        return SetDSerror("DirectSoundCreate", result);
 | 
			
		||||
            return SetDSerror("DirectSoundCreate8", result);
 | 
			
		||||
        }
 | 
			
		||||
        result = IDirectSound_SetCooperativeLevel(this->hidden->sound,
 | 
			
		||||
                                                  GetDesktopWindow(),
 | 
			
		||||
                                                  DSSCL_NORMAL);
 | 
			
		||||
        if (result != DS_OK) {
 | 
			
		||||
            return SetDSerror("DirectSound SetCooperativeLevel", result);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    while ((!valid_format) && (test_format)) {
 | 
			
		||||
| 
						 | 
				
			
			@ -443,13 +530,39 @@ DSOUND_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
 | 
			
		|||
        case AUDIO_S32:
 | 
			
		||||
        case AUDIO_F32:
 | 
			
		||||
            tried_format = SDL_TRUE;
 | 
			
		||||
 | 
			
		||||
            this->spec.format = test_format;
 | 
			
		||||
 | 
			
		||||
            /* Update the fragment size as size in bytes */
 | 
			
		||||
            SDL_CalculateAudioSpec(&this->spec);
 | 
			
		||||
            this->hidden->num_buffers = CreateSecondary(this, NULL);
 | 
			
		||||
            if (this->hidden->num_buffers > 0) {
 | 
			
		||||
 | 
			
		||||
            bufsize = numchunks * this->spec.size;
 | 
			
		||||
            if ((bufsize < DSBSIZE_MIN) || (bufsize > DSBSIZE_MAX)) {
 | 
			
		||||
                SDL_SetError("Sound buffer size must be between %d and %d",
 | 
			
		||||
                             (DSBSIZE_MIN < numchunks) ? 1 : DSBSIZE_MIN / numchunks,
 | 
			
		||||
                             DSBSIZE_MAX / numchunks);
 | 
			
		||||
            } else {
 | 
			
		||||
                int rc;
 | 
			
		||||
				WAVEFORMATEX wfmt;
 | 
			
		||||
                SDL_zero(wfmt);
 | 
			
		||||
                if (SDL_AUDIO_ISFLOAT(this->spec.format)) {
 | 
			
		||||
                    wfmt.wFormatTag = WAVE_FORMAT_IEEE_FLOAT;
 | 
			
		||||
                } else {
 | 
			
		||||
                    wfmt.wFormatTag = WAVE_FORMAT_PCM;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                wfmt.wBitsPerSample = SDL_AUDIO_BITSIZE(this->spec.format);
 | 
			
		||||
                wfmt.nChannels = this->spec.channels;
 | 
			
		||||
                wfmt.nSamplesPerSec = this->spec.freq;
 | 
			
		||||
                wfmt.nBlockAlign = wfmt.nChannels * (wfmt.wBitsPerSample / 8);
 | 
			
		||||
                wfmt.nAvgBytesPerSec = wfmt.nSamplesPerSec * wfmt.nBlockAlign;
 | 
			
		||||
 | 
			
		||||
                rc = iscapture ? CreateCaptureBuffer(this, bufsize, &wfmt) : CreateSecondary(this, bufsize, &wfmt);
 | 
			
		||||
                if (rc == 0) {
 | 
			
		||||
                    this->hidden->num_buffers = numchunks;
 | 
			
		||||
                    valid_format = SDL_TRUE;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
        test_format = SDL_NextAudioFormat();
 | 
			
		||||
| 
						 | 
				
			
			@ -462,8 +575,7 @@ DSOUND_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
 | 
			
		|||
        return SDL_SetError("DirectSound: Unsupported audio format");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* The buffer will auto-start playing in DSOUND_WaitDevice() */
 | 
			
		||||
    this->hidden->mixlen = this->spec.size;
 | 
			
		||||
    /* Playback buffers will auto-start playing in DSOUND_WaitDevice() */
 | 
			
		||||
 | 
			
		||||
    return 0;                   /* good to go. */
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -490,11 +602,14 @@ DSOUND_Init(SDL_AudioDriverImpl * impl)
 | 
			
		|||
    impl->WaitDevice = DSOUND_WaitDevice;
 | 
			
		||||
    impl->WaitDone = DSOUND_WaitDone;
 | 
			
		||||
    impl->GetDeviceBuf = DSOUND_GetDeviceBuf;
 | 
			
		||||
    impl->CaptureFromDevice = DSOUND_CaptureFromDevice;
 | 
			
		||||
    impl->FlushCapture = DSOUND_FlushCapture;
 | 
			
		||||
    impl->CloseDevice = DSOUND_CloseDevice;
 | 
			
		||||
    impl->FreeDeviceHandle = DSOUND_FreeDeviceHandle;
 | 
			
		||||
 | 
			
		||||
    impl->Deinitialize = DSOUND_Deinitialize;
 | 
			
		||||
 | 
			
		||||
    impl->HasCaptureSupport = SDL_TRUE;
 | 
			
		||||
 | 
			
		||||
    return 1;   /* this audio target is available. */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -35,8 +35,9 @@ struct SDL_PrivateAudioData
 | 
			
		|||
{
 | 
			
		||||
    LPDIRECTSOUND sound;
 | 
			
		||||
    LPDIRECTSOUNDBUFFER mixbuf;
 | 
			
		||||
    LPDIRECTSOUNDCAPTURE capture;
 | 
			
		||||
    LPDIRECTSOUNDCAPTUREBUFFER capturebuf;
 | 
			
		||||
    int num_buffers;
 | 
			
		||||
    int mixlen;
 | 
			
		||||
    DWORD lastchunk;
 | 
			
		||||
    Uint8 *locked_buf;
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue