1 /* ScummVM - Graphic Adventure Engine 2 * 3 * ScummVM is the legal property of its developers, whose names 4 * are too numerous to list here. Please refer to the COPYRIGHT 5 * file distributed with this source distribution. 6 * 7 * This program is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public License 9 * as published by the Free Software Foundation; either version 2 10 * of the License, or (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 20 * 21 */ 22 23 #ifndef AGS_ENGINE_MEDIA_AUDIO_AUDIO_H 24 #define AGS_ENGINE_MEDIA_AUDIO_AUDIO_H 25 26 #include "ags/lib/std/array.h" 27 #include "ags/engine/media/audio/audio_defines.h" 28 #include "ags/shared/ac/dynobj/script_audio_clip.h" 29 #include "ags/engine/ac/dynobj/script_audio_channel.h" 30 #include "ags/engine/media/audio/ambient_sound.h" 31 #include "ags/engine/util/mutex.h" 32 #include "ags/engine/util/mutex_lock.h" 33 #include "ags/engine/ac/timer.h" 34 35 namespace AGS3 { 36 37 struct SOUNDCLIP; 38 39 //controls access to the channels, since that's the main point of synchronization between the streaming thread and the user code 40 //this is going to be dependent on the underlying mutexes being recursive 41 //yes, we will have more recursive traffic on mutexes than we need 42 //however this should mostly be happening only when playing sounds, and possibly when sounds numbering only several 43 //the load should not be high 44 class AudioChannelsLock : public AGS::Engine::MutexLock { 45 private: 46 AudioChannelsLock(AudioChannelsLock const &); // non-copyable 47 AudioChannelsLock &operator=(AudioChannelsLock const &); // not copy-assignable 48 49 public: 50 AudioChannelsLock(); 51 52 // Gets a clip from the channel 53 SOUNDCLIP *GetChannel(int index); 54 // Gets a clip from the channel but only if it's in playback state 55 SOUNDCLIP *GetChannelIfPlaying(int index); 56 // Assign new clip to the channel 57 SOUNDCLIP *SetChannel(int index, SOUNDCLIP *clip); 58 // Move clip from one channel to another, clearing the first channel 59 SOUNDCLIP *MoveChannel(int to, int from); 60 }; 61 62 // 63 // Channel helpers, autolock and perform a simple action on a channel. 64 // 65 // Tells if channel has got a clip; does not care about its state 66 bool channel_has_clip(int chanid); 67 // Tells if channel has got a clip and clip is in playback state 68 bool channel_is_playing(int chanid); 69 // Sets new clip to the channel 70 void set_clip_to_channel(int chanid, SOUNDCLIP *clip); 71 72 73 void calculate_reserved_channel_count(); 74 void update_clip_default_volume(ScriptAudioClip *audioClip); 75 void start_fading_in_new_track_if_applicable(int fadeInChannel, ScriptAudioClip *newSound); 76 void stop_or_fade_out_channel(int fadeOutChannel, int fadeInChannel = -1, ScriptAudioClip *newSound = nullptr); 77 SOUNDCLIP *load_sound_clip(ScriptAudioClip *audioClip, bool repeat); 78 ScriptAudioChannel *play_audio_clip_on_channel(int channel, ScriptAudioClip *clip, int priority, int repeat, int fromOffset, SOUNDCLIP *cachedClip = nullptr); 79 void remove_clips_of_type_from_queue(int audioType); 80 void update_queued_clips_volume(int audioType, int new_vol); 81 // Checks if speech voice-over is currently playing, and reapply volume drop to all other active clips 82 void update_volume_drop_if_voiceover(); 83 ScriptAudioChannel *play_audio_clip(ScriptAudioClip *clip, int priority, int repeat, int fromOffset, bool queueIfNoChannel); 84 ScriptAudioChannel *play_audio_clip_by_index(int audioClipIndex); 85 void stop_and_destroy_channel_ex(int chid, bool resetLegacyMusicSettings); 86 void stop_and_destroy_channel(int chid); 87 88 // ***** BACKWARDS COMPATIBILITY WITH OLD AUDIO SYSTEM ***** // 89 int get_old_style_number_for_sound(int sound_number); 90 SOUNDCLIP *load_sound_clip_from_old_style_number(bool isMusic, int indexNumber, bool repeat); 91 92 //============================================================================= 93 94 int get_volume_adjusted_for_distance(int volume, int sndX, int sndY, int sndMaxDist); 95 void update_directional_sound_vol(); 96 void update_ambient_sound_vol(); 97 // Tells if the audio type is allowed to play with regards to current sound config 98 bool is_audiotype_allowed_to_play(AudioFileType type); 99 // Loads sound data referenced by audio clip item, and starts playback; 100 // returns NULL on failure 101 SOUNDCLIP *load_sound_and_play(ScriptAudioClip *aclip, bool repeat); 102 void stop_all_sound_and_music(); 103 void shutdown_sound(); 104 int play_sound(int val1); 105 106 //============================================================================= 107 108 void clear_music_cache(); 109 void play_next_queued(); 110 int calculate_max_volume(); 111 // add/remove the volume drop to the audio channels while speech is playing 112 void apply_volume_drop_modifier(bool applyModifier); 113 // Update the music, and advance the crossfade on a step 114 // (this should only be called once per game loop); 115 void update_audio_system_on_game_loop(); 116 void stopmusic(); 117 void update_music_volume(); 118 void post_new_music_check(int newchannel); 119 // Sets up the crossfading for playing the new music track, 120 // and returns the channel number to use; the channel is guaranteed to be free 121 int prepare_for_new_music(); 122 // Gets audio clip from legacy music number, which also may contain queue flag 123 ScriptAudioClip *get_audio_clip_for_music(int mnum); 124 SOUNDCLIP *load_music_from_disk(int mnum, bool doRepeat); 125 void newmusic(int mnum); 126 127 extern void cancel_scheduled_music_update(); 128 extern void schedule_music_update_at(AGS_Clock::time_point); 129 extern void postpone_scheduled_music_update_by(std::chrono::milliseconds); 130 131 } // namespace AGS3 132 133 #endif 134