2016-01-14 06:21:09 +00:00
|
|
|
#pragma once
|
|
|
|
#include "stdafx.h"
|
|
|
|
#include "EmulationSettings.h"
|
2016-01-31 18:53:17 +00:00
|
|
|
#include "../Utilities/LowPassFilter.h"
|
2016-05-22 12:14:55 +00:00
|
|
|
#include "../Utilities/blip_buf.h"
|
2016-06-05 18:36:20 +00:00
|
|
|
#include "../Utilities/SimpleLock.h"
|
2016-01-15 00:33:16 +00:00
|
|
|
#include "IAudioDevice.h"
|
2016-01-21 05:53:02 +00:00
|
|
|
#include "Snapshotable.h"
|
2016-02-21 20:31:39 +00:00
|
|
|
#include "StereoPanningFilter.h"
|
|
|
|
#include "StereoDelayFilter.h"
|
2018-08-03 14:49:23 +00:00
|
|
|
#include "StereoCombFilter.h"
|
2016-02-21 20:31:39 +00:00
|
|
|
#include "ReverbFilter.h"
|
2016-12-10 02:23:20 +00:00
|
|
|
#include "CrossFeedFilter.h"
|
2017-08-19 20:46:57 +00:00
|
|
|
|
2018-07-01 19:21:05 +00:00
|
|
|
class Console;
|
2017-08-19 20:46:57 +00:00
|
|
|
class OggMixer;
|
2016-01-14 06:21:09 +00:00
|
|
|
|
2017-04-15 17:54:47 +00:00
|
|
|
namespace orfanidis_eq {
|
|
|
|
class freq_grid;
|
|
|
|
class eq1;
|
|
|
|
}
|
|
|
|
|
2016-01-21 05:53:02 +00:00
|
|
|
class SoundMixer : public Snapshotable
|
2016-01-14 06:21:09 +00:00
|
|
|
{
|
2016-01-30 19:57:50 +00:00
|
|
|
public:
|
2018-07-01 19:21:05 +00:00
|
|
|
static constexpr uint32_t CycleLength = 10000;
|
|
|
|
static constexpr uint32_t BitsPerSample = 16;
|
2016-01-30 19:57:50 +00:00
|
|
|
|
2016-01-14 06:21:09 +00:00
|
|
|
private:
|
2018-07-01 19:21:05 +00:00
|
|
|
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;
|
2018-07-14 02:19:26 +00:00
|
|
|
EmulationSettings* _settings;
|
2018-07-01 19:21:05 +00:00
|
|
|
double _fadeRatio;
|
|
|
|
uint32_t _muteFrameCount;
|
|
|
|
unique_ptr<OggMixer> _oggMixer;
|
2016-06-05 18:36:20 +00:00
|
|
|
|
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;
|
2018-07-01 19:21:05 +00:00
|
|
|
shared_ptr<Console> _console;
|
2017-04-15 17:54:47 +00:00
|
|
|
|
2016-12-10 02:23:20 +00:00
|
|
|
CrossFeedFilter _crossFeedFilter;
|
2016-01-31 18:53:17 +00:00
|
|
|
LowPassFilter _lowPassFilter;
|
2016-02-21 20:31:39 +00:00
|
|
|
StereoPanningFilter _stereoPanning;
|
|
|
|
StereoDelayFilter _stereoDelay;
|
2018-08-03 14:49:23 +00:00
|
|
|
StereoCombFilter _stereoCombFilter;
|
2016-02-21 20:31:39 +00:00
|
|
|
ReverbFilter _reverbFilter;
|
2016-01-15 00:33:16 +00:00
|
|
|
|
2016-12-10 02:23:20 +00:00
|
|
|
int16_t _previousOutputLeft = 0;
|
|
|
|
int16_t _previousOutputRight = 0;
|
2016-01-14 06:21:09 +00:00
|
|
|
|
|
|
|
vector<uint32_t> _timestamps;
|
2016-06-12 15:28:45 +00:00
|
|
|
int16_t _channelOutput[MaxChannelCount][CycleLength];
|
|
|
|
int16_t _currentOutput[MaxChannelCount];
|
2016-01-14 06:21:09 +00:00
|
|
|
|
2016-12-10 02:23:20 +00:00
|
|
|
blip_t* _blipBufLeft;
|
|
|
|
blip_t* _blipBufRight;
|
2016-01-14 06:21:09 +00:00
|
|
|
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-01-14 06:21:09 +00:00
|
|
|
|
2016-06-12 22:11:31 +00:00
|
|
|
NesModel _model;
|
2016-01-15 00:33:16 +00:00
|
|
|
uint32_t _sampleRate;
|
|
|
|
uint32_t _clockRate;
|
|
|
|
|
2017-04-02 21:41:24 +00:00
|
|
|
bool _hasPanning;
|
|
|
|
|
2018-06-09 18:03:53 +00:00
|
|
|
double _previousTargetRate;
|
|
|
|
|
2016-12-10 02:23:20 +00:00
|
|
|
double GetChannelOutput(AudioChannel channel, bool forRightChannel);
|
|
|
|
int16_t GetOutputVolume(bool forRightChannel);
|
2016-01-14 06:21:09 +00:00
|
|
|
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);
|
2018-07-31 22:58:50 +00:00
|
|
|
|
|
|
|
double GetTargetRateAdjustment();
|
2018-06-09 18:03:53 +00:00
|
|
|
void UpdateTargetSampleRate();
|
2016-01-15 00:33:16 +00:00
|
|
|
|
2016-01-21 05:53:02 +00:00
|
|
|
protected:
|
2016-12-18 04:14:47 +00:00
|
|
|
virtual void StreamState(bool saving) override;
|
2016-01-21 05:53:02 +00:00
|
|
|
|
2016-01-14 06:21:09 +00:00
|
|
|
public:
|
2018-07-01 19:21:05 +00:00
|
|
|
SoundMixer(shared_ptr<Console> console);
|
2016-01-14 06:21:09 +00:00
|
|
|
~SoundMixer();
|
|
|
|
|
|
|
|
void SetNesModel(NesModel model);
|
|
|
|
void Reset();
|
|
|
|
|
|
|
|
void PlayAudioBuffer(uint32_t cycle);
|
2016-06-12 15:28:45 +00:00
|
|
|
void AddDelta(AudioChannel channel, uint32_t time, int16_t delta);
|
2016-01-30 19:57:50 +00:00
|
|
|
|
2018-07-01 19:21:05 +00:00
|
|
|
void StartRecording(string filepath);
|
|
|
|
void StopRecording();
|
|
|
|
bool IsRecording();
|
2016-06-05 18:36:20 +00:00
|
|
|
|
2016-06-26 00:46:54 +00:00
|
|
|
//For NSF/NSFe
|
2018-07-01 19:21:05 +00:00
|
|
|
uint32_t GetMuteFrameCount();
|
|
|
|
void ResetMuteFrameCount();
|
|
|
|
void SetFadeRatio(double fadeRatio);
|
2016-06-26 00:46:54 +00:00
|
|
|
|
2018-07-01 19:21:05 +00:00
|
|
|
void StopAudio(bool clearBuffer = false);
|
|
|
|
void RegisterAudioDevice(IAudioDevice *audioDevice);
|
2017-08-19 20:46:57 +00:00
|
|
|
|
2018-07-01 19:21:05 +00:00
|
|
|
OggMixer* GetOggMixer();
|
2018-06-09 18:03:53 +00:00
|
|
|
|
2018-07-01 19:21:05 +00:00
|
|
|
void ProcessEndOfFrame();
|
2018-08-03 02:09:55 +00:00
|
|
|
double GetRateAdjustment();
|
2016-01-14 06:21:09 +00:00
|
|
|
};
|