snes9xgx/source/audio.cpp

171 lines
4.1 KiB
C++
Raw Normal View History

/****************************************************************************
2010-01-27 23:20:37 +01:00
* Snes9x Nintendo Wii/Gamecube Port
*
* softdev July 2006
2010-01-27 23:20:37 +01:00
* Tantric 2008-2010
*
* audio.cpp
*
* Audio driver
* Audio is fixed to 32Khz/16bit/Stereo
***************************************************************************/
#include <gccore.h>
#include <ogcsys.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
2009-03-11 18:28:37 +01:00
#include <asndlib.h>
#include "video.h"
2010-03-22 00:43:54 +01:00
#include "snes9x/snes9x.h"
#include "snes9x/memmap.h"
#include "snes9x/cpuexec.h"
#include "snes9x/ppu.h"
#include "snes9x/apu/apu.h"
#include "snes9x/display.h"
#include "snes9x/gfx.h"
#include "snes9x/spc7110.h"
#include "snes9x/controls.h"
extern int ConfigRequested;
/*** Double buffered audio ***/
#define AUDIOBUFFER 2048
static unsigned char soundbuffer[2][AUDIOBUFFER] __attribute__ ((__aligned__ (32)));
static int whichab = 0; /*** Audio buffer flip switch ***/
#define AUDIOSTACK 16384
static lwpq_t audioqueue;
static lwp_t athread;
static uint8 astack[AUDIOSTACK];
2010-01-27 23:08:56 +01:00
static mutex_t audiomutex = LWP_MUTEX_NULL;
/****************************************************************************
* Audio Threading
***************************************************************************/
static void *
AudioThread (void *arg)
{
LWP_InitQueue (&audioqueue);
while (1)
{
if (ConfigRequested)
memset (soundbuffer[whichab], 0, AUDIOBUFFER);
else
{
2010-01-27 23:08:56 +01:00
LWP_MutexLock(audiomutex);
S9xMixSamples (soundbuffer[whichab], AUDIOBUFFER >> 1);
2010-01-27 23:08:56 +01:00
LWP_MutexUnlock(audiomutex);
}
2010-04-14 01:34:01 +02:00
DCFlushRange (soundbuffer[whichab], AUDIOBUFFER);
LWP_ThreadSleep (audioqueue);
}
return NULL;
}
/****************************************************************************
2008-08-07 07:19:17 +02:00
* MixSamples
* This continually calls S9xMixSamples On each DMA Completion
***************************************************************************/
static void
GCMixSamples ()
{
2009-03-11 18:28:37 +01:00
if (!ConfigRequested)
{
2010-04-14 01:34:01 +02:00
whichab ^= 1;
2009-03-11 18:28:37 +01:00
AUDIO_InitDMA ((u32) soundbuffer[whichab], AUDIOBUFFER);
LWP_ThreadSignal (audioqueue);
}
}
2010-01-27 23:08:56 +01:00
static void FinalizeSamplesCallback (void *data)
{
LWP_MutexLock(audiomutex);
2010-04-14 01:34:01 +02:00
S9xFinalizeSamples();
2010-01-27 23:08:56 +01:00
LWP_MutexUnlock(audiomutex);
}
/****************************************************************************
2009-03-12 08:07:52 +01:00
* InitAudio
***************************************************************************/
void
2009-03-12 08:07:52 +01:00
InitAudio ()
{
#ifdef NO_SOUND
AUDIO_Init (NULL);
2009-07-01 19:40:04 +02:00
AUDIO_SetDSPSampleRate(AI_SAMPLERATE_32KHZ);
AUDIO_RegisterDMACallback(GCMixSamples);
#else
ASND_Init();
#endif
2010-01-27 23:08:56 +01:00
LWP_MutexInit(&audiomutex, false);
2009-11-16 09:13:02 +01:00
LWP_CreateThread (&athread, AudioThread, NULL, astack, AUDIOSTACK, 70);
}
2009-03-28 20:03:35 +01:00
/****************************************************************************
* SwitchAudioMode
*
* Switches between menu sound and emulator sound
***************************************************************************/
2009-03-11 18:28:37 +01:00
void
SwitchAudioMode(int mode)
{
if(mode == 0) // emulator
{
#ifndef NO_SOUND
ASND_Pause(1);
ASND_End();
AUDIO_StopDMA();
AUDIO_RegisterDMACallback(NULL);
DSP_Halt();
2009-03-11 18:28:37 +01:00
AUDIO_SetDSPSampleRate(AI_SAMPLERATE_32KHZ);
AUDIO_RegisterDMACallback(GCMixSamples);
2010-05-21 03:36:02 +02:00
#endif
2010-04-14 01:34:01 +02:00
memset(soundbuffer[0],0,AUDIOBUFFER);
memset(soundbuffer[1],0,AUDIOBUFFER);
DCFlushRange(soundbuffer[0],AUDIOBUFFER);
DCFlushRange(soundbuffer[1],AUDIOBUFFER);
AUDIO_InitDMA((u32)soundbuffer[whichab],AUDIOBUFFER);
AUDIO_StartDMA();
2010-05-21 03:36:02 +02:00
2010-01-27 23:08:56 +01:00
S9xSetSamplesAvailableCallback(FinalizeSamplesCallback, NULL);
2009-03-11 18:28:37 +01:00
}
else // menu
{
2010-01-27 23:08:56 +01:00
S9xSetSamplesAvailableCallback(NULL, NULL);
2009-03-11 18:28:37 +01:00
#ifndef NO_SOUND
DSP_Unhalt();
2009-06-13 19:48:03 +02:00
ASND_Init();
2009-03-11 18:28:37 +01:00
ASND_Pause(0);
2009-06-13 19:48:03 +02:00
#else
2010-05-21 03:36:02 +02:00
AUDIO_StopDMA();
2009-03-11 18:28:37 +01:00
#endif
}
}
2009-03-28 20:03:35 +01:00
/****************************************************************************
* ShutdownAudio
*
* Shuts down audio subsystem. Useful to avoid unpleasant sounds if a
* crash occurs during shutdown.
***************************************************************************/
2009-03-12 08:07:52 +01:00
void ShutdownAudio()
{
AUDIO_StopDMA();
}
/****************************************************************************
* AudioStart
*
* Called to kick off the Audio Queue
***************************************************************************/
void
AudioStart ()
{
GCMixSamples ();
}