audio.hpp 1.89 KB
Newer Older
Screwtape's avatar
Screwtape committed
1 2
#pragma once

Screwtape's avatar
Screwtape committed
3
#include <nall/dsp/iir/one-pole.hpp>
Screwtape's avatar
Screwtape committed
4 5 6
#include <nall/dsp/iir/biquad.hpp>
#include <nall/dsp/resampler/cubic.hpp>

Screwtape's avatar
Screwtape committed
7 8 9
namespace Emulator {

struct Interface;
Screwtape's avatar
Screwtape committed
10
struct Audio;
Screwtape's avatar
Screwtape committed
11
struct Filter;
Screwtape's avatar
Screwtape committed
12
struct Stream;
Screwtape's avatar
Screwtape committed
13 14

struct Audio {
Screwtape's avatar
Screwtape committed
15
  auto reset(maybe<uint> channels = nothing, maybe<double> frequency = nothing) -> void;
Screwtape's avatar
Screwtape committed
16
  auto setInterface(Interface* interface) -> void;
Screwtape's avatar
Screwtape committed
17

Screwtape's avatar
Screwtape committed
18
  auto setFrequency(double frequency) -> void;
Screwtape's avatar
Screwtape committed
19 20
  auto setVolume(double volume) -> void;
  auto setBalance(double balance) -> void;
Screwtape's avatar
Screwtape committed
21
  auto setReverb(bool enabled) -> void;
Screwtape's avatar
Screwtape committed
22

Screwtape's avatar
Screwtape committed
23
  auto createStream(uint channels, double frequency) -> shared_pointer<Stream>;
Screwtape's avatar
Screwtape committed
24 25

private:
Screwtape's avatar
Screwtape committed
26 27
  auto process() -> void;

Screwtape's avatar
Screwtape committed
28 29
  Interface* interface = nullptr;
  vector<shared_pointer<Stream>> streams;
Screwtape's avatar
Screwtape committed
30 31

  uint channels = 0;
Screwtape's avatar
Screwtape committed
32
  double frequency = 0.0;
Screwtape's avatar
Screwtape committed
33

Screwtape's avatar
Screwtape committed
34 35
  double volume = 1.0;
  double balance = 0.0;
Screwtape's avatar
Screwtape committed
36 37

  bool reverbEnable = false;
Screwtape's avatar
Screwtape committed
38
  vector<vector<queue<double>>> reverb;
Screwtape's avatar
Screwtape committed
39 40 41 42

  friend class Stream;
};

Screwtape's avatar
Screwtape committed
43 44 45 46 47 48 49 50 51
struct Filter {
  enum class Order : uint { First, Second };
  enum class Type : uint { LowPass, HighPass };

  Order order;
  DSP::IIR::OnePole onePole;  //first-order
  DSP::IIR::Biquad biquad;    //second-order
};

Screwtape's avatar
Screwtape committed
52
struct Stream {
Screwtape's avatar
Screwtape committed
53
  auto reset(uint channels, double inputFrequency, double outputFrequency) -> void;
Screwtape's avatar
Screwtape committed
54

Screwtape's avatar
Screwtape committed
55 56
  auto setFrequency(double inputFrequency, maybe<double> outputFrequency = nothing) -> void;

Screwtape's avatar
Screwtape committed
57
  auto addFilter(Filter::Order order, Filter::Type type, double cutoffFrequency, uint passes = 1) -> void;
Screwtape's avatar
Screwtape committed
58

Screwtape's avatar
Screwtape committed
59
  auto pending() const -> bool;
Screwtape's avatar
Screwtape committed
60 61
  auto read(double samples[]) -> uint;
  auto write(const double samples[]) -> void;
Screwtape's avatar
Screwtape committed
62 63

  template<typename... P> auto sample(P&&... p) -> void {
Screwtape's avatar
Screwtape committed
64
    double samples[sizeof...(P)] = {forward<P>(p)...};
Screwtape's avatar
Screwtape committed
65 66 67 68
    write(samples);
  }

private:
Screwtape's avatar
Screwtape committed
69
  struct Channel {
Screwtape's avatar
Screwtape committed
70
    vector<Filter> filters;
Screwtape's avatar
Screwtape committed
71 72 73
    DSP::Resampler::Cubic resampler;
  };
  vector<Channel> channels;
Screwtape's avatar
Screwtape committed
74 75
  double inputFrequency;
  double outputFrequency;
Screwtape's avatar
Screwtape committed
76 77 78 79

  friend class Audio;
};

Screwtape's avatar
Screwtape committed
80
extern Audio audio;
Screwtape's avatar
Screwtape committed
81 82

}