DDNet documentation
Loading...
Searching...
No Matches
sound.h
Go to the documentation of this file.
1/* (c) Magnus Auvinen. See licence.txt in the root of the distribution for more information. */
2/* If you are missing that file, acquire a complete release at teeworlds.com. */
3#ifndef ENGINE_CLIENT_SOUND_H
4#define ENGINE_CLIENT_SOUND_H
5
6#include <base/lock.h>
7
8#include <engine/sound.h>
9
10#include <SDL_audio.h>
11#include <SDL_events.h>
12
13#include <atomic>
14
15struct CSample
16{
19
20 short *m_pData;
22 int m_Rate;
26
27 float TotalTime() const
28 {
29 return m_NumFrames / (float)m_Rate;
30 }
31
32 bool IsLoaded() const
33 {
34 return m_pData != nullptr;
35 }
36};
37
39{
40 int m_Vol;
41 int m_Pan;
42};
43
44struct CVoice
45{
48 int m_Age; // increases when reused
49 int m_Tick;
50 int m_Vol; // 0 - 255
53 float m_Falloff; // [0.0, 1.0]
54
61};
62
63class CSound : public IEngineSound
64{
65 enum
66 {
70 };
71
72 bool m_SoundEnabled = false;
73 SDL_AudioSpec m_AudioSpec = {};
74 SDL_AudioDeviceID m_Device = 0;
75 bool m_DevicePaused = false;
76 std::atomic<bool> m_DeviceChanged = false;
78
80 int m_FirstFreeSampleIndex GUARDED_BY(m_SoundLock) = 0;
81
82 CVoice m_aVoices[NUM_VOICES] GUARDED_BY(m_SoundLock) = {{nullptr}};
83 CChannel m_aChannels[NUM_CHANNELS] GUARDED_BY(m_SoundLock) = {{255, 0}};
84 int m_NextVoice GUARDED_BY(m_SoundLock) = 0;
85 uint32_t m_MaxFrames = 0;
86
87 // This is not an std::atomic<vec2> as this would require linking with
88 // libatomic with clang x86 as there is no native support for this.
89 std::atomic<float> m_ListenerPositionX = 0.0f;
90 std::atomic<float> m_ListenerPositionY = 0.0f;
91 std::atomic<int> m_SoundVolume = 100;
92 int m_MixingRate = 48000;
93
94 class IEngineGraphics *m_pGraphics = nullptr;
95 IStorage *m_pStorage = nullptr;
96
97 int *m_pMixBuffer = nullptr;
98 int64_t m_PlaybackTime = 0;
99
101 void RateConvert(CSample &Sample) const;
102
103 static int SDLCALL HandleAudioDeviceEvent(void *pUser, SDL_Event *pEvent);
104 bool OpenDevice(bool AllowFrequencyChange);
105 void CloseDevice();
107 bool HasAudioOutput() const;
108 // Returns how many frames the voice advanced, looping or freeing it at the end of its sample
109 unsigned AdvanceVoice(CVoice &Voice, unsigned Frames) REQUIRES(m_SoundLock);
111
112 // pContextName used for error
113 bool DecodeOpus(CSample &Sample, const void *pData, unsigned DataSize, const char *pContextName) const;
114 bool DecodeWV(CSample &Sample, const void *pData, unsigned DataSize, const char *pContextName) const;
115
116 void UpdateVolume();
117
118public:
119 int Init() override REQUIRES(!m_SoundLock);
120 int Update() override REQUIRES(!m_SoundLock);
121 void Shutdown() override REQUIRES(!m_SoundLock);
122
123 bool IsSoundEnabled() override { return m_SoundEnabled; }
124
125 int LoadOpus(const char *pFilename, int StorageType = IStorage::TYPE_ALL) override REQUIRES(!m_SoundLock);
126 int LoadWV(const char *pFilename, int StorageType = IStorage::TYPE_ALL) override REQUIRES(!m_SoundLock);
127 int LoadOpusFromMem(const void *pData, unsigned DataSize, bool ForceLoad, const char *pContextName) override REQUIRES(!m_SoundLock);
128 int LoadWVFromMem(const void *pData, unsigned DataSize, bool ForceLoad, const char *pContextName) override REQUIRES(!m_SoundLock);
129 void UnloadSample(int SampleId) override REQUIRES(!m_SoundLock);
130
131 float GetSampleTotalTime(int SampleId) override REQUIRES(!m_SoundLock); // in s
132 float GetSampleCurrentTime(int SampleId) override REQUIRES(!m_SoundLock); // in s
133 void SetSampleCurrentTime(int SampleId, float Time) override REQUIRES(!m_SoundLock);
134
135 void SetChannel(int ChannelId, float Vol, float Pan) override REQUIRES(!m_SoundLock);
136 void SetListenerPosition(vec2 Position) override;
137
138 void SetVoiceVolume(CVoiceHandle Voice, float Volume) override REQUIRES(!m_SoundLock);
139 void SetVoiceFalloff(CVoiceHandle Voice, float Falloff) override REQUIRES(!m_SoundLock);
140 void SetVoicePosition(CVoiceHandle Voice, vec2 Position) override REQUIRES(!m_SoundLock);
141 void SetVoiceTimeOffset(CVoiceHandle Voice, float TimeOffset) override REQUIRES(!m_SoundLock); // in s
142
143 void SetVoiceCircle(CVoiceHandle Voice, float Radius) override REQUIRES(!m_SoundLock);
144 void SetVoiceRectangle(CVoiceHandle Voice, float Width, float Height) override REQUIRES(!m_SoundLock);
145
146 CVoiceHandle Play(int ChannelId, int SampleId, int Flags, float Volume, vec2 Position) REQUIRES(!m_SoundLock);
147 CVoiceHandle PlayAt(int ChannelId, int SampleId, int Flags, float Volume, vec2 Position) override REQUIRES(!m_SoundLock);
148 CVoiceHandle Play(int ChannelId, int SampleId, int Flags, float Volume) override REQUIRES(!m_SoundLock);
149 void Pause(int SampleId) override REQUIRES(!m_SoundLock);
150 void Stop(int SampleId) override REQUIRES(!m_SoundLock);
151 void StopAll() override REQUIRES(!m_SoundLock);
152 void StopVoice(CVoiceHandle Voice) override REQUIRES(!m_SoundLock);
153 bool IsPlaying(int SampleId) override REQUIRES(!m_SoundLock);
154
155 int MixingRate() const override { return m_MixingRate; }
156 void Mix(short *pFinalOut, unsigned Frames) override REQUIRES(!m_SoundLock);
157
158 void PauseAudioDevice() override;
159 void UnpauseAudioDevice() override;
160};
161
162#endif
Definition lock.h:90
Definition sound.h:64
int LoadOpus(const char *pFilename, int StorageType=IStorage::TYPE_ALL) override REQUIRES(!m_SoundLock)
Definition sound.cpp:674
void Pause(int SampleId) override REQUIRES(!m_SoundLock)
Definition sound.cpp:1069
int64_t m_PlaybackTime
Definition sound.h:98
int m_FirstFreeSampleIndex GUARDED_BY(m_SoundLock)=0
void CloseDevice()
Definition sound.cpp:283
void RateConvert(CSample &Sample) const
Definition sound.cpp:421
int Update() override REQUIRES(!m_SoundLock)
Definition sound.cpp:328
void Shutdown() override REQUIRES(!m_SoundLock)
Definition sound.cpp:384
void SetVoiceVolume(CVoiceHandle Voice, float Volume) override REQUIRES(!m_SoundLock)
Definition sound.cpp:882
bool m_SoundEnabled
Definition sound.h:72
unsigned AdvanceVoice(CVoice &Voice, unsigned Frames) REQUIRES(m_SoundLock)
Definition sound.cpp:32
static int SDLCALL HandleAudioDeviceEvent(void *pUser, SDL_Event *pEvent)
Definition sound.cpp:255
void SetListenerPosition(vec2 Position) override
Definition sound.cpp:876
void StopVoice(CVoiceHandle Voice) override REQUIRES(!m_SoundLock)
Definition sound.cpp:1125
CLock m_SoundLock
Definition sound.h:77
CSample * AllocSample() REQUIRES(!m_SoundLock)
Definition sound.cpp:405
float GetSampleCurrentTime(int SampleId) override REQUIRES(!m_SoundLock)
Definition sound.cpp:830
void AdvancePlayback() REQUIRES(!m_SoundLock)
Definition sound.cpp:336
void UnloadSample(int SampleId) override REQUIRES(!m_SoundLock)
Definition sound.cpp:788
SDL_AudioSpec m_AudioSpec
Definition sound.h:73
int LoadOpusFromMem(const void *pData, unsigned DataSize, bool ForceLoad, const char *pContextName) override REQUIRES(!m_SoundLock)
Definition sound.cpp:748
void SetChannel(int ChannelId, float Vol, float Pan) override REQUIRES(!m_SoundLock)
Definition sound.cpp:867
CVoiceHandle PlayAt(int ChannelId, int SampleId, int Flags, float Volume, vec2 Position) override REQUIRES(!m_SoundLock)
Definition sound.cpp:1059
void SetVoicePosition(CVoiceHandle Voice, vec2 Position) override REQUIRES(!m_SoundLock)
Definition sound.cpp:912
bool IsPlaying(int SampleId) override REQUIRES(!m_SoundLock)
Definition sound.cpp:1140
uint32_t m_MaxFrames
Definition sound.h:85
CVoiceHandle Play(int ChannelId, int SampleId, int Flags, float Volume, vec2 Position) REQUIRES(!m_SoundLock)
Definition sound.cpp:1010
class IEngineGraphics * m_pGraphics
Definition sound.h:94
void Mix(short *pFinalOut, unsigned Frames) override REQUIRES(!m_SoundLock)
Definition sound.cpp:55
float GetSampleTotalTime(int SampleId) override REQUIRES(!m_SoundLock)
Definition sound.cpp:821
void PauseAudioDevice() override
Definition sound.cpp:1149
void Stop(int SampleId) override REQUIRES(!m_SoundLock)
Definition sound.cpp:1087
void SetSampleCurrentTime(int SampleId, float Time) override REQUIRES(!m_SoundLock)
Definition sound.cpp:848
bool HasAudioOutput() const
Definition sound.cpp:319
bool IsSoundEnabled() override
Definition sound.h:123
int LoadWV(const char *pFilename, int StorageType=IStorage::TYPE_ALL) override REQUIRES(!m_SoundLock)
Definition sound.cpp:711
bool DecodeOpus(CSample &Sample, const void *pData, unsigned DataSize, const char *pContextName) const
Definition sound.cpp:461
int m_MixingRate
Definition sound.h:92
bool m_DevicePaused
Definition sound.h:75
std::atomic< float > m_ListenerPositionY
Definition sound.h:90
std::atomic< float > m_ListenerPositionX
Definition sound.h:89
void SetVoiceTimeOffset(CVoiceHandle Voice, float TimeOffset) override REQUIRES(!m_SoundLock)
Definition sound.cpp:926
void StopAll() override REQUIRES(!m_SoundLock)
Definition sound.cpp:1108
int m_NextVoice GUARDED_BY(m_SoundLock)=0
CChannel m_aChannels[NUM_CHANNELS] GUARDED_BY(m_SoundLock)
int Init() override REQUIRES(!m_SoundLock)
Definition sound.cpp:198
void UnpauseAudioDevice() override
Definition sound.cpp:1158
int MixingRate() const override
Definition sound.h:155
SDL_AudioDeviceID m_Device
Definition sound.h:74
@ NUM_VOICES
Definition sound.h:68
@ NUM_CHANNELS
Definition sound.h:69
@ NUM_SAMPLES
Definition sound.h:67
bool DecodeWV(CSample &Sample, const void *pData, unsigned DataSize, const char *pContextName) const
Definition sound.cpp:590
void SetVoiceRectangle(CVoiceHandle Voice, float Width, float Height) override REQUIRES(!m_SoundLock)
Definition sound.cpp:994
bool OpenDevice(bool AllowFrequencyChange)
Definition sound.cpp:264
void UpdateVolume()
Definition sound.cpp:376
int * m_pMixBuffer
Definition sound.h:97
std::atomic< int > m_SoundVolume
Definition sound.h:91
void SetVoiceCircle(CVoiceHandle Voice, float Radius) override REQUIRES(!m_SoundLock)
Definition sound.cpp:979
void UpdateDevice() REQUIRES(!m_SoundLock)
Definition sound.cpp:292
CSample m_aSamples[NUM_SAMPLES] GUARDED_BY(m_SoundLock)
IStorage * m_pStorage
Definition sound.h:95
int LoadWVFromMem(const void *pData, unsigned DataSize, bool ForceLoad, const char *pContextName) override REQUIRES(!m_SoundLock)
Definition sound.cpp:768
CVoice m_aVoices[NUM_VOICES] GUARDED_BY(m_SoundLock)
void SetVoiceFalloff(CVoiceHandle Voice, float Falloff) override REQUIRES(!m_SoundLock)
Definition sound.cpp:897
std::atomic< bool > m_DeviceChanged
Definition sound.h:76
Definition graphics.h:678
Definition sound.h:115
Definition storage.h:21
@ TYPE_ALL
Definition storage.h:27
#define REQUIRES(...)
Definition lock.h:34
Definition sound.h:39
int m_Pan
Definition sound.h:41
int m_Vol
Definition sound.h:40
Definition sound.h:16
int m_PausedAt
Definition sound.h:25
bool IsLoaded() const
Definition sound.h:32
int m_Index
Definition sound.h:17
int m_NumFrames
Definition sound.h:21
int m_Channels
Definition sound.h:23
int m_Rate
Definition sound.h:22
short * m_pData
Definition sound.h:20
float TotalTime() const
Definition sound.h:27
int m_NextFreeSampleIndex
Definition sound.h:18
int m_LoopStart
Definition sound.h:24
Definition sound.h:45
CSample * m_pSample
Definition sound.h:46
CChannel * m_pChannel
Definition sound.h:47
int m_Vol
Definition sound.h:50
int m_Flags
Definition sound.h:51
int m_Age
Definition sound.h:48
float m_Falloff
Definition sound.h:53
int m_Tick
Definition sound.h:49
vec2 m_Position
Definition sound.h:52
int m_Shape
Definition sound.h:55
Definition sound.h:37
Definition sound.h:42
ISound::CVoiceShapeCircle m_Circle
ISound::CVoiceShapeRectangle m_Rectangle
vector2_base< float > vec2
Definition vmath.h:168