1 /*************************************************************************/ 2 /* spatial_sound_server_sw.h */ 3 /*************************************************************************/ 4 /* This file is part of: */ 5 /* GODOT ENGINE */ 6 /* https://godotengine.org */ 7 /*************************************************************************/ 8 /* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ 9 /* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ 10 /* */ 11 /* Permission is hereby granted, free of charge, to any person obtaining */ 12 /* a copy of this software and associated documentation files (the */ 13 /* "Software"), to deal in the Software without restriction, including */ 14 /* without limitation the rights to use, copy, modify, merge, publish, */ 15 /* distribute, sublicense, and/or sell copies of the Software, and to */ 16 /* permit persons to whom the Software is furnished to do so, subject to */ 17 /* the following conditions: */ 18 /* */ 19 /* The above copyright notice and this permission notice shall be */ 20 /* included in all copies or substantial portions of the Software. */ 21 /* */ 22 /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ 23 /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ 24 /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ 25 /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ 26 /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ 27 /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ 28 /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ 29 /*************************************************************************/ 30 #ifndef SPATIAL_SOUND_SERVER_SW_H 31 #define SPATIAL_SOUND_SERVER_SW_H 32 33 #include "octree.h" 34 #include "os/thread_safe.h" 35 #include "servers/spatial_sound_server.h" 36 37 class SpatialSoundServerSW : public SpatialSoundServer { 38 39 OBJ_TYPE(SpatialSoundServerSW, SpatialSoundServer); 40 41 _THREAD_SAFE_CLASS_ 42 43 enum { 44 MAX_CULL_ROOMS = 128, 45 INTERNAL_BUFFER_SIZE = 4096, 46 INTERNAL_BUFFER_MAX_CHANNELS = 4, 47 VOICE_IS_STREAM = -1 48 49 }; 50 51 struct InternalAudioStream : public AudioServer::AudioStream { 52 53 ::SpatialSoundServerSW *owner; 54 virtual int get_channel_count() const; 55 virtual void set_mix_rate(int p_rate); //notify the stream of the mix rate 56 virtual bool mix(int32_t *p_buffer, int p_frames); 57 virtual void update(); 58 }; 59 60 InternalAudioStream *internal_audio_stream; 61 RID internal_audio_stream_rid; 62 int32_t *internal_buffer; 63 int internal_buffer_channels; 64 65 bool internal_buffer_mix(int32_t *p_buffer, int p_frames); 66 67 struct Room; 68 69 struct Space { 70 71 RID default_room; 72 Set<RID> rooms; 73 Set<RID> sources; 74 Set<RID> listeners; 75 76 Octree<Room> octree; 77 }; 78 79 mutable RID_Owner<Space> space_owner; 80 81 struct Room { 82 RID space; 83 Transform transform; 84 Transform inverse_transform; 85 BSP_Tree bounds; 86 RoomReverb reverb; 87 float params[ROOM_PARAM_MAX]; 88 bool override_other_sources; 89 OctreeElementID octree_id; 90 int level; 91 92 Room(); 93 }; 94 95 mutable RID_Owner<Room> room_owner; 96 97 struct Source { 98 99 struct Voice { 100 101 RID voice_rid; 102 RID sample_rid; 103 bool active; 104 bool restart; 105 int priority; 106 float pitch_scale; 107 float volume_scale; 108 int sample_mix_rate; 109 110 float last_volume; 111 float last_filter_gain; 112 float last_filter_cutoff; 113 Vector3 last_panning; 114 int last_mix_rate; 115 RoomReverb last_reverb_room; 116 float last_reverb_send; 117 118 Voice(); 119 ~Voice(); 120 }; 121 122 struct StreamData { 123 124 Vector3 panning; 125 RoomReverb reverb; 126 float reverb_send; 127 float volume; 128 float filter_gain; 129 float filter_cutoff; 130 131 struct FilterState { 132 133 float ha[2]; 134 float hb[2]; 135 } filter_state[4]; 136 StreamDataSource::StreamData137 StreamData() { 138 139 reverb_send = 0; 140 reverb = ROOM_REVERB_HALL; 141 volume = 1.0; 142 filter_gain = 1; 143 filter_cutoff = 5000; 144 } 145 } stream_data; 146 147 RID space; 148 Transform transform; 149 float params[SOURCE_PARAM_MAX]; 150 AudioServer::AudioStream *stream; 151 Vector<Voice> voices; 152 int last_voice; 153 154 Source(); 155 }; 156 157 mutable RID_Owner<Source> source_owner; 158 159 struct Listener { 160 161 RID space; 162 Transform transform; 163 float params[LISTENER_PARAM_MAX]; 164 165 Listener(); 166 }; 167 168 mutable RID_Owner<Listener> listener_owner; 169 170 struct ActiveVoice { 171 172 Source *source; 173 int voice; 174 bool operator<(const ActiveVoice &p_voice) const { return (voice == p_voice.voice) ? (source < p_voice.source) : (voice < p_voice.voice); } 175 ActiveVoice(Source *p_source = NULL, int p_voice = 0) { 176 source = p_source; 177 voice = p_voice; 178 } 179 }; 180 181 Room *cull_rooms[MAX_CULL_ROOMS]; 182 183 Set<Source *> streaming_sources; 184 Set<ActiveVoice> active_voices; 185 186 void _clean_up_owner(RID_OwnerBase *p_owner, const char *p_area); 187 void _update_sources(); 188 189 public: 190 /* SPACE */ 191 virtual RID space_create(); 192 193 /* ROOM */ 194 195 virtual RID room_create(); 196 virtual void room_set_space(RID p_room, RID p_space); 197 virtual RID room_get_space(RID p_room) const; 198 199 virtual void room_set_bounds(RID p_room, const BSP_Tree &p_bounds); 200 virtual BSP_Tree room_get_bounds(RID p_room) const; 201 virtual void room_set_transform(RID p_room, const Transform &p_transform); 202 virtual Transform room_get_transform(RID p_room) const; 203 204 virtual void room_set_param(RID p_room, RoomParam p_param, float p_value); 205 virtual float room_get_param(RID p_room, RoomParam p_param) const; 206 207 virtual void room_set_level(RID p_room, int p_level); 208 virtual int room_get_level(RID p_room) const; 209 210 virtual void room_set_reverb(RID p_room, RoomReverb p_reverb); 211 virtual RoomReverb room_get_reverb(RID p_room) const; 212 213 //useful for underwater or rooms with very strange conditions 214 virtual void room_set_force_params_to_all_sources(RID p_room, bool p_force); 215 virtual bool room_is_forcing_params_to_all_sources(RID p_room) const; 216 217 /* SOURCE */ 218 219 virtual RID source_create(RID p_space); 220 221 virtual void source_set_polyphony(RID p_source, int p_voice_count); 222 virtual int source_get_polyphony(RID p_source) const; 223 224 virtual void source_set_transform(RID p_source, const Transform &p_transform); 225 virtual Transform source_get_transform(RID p_source) const; 226 227 virtual void source_set_param(RID p_source, SourceParam p_param, float p_value); 228 virtual float source_get_param(RID p_source, SourceParam p_param) const; 229 230 virtual void source_set_audio_stream(RID p_source, AudioServer::AudioStream *p_stream); //null to unset 231 virtual SourceVoiceID source_play_sample(RID p_source, RID p_sample, int p_mix_rate, int p_voice = SOURCE_NEXT_VOICE, int p_priority = 0); 232 /* VOICES */ 233 virtual void source_voice_set_pitch_scale(RID p_source, SourceVoiceID p_voice, float p_pitch_scale); 234 virtual void source_voice_set_volume_scale_db(RID p_source, SourceVoiceID p_voice, float p_volume); 235 236 virtual bool source_is_voice_active(RID p_source, SourceVoiceID p_voice) const; 237 virtual void source_stop_voice(RID p_source, SourceVoiceID p_voice); 238 239 /* LISTENER */ 240 241 virtual RID listener_create(); 242 virtual void listener_set_space(RID p_listener, RID p_space); 243 244 virtual void listener_set_transform(RID p_listener, const Transform &p_transform); 245 virtual Transform listener_get_transform(RID p_listener) const; 246 247 virtual void listener_set_param(RID p_listener, ListenerParam p_param, float p_value); 248 virtual float listener_get_param(RID p_listener, ListenerParam p_param) const; 249 250 /* MISC */ 251 252 virtual void free(RID p_id); 253 254 virtual void init(); 255 virtual void update(float p_delta); 256 virtual void finish(); 257 258 SpatialSoundServerSW(); 259 }; 260 261 #endif // SPATIAL_SOUND_SERVER_SW_H 262