vbagx/source/audio.cpp

227 lines
4.8 KiB
C++
Raw Permalink Normal View History

2008-09-14 22:40:26 +02:00
/****************************************************************************
2008-09-17 04:27:55 +02:00
* Visual Boy Advance GX
*
2023-01-30 22:08:08 +01:00
* Tantric 2008-2023
2008-09-17 04:27:55 +02:00
*
* audio.cpp
*
* Head and tail audio mixer
***************************************************************************/
2008-09-14 22:40:26 +02:00
#include <gccore.h>
2009-04-08 09:08:12 +02:00
#include <ogcsys.h>
2008-09-14 22:40:26 +02:00
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
2009-04-08 09:08:12 +02:00
#include <asndlib.h>
2008-09-14 22:40:26 +02:00
#include "audio.h"
extern int ConfigRequested;
2008-09-14 22:40:26 +02:00
/** Locals **/
static int head = 0;
static int tail = 0;
static int gameType = 0;
2008-09-14 22:40:26 +02:00
#define MIXBUFFSIZE 0x10000
static u8 mixerdata[MIXBUFFSIZE];
#define MIXERMASK ((MIXBUFFSIZE >> 2) - 1)
#define SWAP(x) ((x>>16)|(x<<16)) // for reversing stereo channels
2008-09-14 22:40:26 +02:00
2008-10-19 21:10:55 +02:00
static u8 soundbuffer[2][3840] ATTRIBUTE_ALIGN(32);
static int whichab = 0;
static int IsPlaying = 0;
2008-10-19 21:10:55 +02:00
/****************************************************************************
* MIXER_GetSamples
***************************************************************************/
static int MIXER_GetSamples(u8 *dstbuffer, int maxlen)
2008-10-19 21:10:55 +02:00
{
u32 *src = (u32 *)mixerdata;
u32 *dst = (u32 *)dstbuffer;
u32 intlen = maxlen >> 2;
memset(dstbuffer, 0, maxlen);
while( ( head != tail ) && intlen )
{
*dst++ = src[tail++];
tail &= MIXERMASK;
intlen--;
}
return 3200;
}
/****************************************************************************
* AudioPlayer
2008-10-19 21:10:55 +02:00
***************************************************************************/
static void AudioPlayer()
{
if (!ConfigRequested)
2008-10-19 21:10:55 +02:00
{
2010-04-14 01:34:09 +02:00
whichab ^= 1;
2008-10-19 21:10:55 +02:00
int len = MIXER_GetSamples(soundbuffer[whichab], 3200);
DCFlushRange(soundbuffer[whichab],len);
AUDIO_InitDMA((u32)soundbuffer[whichab],len);
IsPlaying = 1;
2008-10-19 21:10:55 +02:00
}
else
IsPlaying = 0;
}
/****************************************************************************
* StopAudio
***************************************************************************/
void StopAudio()
{
AUDIO_StopDMA();
IsPlaying = 0;
}
/****************************************************************************
* SetAudioRate
***************************************************************************/
void SetAudioRate(int type)
{
gameType = type;
2008-10-19 21:10:55 +02:00
}
2009-04-08 09:08:12 +02:00
/****************************************************************************
* SwitchAudioMode
*
* Switches between menu sound and emulator sound
***************************************************************************/
void
SwitchAudioMode(int mode)
{
if(mode == 0) // emulator
{
#ifndef NO_SOUND
ASND_Pause(1);
ASND_End();
AUDIO_StopDMA();
AUDIO_RegisterDMACallback(NULL);
DSP_Halt();
2009-04-08 09:08:12 +02:00
AUDIO_RegisterDMACallback(AudioPlayer);
2010-05-21 03:35:54 +02:00
#endif
2010-04-14 01:34:09 +02:00
memset(soundbuffer[0],0,3840);
memset(soundbuffer[1],0,3840);
DCFlushRange(soundbuffer[0],3840);
DCFlushRange(soundbuffer[1],3840);
AUDIO_InitDMA((u32)soundbuffer[whichab],3200);
AUDIO_StartDMA();
2009-04-08 09:08:12 +02:00
}
else // menu
{
IsPlaying = 0;
2009-04-08 09:08:12 +02:00
#ifndef NO_SOUND
DSP_Unhalt();
2009-06-13 19:50:07 +02:00
ASND_Init();
2009-04-08 09:08:12 +02:00
ASND_Pause(0);
2009-06-13 19:50:07 +02:00
#else
AUDIO_StopDMA();
2009-04-08 09:08:12 +02:00
#endif
}
}
2008-09-14 22:40:26 +02:00
/****************************************************************************
* InitialiseSound
***************************************************************************/
void InitialiseSound()
{
#ifdef NO_SOUND
AUDIO_Init (NULL);
2010-05-28 05:13:13 +02:00
AUDIO_SetDSPSampleRate(AI_SAMPLERATE_48KHZ);
2009-07-01 19:40:11 +02:00
AUDIO_RegisterDMACallback(AudioPlayer);
#else
ASND_Init();
#endif
2009-04-08 09:08:12 +02:00
}
/****************************************************************************
* ShutdownAudio
*
* Shuts down audio subsystem. Useful to avoid unpleasant sounds if a
* crash occurs during shutdown.
***************************************************************************/
void ShutdownAudio()
{
AUDIO_StopDMA();
}
/****************************************************************************
* SoundDriver
***************************************************************************/
SoundWii::SoundWii()
{
memset(soundbuffer, 0, 3840*2);
memset(mixerdata, 0, MIXBUFFSIZE);
}
/****************************************************************************
* SoundWii::write
2008-09-14 22:40:26 +02:00
*
* Upsample from 11025 to 48000
* 11025 == 15052
* 22050 == 30106
* 44100 == 60211
*
* Audio officianados should look away now !
****************************************************************************/
void SoundWii::write(u16 * finalWave, int length)
2008-09-14 22:40:26 +02:00
{
u32 *src = (u32 *)finalWave;
u32 *dst = (u32 *)mixerdata;
u32 intlen = (3200 >> 2);
u32 fixofs = 0;
u32 fixinc = 60211; // length = 2940 - GB
2008-09-14 22:40:26 +02:00
if (gameType == 2) // length = 1468 - GBA
fixinc = 30065;
2008-09-14 22:40:26 +02:00
do
{
// Do simple linear interpolate, and swap channels from L-R to R-L
dst[head++] = SWAP(src[fixofs >> 16]);
head &= MIXERMASK;
fixofs += fixinc;
}
while( --intlen );
// Restart Sound Processing if stopped
if (IsPlaying == 0)
{
ConfigRequested = 0;
AudioPlayer();
}
2008-09-14 22:40:26 +02:00
}
bool SoundWii::init(long sampleRate)
{
return true;
}
SoundWii::~SoundWii()
2008-10-18 22:40:48 +02:00
{
}
void SoundWii::pause()
{
}
void SoundWii::resume()
{
}
void SoundWii::reset()
{
}