2006-11-07 19:08:28 +00:00
|
|
|
/* 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>
|
2006-11-16 23:14:23 +00:00
|
|
|
#include <string.h>
|
2006-11-07 19:08:28 +00:00
|
|
|
|
2008-09-08 08:06:35 +00:00
|
|
|
#include <SDL/SDL.h>
|
2006-11-07 19:08:28 +00:00
|
|
|
#include "types.h"
|
|
|
|
#include "SPU.h"
|
|
|
|
#include "sndsdl.h"
|
|
|
|
#include "debug.h"
|
|
|
|
|
2006-11-12 21:34:54 +00:00
|
|
|
int SNDSDLInit(int buffersize);
|
2006-11-07 19:08:28 +00:00
|
|
|
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
|
|
|
|
};
|
|
|
|
|
|
|
|
static u16 *stereodata16;
|
|
|
|
static u32 soundoffset;
|
|
|
|
static volatile u32 soundpos;
|
|
|
|
static u32 soundlen;
|
|
|
|
static u32 soundbufsize;
|
|
|
|
static SDL_AudioSpec audiofmt;
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
2008-10-17 09:16:13 +00:00
|
|
|
static void MixAudio(void *userdata, Uint8 *stream, int len) {
|
2006-11-07 19:08:28 +00:00
|
|
|
int i;
|
|
|
|
Uint8 *soundbuf=(Uint8 *)stereodata16;
|
|
|
|
|
|
|
|
for (i = 0; i < len; i++)
|
|
|
|
{
|
|
|
|
if (soundpos >= soundbufsize)
|
|
|
|
soundpos = 0;
|
|
|
|
|
|
|
|
stream[i] = soundbuf[soundpos];
|
|
|
|
soundpos++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
2006-11-12 21:34:54 +00:00
|
|
|
int SNDSDLInit(int buffersize)
|
2006-11-07 19:08:28 +00:00
|
|
|
{
|
2009-01-16 19:52:08 +00:00
|
|
|
if (SDL_InitSubSystem(SDL_INIT_AUDIO) != 0)
|
|
|
|
return -1;
|
2006-11-07 19:08:28 +00:00
|
|
|
|
|
|
|
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
|
2006-11-12 21:34:54 +00:00
|
|
|
soundbufsize = buffersize * sizeof(s16) * 2;
|
2006-11-07 19:08:28 +00:00
|
|
|
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
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)
|
2006-11-12 21:34:54 +00:00
|
|
|
memcpy(stereodata16, ((u8 *)buffer)+copy1size, copy2size);
|
2006-11-07 19:08:28 +00:00
|
|
|
// 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)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|