Mesen2/Core/NES/Mappers/Audio/Vrc7Audio.h
2023-12-14 22:23:27 +09:00

92 lines
No EOL
1.9 KiB
C++

#pragma once
#include "pch.h"
#include "NES/APU/BaseExpansionAudio.h"
#include "NES/APU/NesApu.h"
#include "NES/NesConsole.h"
#include "Shared/Utilities/emu2413.h"
#include "Shared/Utilities/Emu2413Serializer.h"
#include "Utilities/Serializer.h"
class Vrc7Audio : public BaseExpansionAudio
{
private:
static constexpr int OpllSampleRate = 49716;
static constexpr int OpllClockRate = Vrc7Audio::OpllSampleRate * 72;
OPLL* _opll = nullptr;
uint8_t _currentReg = 0;
int16_t _previousOutput = 0;
double _clockTimer = 0;
bool _muted = false;
protected:
void ClockAudio() override
{
if(_clockTimer == 0) {
_clockTimer = ((double)_console->GetMasterClockRate()) / Vrc7Audio::OpllSampleRate;
}
_clockTimer--;
if(_clockTimer <= 0) {
int16_t output = OPLL_calc(_opll);
_console->GetApu()->AddExpansionAudioDelta(AudioChannel::VRC7, _muted ? 0 : (output - _previousOutput));
_previousOutput = output;
_clockTimer = ((double)_console->GetMasterClockRate()) / Vrc7Audio::OpllSampleRate;
}
}
void Serialize(Serializer& s) override
{
BaseExpansionAudio::Serialize(s);
SV(_currentReg); SV(_previousOutput); SV(_clockTimer); SV(_muted);
Emu2413Serializer::Serialize(_opll, s);
}
public:
Vrc7Audio(NesConsole* console) : BaseExpansionAudio(console)
{
_previousOutput = 0;
_currentReg = 0;
_muted = false;
_clockTimer = 0;
_opll = OPLL_new(Vrc7Audio::OpllClockRate, Vrc7Audio::OpllSampleRate);
//Set OPLL emulator to VRC7 mode
OPLL_setChipType(_opll, 1);
OPLL_resetPatch(_opll, 1);
}
~Vrc7Audio()
{
OPLL_delete(_opll);
}
void Reset()
{
OPLL_reset(_opll);
}
void SetMuteAudio(bool muted)
{
_muted = muted;
}
void WriteReg(uint16_t addr, uint8_t value)
{
if(_muted) {
//"Writes to $9010 and $9030 are disregarded while this bit is set."
return;
}
switch(addr & 0xF030) {
case 0x9010:
_currentReg = value;
break;
case 0x9030:
OPLL_writeReg(_opll, _currentReg, value);
break;
}
}
};