mirror of
https://github.com/SourMesen/Mesen2.git
synced 2025-04-02 10:21:44 -04:00
96 lines
2.3 KiB
C++
96 lines
2.3 KiB
C++
#include "pch.h"
|
|
#include "SMS/SmsFmAudio.h"
|
|
#include "SMS/SmsConsole.h"
|
|
#include "Shared/Emulator.h"
|
|
#include "Shared/EmuSettings.h"
|
|
#include "Shared/Audio/SoundMixer.h"
|
|
#include "Shared/Utilities/emu2413.h"
|
|
#include "Shared/Utilities/Emu2413Serializer.h"
|
|
#include "Utilities/Serializer.h"
|
|
|
|
SmsFmAudio::SmsFmAudio(Emulator* emu, SmsConsole* console)
|
|
{
|
|
_emu = emu;
|
|
_console = console;
|
|
|
|
_opll = OPLL_new(_console->GetMasterClockRate(), _console->GetMasterClockRate() / 72);
|
|
OPLL_setChipType(_opll, 0);
|
|
OPLL_resetPatch(_opll, 0);
|
|
OPLL_reset(_opll);
|
|
_emu->GetSoundMixer()->RegisterAudioProvider(this);
|
|
}
|
|
|
|
SmsFmAudio::~SmsFmAudio()
|
|
{
|
|
OPLL_delete(_opll);
|
|
_emu->GetSoundMixer()->UnregisterAudioProvider(this);
|
|
}
|
|
|
|
void SmsFmAudio::Run()
|
|
{
|
|
if(_fmEnabled && _emu->GetSettings()->GetSmsConfig().EnableFmAudio) {
|
|
uint64_t clocksToRun = _console->GetMasterClock() - _prevMasterClock;
|
|
while(clocksToRun >= 72) {
|
|
int16_t output = OPLL_calc(_opll);
|
|
_samplesToPlay.push_back(output);
|
|
_samplesToPlay.push_back(output);
|
|
_prevMasterClock += 72;
|
|
clocksToRun -= 72;
|
|
}
|
|
} else {
|
|
_prevMasterClock = _console->GetMasterClock();
|
|
}
|
|
}
|
|
|
|
bool SmsFmAudio::IsPsgAudioMuted()
|
|
{
|
|
//PSG is muted when 1 or 2
|
|
//This only works on the Japanese SMS - not on Mark III consoles
|
|
return _audioControl == 0x01 || _audioControl == 0x02;
|
|
}
|
|
|
|
uint8_t SmsFmAudio::Read()
|
|
{
|
|
//TODOSMS - c-sync counter bits?
|
|
return _audioControl & 0x03;
|
|
}
|
|
|
|
void SmsFmAudio::Write(uint8_t port, uint8_t value)
|
|
{
|
|
switch(port) {
|
|
case 0xF0:
|
|
case 0xF1:
|
|
_fmEnabled = true;
|
|
Run();
|
|
OPLL_writeIO(_opll, port, value);
|
|
break;
|
|
|
|
case 0xF2:
|
|
_audioControl = value & 0x03;
|
|
break;
|
|
}
|
|
}
|
|
|
|
void SmsFmAudio::MixAudio(int16_t* out, uint32_t sampleCount, uint32_t sampleRate)
|
|
{
|
|
Run();
|
|
|
|
if(_audioControl == 0 || _audioControl == 2) {
|
|
//FM audio is muted when 0 or 2
|
|
_samplesToPlay.clear();
|
|
return;
|
|
}
|
|
|
|
_resampler.SetSampleRates(_console->GetMasterClockRate() / 72.0, sampleRate);
|
|
_resampler.SetVolume(_emu->GetSettings()->GetSmsConfig().FmAudioVolume * 1.5 / 100.0);
|
|
_resampler.Resample<true>(_samplesToPlay.data(), (uint32_t)_samplesToPlay.size() / 2, out, sampleCount, true);
|
|
_samplesToPlay.clear();
|
|
}
|
|
|
|
void SmsFmAudio::Serialize(Serializer& s)
|
|
{
|
|
SV(_prevMasterClock);
|
|
SV(_audioControl);
|
|
SV(_fmEnabled);
|
|
Emu2413Serializer::Serialize(_opll, s);
|
|
}
|