mirror of
https://github.com/SourMesen/Mesen2.git
synced 2025-04-02 10:21:44 -04:00
92 lines
No EOL
1.9 KiB
C++
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;
|
|
}
|
|
}
|
|
}; |