-
Notifications
You must be signed in to change notification settings - Fork 4
/
Audio.h
154 lines (113 loc) · 3.26 KB
/
Audio.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
#pragma once
#include "sf/Base.h"
#include "sf/Array.h"
#include "sf/Box.h"
namespace sp {
struct AudioSource
{
static const constexpr uint32_t AdvancePaddingInFloats = 8;
uint32_t sampleRate;
uint32_t numChannels;
virtual void seek(uint32_t sample) = 0;
// Allowed to read past `dst` by AdvancePaddingInFloats floats!
virtual uint32_t advance(uint32_t sample, float *dst, uint32_t num) = 0;
};
struct AudioMixOpts
{
bool loop = false;
uint32_t sampleRate = 44100;
float volumeNext[2] = { 1.0f, 1.0f };
float volumeFadeDuration = 1.0f / 30.0f;
float pitch = 1.0f;
};
struct AudioSampler
{
float carryBuf[64];
uint32_t carryFirstSample = 0;
uint32_t carryNumSamples = 0;
uint32_t srcAdvanceSample = 0;
double srcSampleTime = 0.0;
uint32_t loopCount = 0;
bool ended = false;
bool started = false;
float volumeT = 1.0f;
float volumeSrc[2] = { };
float volumeDst[2] = { };
void advanceMixStereo(float *dst, uint32_t numDst, AudioSource *source, const AudioMixOpts &opts);
void advanceMixStereoImp(float *dst, uint32_t numDst, AudioSource *source, const AudioMixOpts &opts);
};
struct AudioLimiter
{
sf::Array<float> buffer;
float windowLengthSec = 1.0f / 100.0f;
float volumeRecoverPerWindow = 0.01f;
float prevWindowVolume = 1.0f;
float prevTargetVolume = 1.0f;
bool bufferEmpty = true;
uint32_t overflowOffset = 0;
uint32_t numOverflowSamples = 0;
void reset();
float *getStereoBuffer(uint32_t &requiredSamples, uint32_t numSamples, uint32_t sampleRate);
void limitStereo(float *dstSamples, uint32_t numSamples, uint32_t sampleRate);
};
struct BeginLoopAudioSource : AudioSource
{
sf::Box<AudioSource> begin;
sf::Box<AudioSource> loop;
bool inLoop = false;
uint32_t loopBeginSample = 0;
BeginLoopAudioSource();
BeginLoopAudioSource(sf::Box<AudioSource> begin, sf::Box<AudioSource> loop);
virtual void seek(uint32_t sample) override;
virtual uint32_t advance(uint32_t sample, float *dst, uint32_t num) override;
};
struct BeginLoopEndAudioSource : AudioSource
{
enum State
{
Begin,
Loop,
End,
};
sf::Box<AudioSource> begin;
sf::Box<AudioSource> loop;
sf::Box<AudioSource> end;
uint32_t impStopFlag = 0;
State impState = Begin;
uint32_t impBeginSample = 0;
void stop();
bool unstop();
virtual void seek(uint32_t sample) override;
virtual uint32_t advance(uint32_t sample, float *dst, uint32_t num) override;
};
struct InterruptLoopAudioSource : AudioSource
{
sf::Box<AudioSource> loop;
sf::Box<AudioSource> end;
uint32_t impStopFlag = 0;
sf::Array<float> fadeBuffer;
bool hasFadeBuffer = false;
bool atEnd = false;
uint64_t totalSamples;
uint32_t fadeBufferFirstSample;
uint32_t interruptInterval = 1;
void stop();
bool unstop();
virtual void seek(uint32_t sample) override;
virtual uint32_t advance(uint32_t sample, float *dst, uint32_t num) override;
};
struct SwappingAudioSource : AudioSource
{
sf::Box<AudioSource> source[2];
uint64_t startSample[2] = { };
uint32_t impShouldStart[2] = { };
uint32_t impPlaying[2] = { };
uint32_t swapInterval = 1;
uint64_t totalSamples = 0;
void play(uint32_t sourceIndex);
void unplay(uint32_t sourceIndex);
bool isPlaying(uint32_t sourceIndex) const;
virtual void seek(uint32_t sample) override;
virtual uint32_t advance(uint32_t sample, float *dst, uint32_t num) override;
};
}