mirror of
https://github.com/SourMesen/Mesen2.git
synced 2025-04-02 10:21:44 -04:00
-Super Mario Land 2 - Pops in menu are fixed by immediately updating APU output after a write -Perfect Dark - Low voice volume is fixed by having the correct output when the channels are disabled (but DAC is still enabled) -Daiku no Gen - Low voice volume is fixed by keeping square channel output to digital 0 (= analog 1) until its first tick after being enabled (the game does not let the channel tick at all while the voice sample is playing)
81 lines
1.8 KiB
C++
81 lines
1.8 KiB
C++
#pragma once
|
|
#include "pch.h"
|
|
#include "Gameboy/APU/GbSquareChannel.h"
|
|
#include "Gameboy/APU/GbWaveChannel.h"
|
|
#include "Gameboy/APU/GbNoiseChannel.h"
|
|
#include "Utilities/Audio/blip_buf.h"
|
|
#include "Utilities/ISerializable.h"
|
|
|
|
class Emulator;
|
|
class Gameboy;
|
|
class SoundMixer;
|
|
class EmuSettings;
|
|
struct GameboyConfig;
|
|
|
|
class GbApu : public ISerializable
|
|
{
|
|
public:
|
|
static constexpr int SampleRate = 96000;
|
|
|
|
private:
|
|
static constexpr int ApuFrequency = 1024 * 1024 * 4; //4mhz
|
|
static constexpr int MaxSamples = 4000;
|
|
Emulator* _emu = nullptr;
|
|
Gameboy* _gameboy = nullptr;
|
|
EmuSettings* _settings = nullptr;
|
|
SoundMixer* _soundMixer = nullptr;
|
|
|
|
unique_ptr<GbSquareChannel> _square1;
|
|
unique_ptr<GbSquareChannel> _square2;
|
|
unique_ptr<GbWaveChannel> _wave;
|
|
unique_ptr<GbNoiseChannel> _noise;
|
|
|
|
int16_t* _soundBuffer = nullptr;
|
|
blip_t* _leftChannel = nullptr;
|
|
blip_t* _rightChannel = nullptr;
|
|
|
|
int16_t _prevLeftOutput = 0;
|
|
int16_t _prevRightOutput = 0;
|
|
uint32_t _clockCounter = 0;
|
|
uint64_t _prevClockCount = 0;
|
|
|
|
uint32_t _skipFirstEventCounter = 0;
|
|
uint64_t _powerOnCycle = 0;
|
|
|
|
GbApuState _state = {};
|
|
|
|
uint8_t InternalRead(uint16_t addr);
|
|
uint8_t InternalReadCgbRegister(uint16_t addr);
|
|
|
|
void UpdateOutput(GameboyConfig& cfg);
|
|
|
|
public:
|
|
GbApu();
|
|
virtual ~GbApu();
|
|
|
|
void Init(Emulator* emu, Gameboy* gameboy);
|
|
|
|
GbApuDebugState GetState();
|
|
|
|
bool IsOddApuCycle();
|
|
uint64_t GetElapsedApuCycles();
|
|
|
|
void Run();
|
|
|
|
void PlayQueuedAudio();
|
|
|
|
void GetSoundSamples(int16_t* &samples, uint32_t& sampleCount);
|
|
|
|
void ClockFrameSequencer();
|
|
|
|
uint8_t Peek(uint16_t addr);
|
|
uint8_t Read(uint16_t addr);
|
|
void Write(uint16_t addr, uint8_t value);
|
|
|
|
uint8_t PeekCgbRegister(uint16_t addr);
|
|
uint8_t ReadCgbRegister(uint16_t addr);
|
|
|
|
template<typename T> void ProcessLengthEnableFlag(uint8_t value, T& length, bool& lengthEnabled, bool& enabled);
|
|
|
|
void Serialize(Serializer& s) override;
|
|
};
|