2018-11-15 23:31:39 +00:00
|
|
|
/*****************************************************************************\
|
|
|
|
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
|
|
|
|
This file is licensed under the Snes9x License.
|
|
|
|
For further information, consult the LICENSE file in the root directory.
|
|
|
|
\*****************************************************************************/
|
2010-09-25 15:46:12 +00:00
|
|
|
|
|
|
|
#include "IS9xSoundOutput.h"
|
|
|
|
#include "../snes9x.h"
|
|
|
|
#include "../apu/apu.h"
|
|
|
|
#include "wsnes9x.h"
|
|
|
|
#include "CXAudio2.h"
|
2019-02-12 15:52:05 +00:00
|
|
|
#include "CWaveOut.h"
|
2010-09-25 15:46:12 +00:00
|
|
|
#include "win32_sound.h"
|
2018-05-24 23:52:43 +00:00
|
|
|
#include "win32_display.h"
|
2010-09-25 15:46:12 +00:00
|
|
|
|
|
|
|
#define CLAMP(x, low, high) (((x) > (high)) ? (high) : (((x) < (low)) ? (low) : (x)))
|
|
|
|
|
|
|
|
// available sound output methods
|
|
|
|
CXAudio2 S9xXAudio2;
|
2019-02-12 15:52:05 +00:00
|
|
|
CWaveOut S9xWaveOut;
|
2010-09-25 15:46:12 +00:00
|
|
|
|
|
|
|
// Interface used to access the sound output
|
|
|
|
IS9xSoundOutput *S9xSoundOutput = &S9xXAudio2;
|
|
|
|
|
|
|
|
/* ReInitSound
|
|
|
|
reinitializes the sound core with current settings
|
|
|
|
IN:
|
|
|
|
mode - 0 disables sound output, 1 enables
|
|
|
|
-----
|
|
|
|
returns true if successful, false otherwise
|
|
|
|
*/
|
|
|
|
bool ReInitSound()
|
|
|
|
{
|
2011-02-12 15:32:53 +00:00
|
|
|
if (GUI.AVIOut)
|
|
|
|
return false;
|
2018-05-24 23:52:43 +00:00
|
|
|
if (GUI.AutomaticInputRate)
|
|
|
|
{
|
|
|
|
int rate = WinGetAutomaticInputRate();
|
|
|
|
if (rate)
|
|
|
|
Settings.SoundInputRate = rate;
|
|
|
|
else
|
2018-06-07 20:49:41 +00:00
|
|
|
{
|
2018-05-24 23:52:43 +00:00
|
|
|
GUI.AutomaticInputRate = false;
|
2019-02-19 23:54:57 +00:00
|
|
|
Settings.SoundInputRate = 31920;
|
2018-06-07 20:49:41 +00:00
|
|
|
}
|
2018-05-24 23:52:43 +00:00
|
|
|
}
|
2018-06-07 20:49:41 +00:00
|
|
|
|
|
|
|
Settings.SoundInputRate = CLAMP(Settings.SoundInputRate,31700, 32300);
|
2010-09-25 15:46:12 +00:00
|
|
|
Settings.SoundPlaybackRate = CLAMP(Settings.SoundPlaybackRate,8000, 48000);
|
|
|
|
S9xSetSoundMute(GUI.Mute);
|
|
|
|
if(S9xSoundOutput)
|
|
|
|
S9xSoundOutput->DeInitSoundOutput();
|
2011-02-12 15:32:53 +00:00
|
|
|
|
2019-02-27 17:02:22 +00:00
|
|
|
return S9xInitSound(0);
|
2010-09-25 15:46:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void CloseSoundDevice() {
|
|
|
|
S9xSoundOutput->DeInitSoundOutput();
|
|
|
|
S9xSetSamplesAvailableCallback(NULL,NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* S9xOpenSoundDevice
|
|
|
|
called by S9xInitSound - initializes the currently selected sound output and
|
|
|
|
applies the current sound settings
|
|
|
|
-----
|
|
|
|
returns true if successful, false otherwise
|
|
|
|
*/
|
|
|
|
bool8 S9xOpenSoundDevice ()
|
|
|
|
{
|
2010-10-04 15:33:42 +00:00
|
|
|
S9xSetSamplesAvailableCallback (NULL, NULL);
|
2010-09-25 15:46:12 +00:00
|
|
|
// point the interface to the correct output object
|
|
|
|
switch(GUI.SoundDriver) {
|
2019-02-12 15:52:05 +00:00
|
|
|
case WIN_WAVEOUT_DRIVER:
|
|
|
|
S9xSoundOutput = &S9xWaveOut;
|
2010-09-25 15:46:12 +00:00
|
|
|
break;
|
2010-09-25 17:35:19 +00:00
|
|
|
case WIN_XAUDIO2_SOUND_DRIVER:
|
2010-09-25 15:46:12 +00:00
|
|
|
S9xSoundOutput = &S9xXAudio2;
|
|
|
|
break;
|
2019-02-12 15:52:05 +00:00
|
|
|
default: // we default to WaveOut
|
|
|
|
GUI.SoundDriver = WIN_WAVEOUT_DRIVER;
|
|
|
|
S9xSoundOutput = &S9xWaveOut;
|
2010-09-25 15:46:12 +00:00
|
|
|
}
|
|
|
|
if(!S9xSoundOutput->InitSoundOutput())
|
|
|
|
return false;
|
2010-10-04 15:33:42 +00:00
|
|
|
|
|
|
|
if(!S9xSoundOutput->SetupSound())
|
|
|
|
return false;
|
|
|
|
|
2010-09-25 15:46:12 +00:00
|
|
|
S9xSetSamplesAvailableCallback (S9xSoundCallback, NULL);
|
2010-10-04 15:33:42 +00:00
|
|
|
return true;
|
2010-09-25 15:46:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* S9xSoundCallback
|
|
|
|
called by the sound core to process generated samples
|
|
|
|
*/
|
|
|
|
void S9xSoundCallback(void *data)
|
2017-11-24 23:10:44 +00:00
|
|
|
{
|
|
|
|
static double last_volume = 1.0;
|
|
|
|
|
|
|
|
// only try to change volume if we actually need to switch it
|
|
|
|
double current_volume = (Settings.TurboMode ? GUI.VolumeTurbo : GUI.VolumeRegular) / 100.;
|
|
|
|
if (last_volume != current_volume) {
|
|
|
|
S9xSoundOutput->SetVolume(current_volume);
|
|
|
|
last_volume = current_volume;
|
|
|
|
}
|
|
|
|
|
2010-09-25 15:46:12 +00:00
|
|
|
S9xSoundOutput->ProcessSound();
|
2010-09-25 17:35:19 +00:00
|
|
|
}
|
2018-12-15 13:19:16 +00:00
|
|
|
|
|
|
|
/* GetAvailableSoundDevices
|
|
|
|
returns a list of output devices available for the current output driver
|
|
|
|
*/
|
|
|
|
std::vector<std::wstring> GetAvailableSoundDevices()
|
|
|
|
{
|
|
|
|
return S9xSoundOutput->GetDeviceList();
|
|
|
|
}
|
|
|
|
|
|
|
|
/* FindAudioDeviceIndex
|
|
|
|
find an audio device that matches the currently configured audio device string
|
|
|
|
*/
|
|
|
|
int FindAudioDeviceIndex(TCHAR *audio_device)
|
|
|
|
{
|
|
|
|
return S9xSoundOutput->FindDeviceIndex(audio_device);
|
|
|
|
}
|