Mesen/Core/SoundMixer.h

121 lines
3.0 KiB
C
Raw Normal View History

#pragma once
#include "stdafx.h"
#include "EmulationSettings.h"
#include "../Utilities/LowPassFilter.h"
2016-05-22 12:14:55 +00:00
#include "../Utilities/blip_buf.h"
#include "../Utilities/SimpleLock.h"
#include "IAudioDevice.h"
#include "Snapshotable.h"
#include "StereoPanningFilter.h"
#include "StereoDelayFilter.h"
2018-08-03 14:49:23 +00:00
#include "StereoCombFilter.h"
#include "ReverbFilter.h"
2016-12-10 02:23:20 +00:00
#include "CrossFeedFilter.h"
2017-08-19 20:46:57 +00:00
class Console;
2017-08-19 20:46:57 +00:00
class WaveRecorder;
class OggMixer;
2017-04-15 17:54:47 +00:00
namespace orfanidis_eq {
class freq_grid;
class eq1;
}
class SoundMixer : public Snapshotable
{
2016-01-30 19:57:50 +00:00
public:
static constexpr uint32_t CycleLength = 10000;
static constexpr uint32_t BitsPerSample = 16;
2016-01-30 19:57:50 +00:00
private:
static constexpr uint32_t MaxSampleRate = 96000;
static constexpr uint32_t MaxSamplesPerFrame = MaxSampleRate / 60 * 4 * 2; //x4 to allow CPU overclocking up to 10x, x2 for panning stereo
static constexpr uint32_t MaxChannelCount = 11;
IAudioDevice* _audioDevice;
EmulationSettings* _settings;
shared_ptr<WaveRecorder> _waveRecorder;
double _fadeRatio;
uint32_t _muteFrameCount;
unique_ptr<OggMixer> _oggMixer;
2017-04-15 17:54:47 +00:00
unique_ptr<orfanidis_eq::freq_grid> _eqFrequencyGrid;
unique_ptr<orfanidis_eq::eq1> _equalizerLeft;
unique_ptr<orfanidis_eq::eq1> _equalizerRight;
shared_ptr<Console> _console;
2017-04-15 17:54:47 +00:00
2016-12-10 02:23:20 +00:00
CrossFeedFilter _crossFeedFilter;
LowPassFilter _lowPassFilter;
StereoPanningFilter _stereoPanning;
StereoDelayFilter _stereoDelay;
2018-08-03 14:49:23 +00:00
StereoCombFilter _stereoCombFilter;
ReverbFilter _reverbFilter;
2016-12-10 02:23:20 +00:00
int16_t _previousOutputLeft = 0;
int16_t _previousOutputRight = 0;
double _rateAdjustment = 1.0;
int32_t _underTarget = 0;
vector<uint32_t> _timestamps;
int16_t _channelOutput[MaxChannelCount][CycleLength];
int16_t _currentOutput[MaxChannelCount];
2016-12-10 02:23:20 +00:00
blip_t* _blipBufLeft;
blip_t* _blipBufRight;
int16_t *_outputBuffer;
2016-01-30 19:57:50 +00:00
double _volumes[MaxChannelCount];
2016-12-10 02:23:20 +00:00
double _panning[MaxChannelCount];
2016-06-12 22:11:31 +00:00
NesModel _model;
uint32_t _sampleRate;
uint32_t _clockRate;
bool _hasPanning;
double _previousTargetRate;
2016-12-10 02:23:20 +00:00
double GetChannelOutput(AudioChannel channel, bool forRightChannel);
int16_t GetOutputVolume(bool forRightChannel);
void EndFrame(uint32_t time);
2016-06-12 22:11:31 +00:00
void UpdateRates(bool forceUpdate);
2017-04-15 17:54:47 +00:00
void UpdateEqualizers(bool forceUpdate);
void ApplyEqualizer(orfanidis_eq::eq1* equalizer, size_t sampleCount);
double GetTargetRateAdjustment();
void UpdateTargetSampleRate();
protected:
2016-12-18 04:14:47 +00:00
virtual void StreamState(bool saving) override;
public:
SoundMixer(shared_ptr<Console> console);
~SoundMixer();
void SetNesModel(NesModel model);
void Reset();
void PlayAudioBuffer(uint32_t cycle);
void AddDelta(AudioChannel channel, uint32_t time, int16_t delta);
2016-01-30 19:57:50 +00:00
void StartRecording(string filepath);
void StopRecording();
bool IsRecording();
2016-06-26 00:46:54 +00:00
//For NSF/NSFe
uint32_t GetMuteFrameCount();
void ResetMuteFrameCount();
void SetFadeRatio(double fadeRatio);
2016-06-26 00:46:54 +00:00
void StopAudio(bool clearBuffer = false);
void RegisterAudioDevice(IAudioDevice *audioDevice);
2017-08-19 20:46:57 +00:00
OggMixer* GetOggMixer();
AudioStatistics GetStatistics();
void ProcessEndOfFrame();
double GetRateAdjustment();
};