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