Mesen-SX/Core/Spc.cpp
Sour a71de2a7bf SPC: Run SPC 1 frame per frame, rather than 60 frames per frame.
+ Fixed warnings in SPC code in 64-bit mode
2019-02-21 16:49:19 -05:00

61 lines
1.5 KiB
C++

#include "stdafx.h"
#include "Spc.h"
#include "SNES_SPC.h"
#include "Console.h"
#include "MemoryManager.h"
#include "SoundMixer.h"
#include "../Utilities/VirtualFile.h"
Spc::Spc(shared_ptr<Console> console)
{
_console = console;
vector<uint8_t> fileData;
VirtualFile spcBios("spc700.rom");
spcBios.ReadFile(fileData);
memcpy(_spcBios, fileData.data(), 64);
_soundBuffer = new int16_t[Spc::SampleBufferSize];
_spc = new SNES_SPC();
_spc->init();
_spc->init_rom(_spcBios);
_spc->reset();
_spc->set_output(_soundBuffer, Spc::SampleBufferSize >> 1);
_startFrameMasterClock = 0;
}
Spc::~Spc()
{
delete _spc;
}
int Spc::GetSpcTime()
{
uint64_t currentClock = _console->GetMemoryManager()->GetMasterClock();
uint64_t elapsedClocks = currentClock - _startFrameMasterClock;
return (int)(elapsedClocks * 1024000 / 21477000);
}
uint8_t Spc::Read(uint16_t addr)
{
return _spc->read_port(GetSpcTime(), addr & 0x03);
}
void Spc::Write(uint32_t addr, uint8_t value)
{
_spc->write_port(GetSpcTime(), addr & 0x03, value);
}
void Spc::ProcessEndFrame()
{
_spc->end_frame(GetSpcTime());
int sampleCount = _spc->sample_count();
_console->GetSoundMixer()->PlayAudioBuffer(_soundBuffer, sampleCount / 2);
_spc->set_output(_soundBuffer, Spc::SampleBufferSize >> 1);
uint64_t remainder = (_console->GetMemoryManager()->GetMasterClock() - _startFrameMasterClock) * 1024000 % 21477000 / 1024000;
_startFrameMasterClock = _console->GetMemoryManager()->GetMasterClock() - remainder;
}