-Oops. Forgot to commit windows sound support file

-Added SDL sound support for linux port
This commit is contained in:
cyberwarriorx 2006-11-07 19:08:28 +00:00
parent d193971f5f
commit a531401927
9 changed files with 521 additions and 2 deletions

View File

@ -1,4 +1,4 @@
bin_PROGRAMS = desmume-cli
desmume_cli_SOURCES = main.c
desmume_cli_SOURCES = main.c ../sndsdl.c
desmume_cli_LDADD = ../libdesmume.a $(SDL_LIBS)
desmume_cli_CFLAGS = $(SDL_CFLAGS)

View File

@ -7,6 +7,7 @@
#include "../NDSSystem.h"
#include "../cflash.h"
#include "../debug.h"
#include "../sndsdl.h"
BOOL execute = FALSE;
@ -15,6 +16,7 @@ SDL_Surface * surface;
SoundInterface_struct *SNDCoreList[] = {
&SNDDummy,
&SNDFile,
&SNDSDL,
NULL
};
@ -121,6 +123,7 @@ int main(int argc, char ** argv) {
}
}
NDS_exec(1120380, FALSE);
SPU_Emulate();
Draw();
}

View File

@ -1,4 +1,4 @@
bin_PROGRAMS = desmume
desmume_SOURCES = main.c desmume.c dToolsList.c tools/ioregsView.c
desmume_SOURCES = main.c desmume.c dToolsList.c tools/ioregsView.c ../sndsdl.c
desmume_LDADD = ../libdesmume.a $(GTK_LIBS)
desmume_CFLAGS = $(GTK_CFLAGS)

View File

@ -52,6 +52,7 @@ BOOL desmume_running()
void desmume_cycle()
{
desmume_last_cycle = NDS_exec((560190 << 1) - desmume_last_cycle, FALSE);
SPU_Emulate();
}
void desmume_keypad(u16 k)

View File

@ -10,6 +10,7 @@
#include "../armcpu.h"
#include "../NDSSystem.h"
#include "../debug.h"
#include "../sndsdl.h"
#include "desmume.h"
@ -66,6 +67,7 @@ char * CONFIG_FILE;
SoundInterface_struct *SNDCoreList[] = {
&SNDDummy,
&SNDFile,
&SNDSDL,
NULL
};

198
desmume/src/sndsdl.c Normal file
View File

@ -0,0 +1,198 @@
/* Copyright 2005-2006 Theo Berkau
This file is part of DeSmuME
DeSmuME is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
Yabause is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Yabause; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <stdlib.h>
#include "SDL.h"
#include "types.h"
#include "SPU.h"
#include "sndsdl.h"
#include "debug.h"
int SNDSDLInit();
void SNDSDLDeInit();
void SNDSDLUpdateAudio(s16 *buffer, u32 num_samples);
u32 SNDSDLGetAudioSpace();
void SNDSDLMuteAudio();
void SNDSDLUnMuteAudio();
void SNDSDLSetVolume(int volume);
SoundInterface_struct SNDSDL = {
SNDCORE_SDL,
"SDL Sound Interface",
SNDSDLInit,
SNDSDLDeInit,
SNDSDLUpdateAudio,
SNDSDLGetAudioSpace,
SNDSDLMuteAudio,
SNDSDLUnMuteAudio,
SNDSDLSetVolume
};
#define NUMSOUNDBLOCKS 4
static u16 *stereodata16;
static u32 soundoffset;
static volatile u32 soundpos;
static u32 soundlen;
static u32 soundbufsize;
static SDL_AudioSpec audiofmt;
//////////////////////////////////////////////////////////////////////////////
void MixAudio(void *userdata, Uint8 *stream, int len) {
int i;
Uint8 *soundbuf=(Uint8 *)stereodata16;
for (i = 0; i < len; i++)
{
if (soundpos >= soundbufsize)
soundpos = 0;
stream[i] = soundbuf[soundpos];
soundpos++;
}
}
//////////////////////////////////////////////////////////////////////////////
int SNDSDLInit()
{
SDL_InitSubSystem(SDL_INIT_AUDIO);
// if (SDL_InitSubSystem(SDL_INIT_AUDIO) != 0);
// return -1;
audiofmt.freq = 44100;
audiofmt.format = AUDIO_S16SYS;
audiofmt.channels = 2;
audiofmt.samples = (audiofmt.freq / 60) * 2;
audiofmt.callback = MixAudio;
audiofmt.userdata = NULL;
//samples should be a power of 2 according to SDL-doc
//so normalize it to the nearest power of 2 here
u32 normSamples = 512;
while (normSamples < audiofmt.samples)
normSamples <<= 1;
audiofmt.samples = normSamples;
soundlen = audiofmt.freq / 60; // 60 for NTSC
soundbufsize = soundlen * NUMSOUNDBLOCKS * 2 * 2;
if (SDL_OpenAudio(&audiofmt, NULL) != 0)
{
return -1;
}
if ((stereodata16 = (u16 *)malloc(soundbufsize)) == NULL)
return -1;
memset(stereodata16, 0, soundbufsize);
soundpos = 0;
SDL_PauseAudio(0);
return 0;
}
//////////////////////////////////////////////////////////////////////////////
void SNDSDLDeInit()
{
SDL_CloseAudio();
if (stereodata16)
free(stereodata16);
}
//////////////////////////////////////////////////////////////////////////////
int SNDSDLReset()
{
return 0;
}
//////////////////////////////////////////////////////////////////////////////
void SNDSDLUpdateAudio(s16 *buffer, u32 num_samples)
{
u32 copy1size=0, copy2size=0;
SDL_LockAudio();
if ((soundbufsize - soundoffset) < (num_samples * sizeof(s16) * 2))
{
copy1size = (soundbufsize - soundoffset);
copy2size = (num_samples * sizeof(s16) * 2) - copy1size;
}
else
{
copy1size = (num_samples * sizeof(s16) * 2);
copy2size = 0;
}
memcpy((((u8 *)stereodata16)+soundoffset), buffer, copy1size);
// ScspConvert32uto16s((s32 *)leftchanbuffer, (s32 *)rightchanbuffer, (s16 *)(((u8 *)stereodata16)+soundoffset), copy1size / sizeof(s16) / 2);
if (copy2size)
memcpy(stereodata16, buffer+copy1size, copy2size);
// ScspConvert32uto16s((s32 *)leftchanbuffer, (s32 *)rightchanbuffer, (s16 *)stereodata16, copy2size / sizeof(s16) / 2);
soundoffset += copy1size + copy2size;
soundoffset %= soundbufsize;
SDL_UnlockAudio();
}
//////////////////////////////////////////////////////////////////////////////
u32 SNDSDLGetAudioSpace()
{
u32 freespace=0;
if (soundoffset > soundpos)
freespace = soundbufsize - soundoffset + soundpos;
else
freespace = soundpos - soundoffset;
return (freespace / sizeof(s16) / 2);
}
//////////////////////////////////////////////////////////////////////////////
void SNDSDLMuteAudio()
{
SDL_PauseAudio(1);
}
//////////////////////////////////////////////////////////////////////////////
void SNDSDLUnMuteAudio()
{
SDL_PauseAudio(0);
}
//////////////////////////////////////////////////////////////////////////////
void SNDSDLSetVolume(int volume)
{
}
//////////////////////////////////////////////////////////////////////////////

26
desmume/src/sndsdl.h Normal file
View File

@ -0,0 +1,26 @@
/* Copyright 2005-2006 Theo Berkau
This file is part of DeSmuME.
DeSmuME is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
Yabause is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Yabause; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef SNDSDL_H
#define SNDSDL_H
#define SNDCORE_SDL 2
extern SoundInterface_struct SNDSDL;
#endif

264
desmume/src/windows/snddx.c Executable file
View File

@ -0,0 +1,264 @@
/* Copyright (C) 2005-2006 Theo Berkau
This file is part of DeSmuME
DeSmuME is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
DeSmuME is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with DeSmuME; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <dsound.h>
#ifdef __MINGW32__
// I have to do this because for some reason because the dxerr8.h header is fubared
const char* __stdcall DXGetErrorString8A(HRESULT hr);
#define DXGetErrorString8 DXGetErrorString8A
const char* __stdcall DXGetErrorDescription8A(HRESULT hr);
#define DXGetErrorDescription8 DXGetErrorDescription8A
#else
#include <dxerr8.h>
#endif
#include "../SPU.h"
#include "snddx.h"
int SNDDXInit(int buffersize);
void SNDDXDeInit();
void SNDDXUpdateAudio(s16 *buffer, u32 num_samples);
u32 SNDDXGetAudioSpace();
void SNDDXMuteAudio();
void SNDDXUnMuteAudio();
void SNDDXSetVolume(int volume);
SoundInterface_struct SNDDIRECTX = {
SNDCORE_DIRECTX,
"Direct Sound Interface",
SNDDXInit,
SNDDXDeInit,
SNDDXUpdateAudio,
SNDDXGetAudioSpace,
SNDDXMuteAudio,
SNDDXUnMuteAudio,
SNDDXSetVolume
};
LPDIRECTSOUND8 lpDS8;
LPDIRECTSOUNDBUFFER lpDSB, lpDSB2;
extern HWND hwnd;
static s16 *stereodata16;
static u32 soundoffset=0;
static u32 soundbufsize;
static LONG soundvolume;
static int issoundmuted;
//////////////////////////////////////////////////////////////////////////////
int SNDDXInit(int buffersize)
{
DSBUFFERDESC dsbdesc;
WAVEFORMATEX wfx;
HRESULT ret;
char tempstr[512];
if ((ret = DirectSoundCreate8(NULL, &lpDS8, NULL)) != DS_OK)
{
sprintf(tempstr, "DirectSound8Create error: %s - %s", DXGetErrorString8(ret), DXGetErrorDescription8(ret));
MessageBox (NULL, tempstr, "Error", MB_OK | MB_ICONINFORMATION);
return -1;
}
if ((ret = IDirectSound8_SetCooperativeLevel(lpDS8, hwnd, DSSCL_PRIORITY)) != DS_OK)
{
sprintf(tempstr, "IDirectSound8_SetCooperativeLevel error: %s - %s", DXGetErrorString8(ret), DXGetErrorDescription8(ret));
MessageBox (NULL, tempstr, "Error", MB_OK | MB_ICONINFORMATION);
return -1;
}
memset(&dsbdesc, 0, sizeof(dsbdesc));
dsbdesc.dwSize = sizeof(DSBUFFERDESC);
dsbdesc.dwFlags = DSBCAPS_PRIMARYBUFFER;
dsbdesc.dwBufferBytes = 0;
dsbdesc.lpwfxFormat = NULL;
if ((ret = IDirectSound8_CreateSoundBuffer(lpDS8, &dsbdesc, &lpDSB, NULL)) != DS_OK)
{
sprintf(tempstr, "Error when creating primary sound buffer: %s - %s", DXGetErrorString8(ret), DXGetErrorDescription8(ret));
MessageBox (NULL, tempstr, "Error", MB_OK | MB_ICONINFORMATION);
return -1;
}
soundbufsize = buffersize * 2 * 2;
memset(&wfx, 0, sizeof(wfx));
wfx.wFormatTag = WAVE_FORMAT_PCM;
wfx.nChannels = 2;
wfx.nSamplesPerSec = 44100;
wfx.wBitsPerSample = 16;
wfx.nBlockAlign = (wfx.wBitsPerSample / 8) * wfx.nChannels;
wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign;
if ((ret = IDirectSoundBuffer8_SetFormat(lpDSB, &wfx)) != DS_OK)
{
sprintf(tempstr, "IDirectSoundBuffer8_SetFormat error: %s - %s", DXGetErrorString8(ret), DXGetErrorDescription8(ret));
MessageBox (NULL, tempstr, "Error", MB_OK | MB_ICONINFORMATION);
return -1;
}
memset(&dsbdesc, 0, sizeof(dsbdesc));
dsbdesc.dwSize = sizeof(DSBUFFERDESC);
dsbdesc.dwFlags = DSBCAPS_GLOBALFOCUS | DSBCAPS_STICKYFOCUS |
DSBCAPS_CTRLVOLUME | DSBCAPS_GETCURRENTPOSITION2 |
DSBCAPS_LOCHARDWARE;
dsbdesc.dwBufferBytes = soundbufsize;
dsbdesc.lpwfxFormat = &wfx;
if ((ret = IDirectSound8_CreateSoundBuffer(lpDS8, &dsbdesc, &lpDSB2, NULL)) != DS_OK)
{
if (ret == DSERR_CONTROLUNAVAIL ||
ret == DSERR_INVALIDCALL)
{
// Try using a software buffer instead
dsbdesc.dwFlags = DSBCAPS_GLOBALFOCUS | DSBCAPS_STICKYFOCUS |
DSBCAPS_CTRLVOLUME | DSBCAPS_GETCURRENTPOSITION2 |
DSBCAPS_LOCSOFTWARE;
if ((ret = IDirectSound8_CreateSoundBuffer(lpDS8, &dsbdesc, &lpDSB2, NULL)) != DS_OK)
{
sprintf(tempstr, "Error when creating secondary sound buffer: %s - %s", DXGetErrorString8(ret), DXGetErrorDescription8(ret));
MessageBox (NULL, tempstr, "Error", MB_OK | MB_ICONINFORMATION);
return -1;
}
}
else
{
sprintf(tempstr, "Error when creating secondary sound buffer: %s - %s", DXGetErrorString8(ret), DXGetErrorDescription8(ret));
MessageBox (NULL, tempstr, "Error", MB_OK | MB_ICONINFORMATION);
return -1;
}
}
IDirectSoundBuffer8_Play(lpDSB2, 0, 0, DSBPLAY_LOOPING);
if ((stereodata16 = (s16 *)malloc(soundbufsize)) == NULL)
return -1;
memset(stereodata16, 0, soundbufsize);
soundvolume = DSBVOLUME_MAX;
issoundmuted = 0;
return 0;
}
//////////////////////////////////////////////////////////////////////////////
void SNDDXDeInit()
{
DWORD status=0;
if (lpDSB2)
{
IDirectSoundBuffer8_GetStatus(lpDSB2, &status);
if(status == DSBSTATUS_PLAYING)
IDirectSoundBuffer8_Stop(lpDSB2);
IDirectSoundBuffer8_Release(lpDSB2);
lpDSB2 = NULL;
}
if (lpDSB)
{
IDirectSoundBuffer8_Release(lpDSB);
lpDSB = NULL;
}
if (lpDS8)
{
IDirectSound8_Release(lpDS8);
lpDS8 = NULL;
}
}
//////////////////////////////////////////////////////////////////////////////
void SNDDXUpdateAudio(s16 *buffer, u32 num_samples)
{
LPVOID buffer1;
LPVOID buffer2;
DWORD buffer1_size, buffer2_size;
DWORD status;
IDirectSoundBuffer8_GetStatus(lpDSB2, &status);
if (status & DSBSTATUS_BUFFERLOST)
return; // fix me
IDirectSoundBuffer8_Lock(lpDSB2, soundoffset, num_samples * sizeof(s16) * 2, &buffer1, &buffer1_size, &buffer2, &buffer2_size, 0);
memcpy(buffer1, buffer, buffer1_size);
if (buffer2)
memcpy(buffer2, buffer+buffer1_size, buffer2_size);
soundoffset += buffer1_size + buffer2_size;
soundoffset %= soundbufsize;
IDirectSoundBuffer8_Unlock(lpDSB2, buffer1, buffer1_size, buffer2, buffer2_size);
}
//////////////////////////////////////////////////////////////////////////////
u32 SNDDXGetAudioSpace()
{
DWORD playcursor, writecursor;
u32 freespace=0;
if (IDirectSoundBuffer8_GetCurrentPosition (lpDSB2, &playcursor, &writecursor) != DS_OK)
return 0;
if (soundoffset > playcursor)
freespace = soundbufsize - soundoffset + playcursor;
else
freespace = playcursor - soundoffset;
// if (freespace > 512)
return (freespace / 2 / 2);
// else
// return 0;
}
//////////////////////////////////////////////////////////////////////////////
void SNDDXMuteAudio()
{
issoundmuted = 1;
IDirectSoundBuffer8_SetVolume (lpDSB2, DSBVOLUME_MIN);
}
//////////////////////////////////////////////////////////////////////////////
void SNDDXUnMuteAudio()
{
issoundmuted = 0;
IDirectSoundBuffer8_SetVolume (lpDSB2, soundvolume);
}
//////////////////////////////////////////////////////////////////////////////
void SNDDXSetVolume(int volume)
{
soundvolume = (((LONG)volume) - 100) * 100;
if (!issoundmuted)
IDirectSoundBuffer8_SetVolume (lpDSB2, soundvolume);
}

25
desmume/src/windows/snddx.h Executable file
View File

@ -0,0 +1,25 @@
/* Copyright (C) 2006 Theo Berkau
This file is part of DeSmuME
DeSmuME is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
DeSmuME is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with DeSmuME; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef SNDDX_H
#define SNDDX_H
#define SNDCORE_DIRECTX 2
extern SoundInterface_struct SNDDIRECTX;
#endif