2014-02-10 09:10:30 +08:00
/**************************************************************************/
/* audio_server.h */
/**************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/**************************************************************************/
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
2018-01-05 07:50:27 +08:00
2014-02-10 09:10:30 +08:00
# ifndef AUDIO_SERVER_H
# define AUDIO_SERVER_H
2018-09-12 00:13:45 +08:00
# include "core/math/audio_frame.h"
2020-11-08 06:33:38 +08:00
# include "core/object/class_db.h"
2018-09-12 00:13:45 +08:00
# include "core/os/os.h"
2021-08-28 01:28:23 +08:00
# include "core/templates/safe_list.h"
2020-11-08 06:33:38 +08:00
# include "core/variant/variant.h"
2017-01-16 03:06:14 +08:00
# include "servers/audio/audio_effect.h"
2021-08-28 01:28:23 +08:00
# include "servers/audio/audio_filter_sw.h"
# include <atomic>
2014-02-10 09:10:30 +08:00
2017-09-14 00:34:22 +08:00
class AudioDriverDummy ;
2024-04-18 22:50:34 +08:00
class AudioSample ;
2018-02-27 15:54:56 +08:00
class AudioStream ;
2022-07-23 22:34:36 +08:00
class AudioStreamWAV ;
2021-08-28 01:28:23 +08:00
class AudioStreamPlayback ;
2024-04-18 22:50:34 +08:00
class AudioSamplePlayback ;
2017-09-14 00:34:22 +08:00
2017-01-16 03:06:14 +08:00
class AudioDriver {
static AudioDriver * singleton ;
2022-05-02 22:28:25 +08:00
uint64_t _last_mix_time = 0 ;
uint64_t _last_mix_frames = 0 ;
2017-01-16 03:06:14 +08:00
2018-06-21 08:02:02 +08:00
# ifdef DEBUG_ENABLED
2024-02-06 11:29:44 +08:00
SafeNumeric < uint64_t > prof_ticks ;
SafeNumeric < uint64_t > prof_time ;
2018-06-21 08:02:02 +08:00
# endif
2017-01-16 03:06:14 +08:00
protected :
2020-01-20 20:11:47 +08:00
Vector < int32_t > input_buffer ;
2022-05-02 22:28:25 +08:00
unsigned int input_position = 0 ;
unsigned int input_size = 0 ;
2018-07-04 09:08:43 +08:00
2017-01-16 03:06:14 +08:00
void audio_server_process ( int p_frames , int32_t * p_buffer , bool p_update_mix_time = true ) ;
void update_mix_time ( int p_frames ) ;
2020-01-20 20:11:47 +08:00
void input_buffer_init ( int driver_buffer_frames ) ;
void input_buffer_write ( int32_t sample ) ;
2014-02-10 09:10:30 +08:00
2022-12-10 14:39:14 +08:00
int _get_configured_mix_rate ( ) ;
2018-06-21 08:02:02 +08:00
# ifdef DEBUG_ENABLED
2024-02-06 11:29:44 +08:00
_FORCE_INLINE_ void start_counting_ticks ( ) { prof_ticks . set ( OS : : get_singleton ( ) - > get_ticks_usec ( ) ) ; }
_FORCE_INLINE_ void stop_counting_ticks ( ) { prof_time . add ( OS : : get_singleton ( ) - > get_ticks_usec ( ) - prof_ticks . get ( ) ) ; }
2018-06-21 08:02:02 +08:00
# else
_FORCE_INLINE_ void start_counting_ticks ( ) { }
_FORCE_INLINE_ void stop_counting_ticks ( ) { }
# endif
2017-01-16 03:06:14 +08:00
public :
2021-01-09 09:29:49 +08:00
double get_time_since_last_mix ( ) ; //useful for video -> audio sync
double get_time_to_next_mix ( ) ;
2014-02-10 09:10:30 +08:00
2017-01-16 03:06:14 +08:00
enum SpeakerMode {
SPEAKER_MODE_STEREO ,
2017-08-23 05:27:17 +08:00
SPEAKER_SURROUND_31 ,
2017-01-16 03:06:14 +08:00
SPEAKER_SURROUND_51 ,
SPEAKER_SURROUND_71 ,
2014-02-10 09:10:30 +08:00
} ;
2017-01-16 03:06:14 +08:00
static AudioDriver * get_singleton ( ) ;
void set_singleton ( ) ;
2014-02-10 09:10:30 +08:00
2023-02-08 23:40:15 +08:00
// Virtual API to implement.
2017-01-16 03:06:14 +08:00
virtual const char * get_name ( ) const = 0 ;
2014-02-10 09:10:30 +08:00
2017-01-16 03:06:14 +08:00
virtual Error init ( ) = 0 ;
virtual void start ( ) = 0 ;
virtual int get_mix_rate ( ) const = 0 ;
2024-02-21 20:02:10 +08:00
virtual int get_input_mix_rate ( ) const { return get_mix_rate ( ) ; }
2017-01-16 03:06:14 +08:00
virtual SpeakerMode get_speaker_mode ( ) const = 0 ;
2023-02-08 23:40:15 +08:00
virtual float get_latency ( ) { return 0 ; }
2017-01-16 03:06:14 +08:00
virtual void lock ( ) = 0 ;
virtual void unlock ( ) = 0 ;
virtual void finish ( ) = 0 ;
2014-02-10 09:10:30 +08:00
2023-02-08 23:40:15 +08:00
virtual PackedStringArray get_output_device_list ( ) ;
virtual String get_output_device ( ) ;
virtual void set_output_device ( const String & p_name ) { }
virtual Error input_start ( ) { return FAILED ; }
virtual Error input_stop ( ) { return FAILED ; }
2022-11-24 22:41:40 +08:00
virtual PackedStringArray get_input_device_list ( ) ;
2023-02-08 23:40:15 +08:00
virtual String get_input_device ( ) { return " Default " ; }
virtual void set_input_device ( const String & p_name ) { }
2018-02-27 15:54:56 +08:00
2023-02-08 23:40:15 +08:00
//
2014-02-10 09:10:30 +08:00
2017-08-23 05:27:17 +08:00
SpeakerMode get_speaker_mode_by_total_channels ( int p_channels ) const ;
int get_total_channels_by_speaker_mode ( SpeakerMode ) const ;
2020-01-20 20:11:47 +08:00
Vector < int32_t > get_input_buffer ( ) { return input_buffer ; }
unsigned int get_input_position ( ) { return input_position ; }
unsigned int get_input_size ( ) { return input_size ; }
2019-10-12 06:40:43 +08:00
2018-06-21 08:02:02 +08:00
# ifdef DEBUG_ENABLED
2024-02-06 11:29:44 +08:00
uint64_t get_profiling_time ( ) const { return prof_time . get ( ) ; }
void reset_profiling_time ( ) { prof_time . set ( 0 ) ; }
2018-06-21 08:02:02 +08:00
# endif
2024-04-18 22:50:34 +08:00
// Samples handling.
virtual bool is_stream_registered_as_sample ( const Ref < AudioStream > & p_stream ) const {
return false ;
}
virtual void register_sample ( const Ref < AudioSample > & p_sample ) { }
virtual void unregister_sample ( const Ref < AudioSample > & p_sample ) { }
virtual void start_sample_playback ( const Ref < AudioSamplePlayback > & p_playback ) ;
virtual void stop_sample_playback ( const Ref < AudioSamplePlayback > & p_playback ) { }
virtual void set_sample_playback_pause ( const Ref < AudioSamplePlayback > & p_playback , bool p_paused ) { }
virtual bool is_sample_playback_active ( const Ref < AudioSamplePlayback > & p_playback ) { return false ; }
2024-08-06 21:46:37 +08:00
virtual double get_sample_playback_position ( const Ref < AudioSamplePlayback > & p_playback ) { return false ; }
2024-04-18 22:50:34 +08:00
virtual void update_sample_playback_pitch_scale ( const Ref < AudioSamplePlayback > & p_playback , float p_pitch_scale = 0.0f ) { }
virtual void set_sample_playback_bus_volumes_linear ( const Ref < AudioSamplePlayback > & p_playback , const HashMap < StringName , Vector < AudioFrame > > & p_bus_volumes ) { }
virtual void set_sample_bus_count ( int p_count ) { }
virtual void remove_sample_bus ( int p_bus ) { }
virtual void add_sample_bus ( int p_at_pos = - 1 ) { }
virtual void move_sample_bus ( int p_bus , int p_to_pos ) { }
virtual void set_sample_bus_send ( int p_bus , const StringName & p_send ) { }
virtual void set_sample_bus_volume_db ( int p_bus , float p_volume_db ) { }
virtual void set_sample_bus_solo ( int p_bus , bool p_enable ) { }
virtual void set_sample_bus_mute ( int p_bus , bool p_enable ) { }
2022-05-02 22:28:25 +08:00
AudioDriver ( ) { }
2017-01-16 03:06:14 +08:00
virtual ~ AudioDriver ( ) { }
2014-02-10 09:10:30 +08:00
} ;
2017-01-16 03:06:14 +08:00
class AudioDriverManager {
enum {
MAX_DRIVERS = 10
} ;
2014-02-10 09:10:30 +08:00
2017-01-16 03:06:14 +08:00
static AudioDriver * drivers [ MAX_DRIVERS ] ;
static int driver_count ;
2014-02-10 09:10:30 +08:00
2017-09-14 00:34:22 +08:00
static AudioDriverDummy dummy_driver ;
2017-03-05 23:44:50 +08:00
public :
2022-12-10 14:39:14 +08:00
static const int DEFAULT_MIX_RATE = 44100 ;
2017-01-16 03:06:14 +08:00
static void add_driver ( AudioDriver * p_driver ) ;
2017-09-14 00:34:22 +08:00
static void initialize ( int p_driver ) ;
2017-01-16 03:06:14 +08:00
static int get_driver_count ( ) ;
static AudioDriver * get_driver ( int p_driver ) ;
} ;
2014-02-10 09:10:30 +08:00
2017-01-26 01:30:40 +08:00
class AudioBusLayout ;
2017-01-22 06:00:25 +08:00
2017-01-16 03:06:14 +08:00
class AudioServer : public Object {
2019-03-20 02:35:57 +08:00
GDCLASS ( AudioServer , Object ) ;
2017-01-16 03:06:14 +08:00
public :
2019-05-30 19:47:18 +08:00
//re-expose this here, as AudioDriver is not exposed to script
2017-01-16 03:06:14 +08:00
enum SpeakerMode {
SPEAKER_MODE_STEREO ,
2017-08-23 05:27:17 +08:00
SPEAKER_SURROUND_31 ,
2017-01-16 03:06:14 +08:00
SPEAKER_SURROUND_51 ,
SPEAKER_SURROUND_71 ,
2014-02-10 09:10:30 +08:00
} ;
2017-01-22 06:00:25 +08:00
2024-04-18 22:50:34 +08:00
enum PlaybackType {
PLAYBACK_TYPE_DEFAULT ,
PLAYBACK_TYPE_STREAM ,
PLAYBACK_TYPE_SAMPLE ,
PLAYBACK_TYPE_MAX
} ;
2017-01-22 06:00:25 +08:00
enum {
2021-08-28 01:28:23 +08:00
AUDIO_DATA_INVALID_ID = - 1 ,
MAX_CHANNELS_PER_BUS = 4 ,
MAX_BUSES_PER_PLAYBACK = 6 ,
2021-08-28 12:51:03 +08:00
LOOKAHEAD_BUFFER_SIZE = 64 ,
2017-01-22 06:00:25 +08:00
} ;
typedef void ( * AudioCallback ) ( void * p_userdata ) ;
2017-01-16 03:06:14 +08:00
private :
2022-05-02 22:28:25 +08:00
uint64_t mix_time = 0 ;
int mix_size = 0 ;
2019-04-27 23:22:47 +08:00
2022-05-02 22:28:25 +08:00
uint32_t buffer_size = 0 ;
uint64_t mix_count = 0 ;
uint64_t mix_frames = 0 ;
2018-06-21 08:02:02 +08:00
# ifdef DEBUG_ENABLED
2024-02-06 11:29:44 +08:00
SafeNumeric < uint64_t > prof_time ;
2018-06-21 08:02:02 +08:00
# endif
2017-01-22 06:00:25 +08:00
2022-05-02 22:28:25 +08:00
float channel_disable_threshold_db = 0.0f ;
uint32_t channel_disable_frames = 0 ;
2017-01-22 06:00:25 +08:00
2022-05-02 22:28:25 +08:00
int channel_count = 0 ;
int to_mix = 0 ;
2014-02-10 09:10:30 +08:00
2022-05-02 22:28:25 +08:00
float playback_speed_scale = 1.0f ;
2019-06-03 07:01:42 +08:00
2022-07-21 07:00:58 +08:00
bool tag_used_audio_streams = false ;
2017-01-16 03:06:14 +08:00
struct Bus {
2017-01-22 06:00:25 +08:00
StringName name ;
2022-05-02 22:28:25 +08:00
bool solo = false ;
bool mute = false ;
bool bypass = false ;
2017-01-22 06:00:25 +08:00
2022-05-02 22:28:25 +08:00
bool soloed = false ;
2017-08-19 05:19:12 +08:00
2022-05-02 22:28:25 +08:00
// Each channel is a stereo pair.
2017-01-22 06:00:25 +08:00
struct Channel {
2022-05-02 22:28:25 +08:00
bool used = false ;
bool active = false ;
AudioFrame peak_volume = AudioFrame ( AUDIO_MIN_PEAK_DB , AUDIO_MIN_PEAK_DB ) ;
2017-01-22 06:00:25 +08:00
Vector < AudioFrame > buffer ;
2020-03-17 14:33:00 +08:00
Vector < Ref < AudioEffectInstance > > effect_instances ;
2022-05-02 22:28:25 +08:00
uint64_t last_mix_with_audio = 0 ;
Channel ( ) { }
2017-01-22 06:00:25 +08:00
} ;
Vector < Channel > channels ;
2017-01-16 03:06:14 +08:00
struct Effect {
Ref < AudioEffect > effect ;
2022-05-02 22:28:25 +08:00
bool enabled = false ;
2018-06-21 08:02:02 +08:00
# ifdef DEBUG_ENABLED
2022-05-02 22:28:25 +08:00
uint64_t prof_time = 0 ;
2018-06-21 08:02:02 +08:00
# endif
2017-01-16 03:06:14 +08:00
} ;
2014-02-10 09:10:30 +08:00
2017-01-16 03:06:14 +08:00
Vector < Effect > effects ;
2022-05-02 22:28:25 +08:00
float volume_db = 0.0f ;
2017-01-22 06:00:25 +08:00
StringName send ;
2022-05-02 22:28:25 +08:00
int index_cache = 0 ;
2014-02-10 09:10:30 +08:00
} ;
2021-08-28 01:28:23 +08:00
struct AudioStreamPlaybackBusDetails {
2022-05-02 22:28:25 +08:00
bool bus_active [ MAX_BUSES_PER_PLAYBACK ] = { } ;
2021-08-28 01:28:23 +08:00
StringName bus [ MAX_BUSES_PER_PLAYBACK ] ;
AudioFrame volume [ MAX_BUSES_PER_PLAYBACK ] [ MAX_CHANNELS_PER_BUS ] ;
} ;
struct AudioStreamPlaybackListNode {
2024-10-13 09:38:40 +08:00
// The state machine for audio stream playbacks is as follows:
// 1. The playback is created and added to the playback list in the playing state.
// 2. The playback is (maybe) paused, and the state is set to FADE_OUT_TO_PAUSE.
// 2.1. The playback is mixed after being paused, and the audio server thread atomically sets the state to PAUSED after performing a brief fade-out.
// 3. The playback is (maybe) deleted, and the state is set to FADE_OUT_TO_DELETION.
// 3.1. The playback is mixed after being deleted, and the audio server thread atomically sets the state to AWAITING_DELETION after performing a brief fade-out.
// NOTE: The playback is not deallocated at this time because allocation and deallocation are not realtime-safe.
// 4. The playback is removed and deallocated on the main thread using the SafeList maybe_cleanup method.
2021-08-28 01:28:23 +08:00
enum PlaybackState {
PAUSED = 0 , // Paused. Keep this stream playback around though so it can be restarted.
PLAYING = 1 , // Playing. Fading may still be necessary if volume changes!
FADE_OUT_TO_PAUSE = 2 , // About to pause.
FADE_OUT_TO_DELETION = 3 , // About to stop.
AWAITING_DELETION = 4 ,
} ;
// If zero or positive, a place in the stream to seek to during the next mix.
SafeNumeric < float > setseek ;
SafeNumeric < float > pitch_scale ;
SafeNumeric < float > highshelf_gain ;
SafeNumeric < float > attenuation_filter_cutoff_hz ; // This isn't used unless highshelf_gain is nonzero.
AudioFilterSW : : Processor filter_process [ 8 ] ;
// Updating this ref after the list node is created breaks consistency guarantees, don't do it!
Ref < AudioStreamPlayback > stream_playback ;
// Playback state determines the fate of a particular AudioStreamListNode during the mix step. Must be atomically replaced.
std : : atomic < PlaybackState > state = AWAITING_DELETION ;
// This data should only ever be modified by an atomic replacement of the pointer.
std : : atomic < AudioStreamPlaybackBusDetails * > bus_details = nullptr ;
// Previous bus details should only be accessed on the audio thread.
AudioStreamPlaybackBusDetails * prev_bus_details = nullptr ;
// The next few samples are stored here so we have some time to fade audio out if it ends abruptly at the beginning of the next mix.
AudioFrame lookahead [ LOOKAHEAD_BUFFER_SIZE ] ;
} ;
SafeList < AudioStreamPlaybackListNode * > playback_list ;
SafeList < AudioStreamPlaybackBusDetails * > bus_details_graveyard ;
2024-09-05 00:04:27 +08:00
void _delete_stream_playback ( Ref < AudioStreamPlayback > p_playback ) ;
void _delete_stream_playback_list_node ( AudioStreamPlaybackListNode * p_node ) ;
2021-08-28 01:28:23 +08:00
2021-08-28 12:51:03 +08:00
// TODO document if this is necessary.
SafeList < AudioStreamPlaybackBusDetails * > bus_details_graveyard_frame_old ;
2020-03-17 14:33:00 +08:00
Vector < Vector < AudioFrame > > temp_buffer ; //temp_buffer for each level
2021-08-28 01:28:23 +08:00
Vector < AudioFrame > mix_buffer ;
2017-01-22 06:00:25 +08:00
Vector < Bus * > buses ;
2022-05-13 21:04:37 +08:00
HashMap < StringName , Bus * > bus_map ;
2014-02-10 09:10:30 +08:00
2017-01-22 06:00:25 +08:00
void _update_bus_effects ( int p_bus ) ;
2014-02-10 09:10:30 +08:00
2017-01-16 03:06:14 +08:00
static AudioServer * singleton ;
2017-01-22 06:00:25 +08:00
2018-03-18 09:43:32 +08:00
void init_channels_and_buffers ( ) ;
2017-01-22 06:00:25 +08:00
void _mix_step ( ) ;
2021-08-28 01:28:23 +08:00
void _mix_step_for_channel ( AudioFrame * p_out_buf , AudioFrame * p_source_buf , AudioFrame p_vol_start , AudioFrame p_vol_final , float p_attenuation_filter_cutoff_hz , float p_highshelf_gain , AudioFilterSW : : Processor * p_processor_l , AudioFilterSW : : Processor * p_processor_r ) ;
// Should only be called on the main thread.
AudioStreamPlaybackListNode * _find_playback_list_node ( Ref < AudioStreamPlayback > p_playback ) ;
2017-01-22 06:00:25 +08:00
struct CallbackItem {
AudioCallback callback ;
2022-04-04 21:06:57 +08:00
void * userdata = nullptr ;
2017-01-22 06:00:25 +08:00
} ;
2021-08-28 01:28:23 +08:00
SafeList < CallbackItem * > update_callback_list ;
SafeList < CallbackItem * > mix_callback_list ;
SafeList < CallbackItem * > listener_changed_callback_list ;
2017-01-22 06:00:25 +08:00
friend class AudioDriver ;
void _driver_process ( int p_frames , int32_t * p_buffer ) ;
2024-07-26 21:56:44 +08:00
LocalVector < Ref < AudioSamplePlayback > > sample_playback_list ;
2024-07-12 22:49:59 +08:00
2017-01-22 06:00:25 +08:00
protected :
static void _bind_methods ( ) ;
2014-02-10 09:10:30 +08:00
2017-03-05 23:44:50 +08:00
public :
2017-08-23 05:27:17 +08:00
_FORCE_INLINE_ int get_channel_count ( ) const {
switch ( get_speaker_mode ( ) ) {
2020-05-10 19:00:47 +08:00
case SPEAKER_MODE_STEREO :
return 1 ;
case SPEAKER_SURROUND_31 :
return 2 ;
case SPEAKER_SURROUND_51 :
return 3 ;
case SPEAKER_SURROUND_71 :
return 4 ;
2017-08-23 05:27:17 +08:00
}
ERR_FAIL_V ( 1 ) ;
}
2022-05-02 22:28:25 +08:00
// Do not use from outside audio thread.
2018-11-14 05:16:33 +08:00
bool thread_has_channel_mix_buffer ( int p_bus , int p_buffer ) const ;
2017-01-22 06:00:25 +08:00
AudioFrame * thread_get_channel_mix_buffer ( int p_bus , int p_buffer ) ;
int thread_get_mix_buffer_size ( ) const ;
int thread_find_bus_index ( const StringName & p_name ) ;
2014-02-10 09:10:30 +08:00
2017-01-16 03:06:14 +08:00
void set_bus_count ( int p_count ) ;
int get_bus_count ( ) const ;
2014-02-10 09:10:30 +08:00
2017-01-24 10:12:08 +08:00
void remove_bus ( int p_index ) ;
void add_bus ( int p_at_pos = - 1 ) ;
void move_bus ( int p_bus , int p_to_pos ) ;
2017-01-16 03:06:14 +08:00
void set_bus_name ( int p_bus , const String & p_name ) ;
String get_bus_name ( int p_bus ) const ;
2017-07-11 04:51:29 +08:00
int get_bus_index ( const StringName & p_bus_name ) const ;
2014-02-10 09:10:30 +08:00
2018-12-08 00:38:40 +08:00
int get_bus_channels ( int p_bus ) const ;
2017-01-16 03:06:14 +08:00
void set_bus_volume_db ( int p_bus , float p_volume_db ) ;
float get_bus_volume_db ( int p_bus ) const ;
2014-02-10 09:10:30 +08:00
2017-01-22 06:00:25 +08:00
void set_bus_send ( int p_bus , const StringName & p_send ) ;
StringName get_bus_send ( int p_bus ) const ;
void set_bus_solo ( int p_bus , bool p_enable ) ;
bool is_bus_solo ( int p_bus ) const ;
void set_bus_mute ( int p_bus , bool p_enable ) ;
bool is_bus_mute ( int p_bus ) const ;
void set_bus_bypass_effects ( int p_bus , bool p_enable ) ;
bool is_bus_bypassing_effects ( int p_bus ) const ;
2017-01-16 03:06:14 +08:00
void add_bus_effect ( int p_bus , const Ref < AudioEffect > & p_effect , int p_at_pos = - 1 ) ;
void remove_bus_effect ( int p_bus , int p_effect ) ;
2014-02-10 09:10:30 +08:00
2017-01-16 03:06:14 +08:00
int get_bus_effect_count ( int p_bus ) ;
Ref < AudioEffect > get_bus_effect ( int p_bus , int p_effect ) ;
2019-04-10 23:57:03 +08:00
Ref < AudioEffectInstance > get_bus_effect_instance ( int p_bus , int p_effect , int p_channel = 0 ) ;
2014-02-10 09:10:30 +08:00
2017-01-16 03:06:14 +08:00
void swap_bus_effects ( int p_bus , int p_effect , int p_by_effect ) ;
2014-02-10 09:10:30 +08:00
2017-01-16 03:06:14 +08:00
void set_bus_effect_enabled ( int p_bus , int p_effect , bool p_enabled ) ;
bool is_bus_effect_enabled ( int p_bus , int p_effect ) const ;
2014-02-10 09:10:30 +08:00
2017-01-22 06:00:25 +08:00
float get_bus_peak_volume_left_db ( int p_bus , int p_channel ) const ;
float get_bus_peak_volume_right_db ( int p_bus , int p_channel ) const ;
bool is_bus_channel_active ( int p_bus , int p_channel ) const ;
2020-05-08 00:46:33 +08:00
void set_playback_speed_scale ( float p_scale ) ;
float get_playback_speed_scale ( ) const ;
2019-06-03 07:01:42 +08:00
2021-08-28 12:51:03 +08:00
// Convenience method.
2021-08-02 03:47:20 +08:00
void start_playback_stream ( Ref < AudioStreamPlayback > p_playback , const StringName & p_bus , Vector < AudioFrame > p_volume_db_vector , float p_start_time = 0 , float p_pitch_scale = 1 ) ;
2021-08-28 12:51:03 +08:00
// Expose all parameters.
2021-08-02 03:47:20 +08:00
void start_playback_stream ( Ref < AudioStreamPlayback > p_playback , const HashMap < StringName , Vector < AudioFrame > > & p_bus_volumes , float p_start_time = 0 , float p_pitch_scale = 1 , float p_highshelf_gain = 0 , float p_attenuation_cutoff_hz = 0 ) ;
2021-08-28 01:28:23 +08:00
void stop_playback_stream ( Ref < AudioStreamPlayback > p_playback ) ;
2021-08-02 03:47:20 +08:00
void set_playback_bus_exclusive ( Ref < AudioStreamPlayback > p_playback , const StringName & p_bus , Vector < AudioFrame > p_volumes ) ;
void set_playback_bus_volumes_linear ( Ref < AudioStreamPlayback > p_playback , const HashMap < StringName , Vector < AudioFrame > > & p_bus_volumes ) ;
2021-08-28 01:28:23 +08:00
void set_playback_all_bus_volumes_linear ( Ref < AudioStreamPlayback > p_playback , Vector < AudioFrame > p_volumes ) ;
void set_playback_pitch_scale ( Ref < AudioStreamPlayback > p_playback , float p_pitch_scale ) ;
void set_playback_paused ( Ref < AudioStreamPlayback > p_playback , bool p_paused ) ;
void set_playback_highshelf_params ( Ref < AudioStreamPlayback > p_playback , float p_gain , float p_attenuation_cutoff_hz ) ;
bool is_playback_active ( Ref < AudioStreamPlayback > p_playback ) ;
float get_playback_position ( Ref < AudioStreamPlayback > p_playback ) ;
bool is_playback_paused ( Ref < AudioStreamPlayback > p_playback ) ;
uint64_t get_mix_count ( ) const ;
2022-07-21 07:00:58 +08:00
uint64_t get_mixed_frames ( ) const ;
2021-08-28 01:28:23 +08:00
2024-10-23 05:14:59 +08:00
String get_driver_name ( ) const ;
2021-08-28 01:28:23 +08:00
void notify_listener_changed ( ) ;
2017-01-16 03:06:14 +08:00
virtual void init ( ) ;
virtual void finish ( ) ;
2018-06-21 08:02:02 +08:00
virtual void update ( ) ;
2017-01-26 01:30:40 +08:00
virtual void load_default_bus_layout ( ) ;
2014-02-10 09:10:30 +08:00
/* MISC config */
2017-01-16 03:06:14 +08:00
virtual void lock ( ) ;
virtual void unlock ( ) ;
2014-02-10 09:10:30 +08:00
2017-01-16 03:06:14 +08:00
virtual SpeakerMode get_speaker_mode ( ) const ;
virtual float get_mix_rate ( ) const ;
2024-02-21 20:02:10 +08:00
virtual float get_input_mix_rate ( ) const ;
2014-02-10 09:10:30 +08:00
2017-01-16 03:06:14 +08:00
virtual float read_output_peak_db ( ) const ;
2014-02-10 09:10:30 +08:00
static AudioServer * get_singleton ( ) ;
2019-04-27 23:22:47 +08:00
virtual double get_output_latency ( ) const ;
virtual double get_time_to_next_mix ( ) const ;
2019-04-28 01:05:16 +08:00
virtual double get_time_since_last_mix ( ) const ;
2014-02-10 09:10:30 +08:00
2021-08-28 01:28:23 +08:00
void add_listener_changed_callback ( AudioCallback p_callback , void * p_userdata ) ;
void remove_listener_changed_callback ( AudioCallback p_callback , void * p_userdata ) ;
2017-01-22 06:00:25 +08:00
2018-10-10 21:58:29 +08:00
void add_update_callback ( AudioCallback p_callback , void * p_userdata ) ;
void remove_update_callback ( AudioCallback p_callback , void * p_userdata ) ;
2021-08-28 01:28:23 +08:00
void add_mix_callback ( AudioCallback p_callback , void * p_userdata ) ;
void remove_mix_callback ( AudioCallback p_callback , void * p_userdata ) ;
2017-03-13 23:45:27 +08:00
void set_bus_layout ( const Ref < AudioBusLayout > & p_bus_layout ) ;
2017-01-26 01:30:40 +08:00
Ref < AudioBusLayout > generate_bus_layout ( ) const ;
2022-11-24 22:41:40 +08:00
PackedStringArray get_output_device_list ( ) ;
String get_output_device ( ) ;
2023-02-08 23:40:15 +08:00
void set_output_device ( const String & p_name ) ;
2018-03-25 11:43:51 +08:00
2022-11-24 22:41:40 +08:00
PackedStringArray get_input_device_list ( ) ;
String get_input_device ( ) ;
void set_input_device ( const String & p_name ) ;
2018-07-17 09:43:47 +08:00
2022-07-21 07:00:58 +08:00
void set_enable_tagging_used_audio_streams ( bool p_enable ) ;
2024-01-04 07:20:55 +08:00
# ifdef TOOLS_ENABLED
virtual void get_argument_options ( const StringName & p_function , int p_idx , List < String > * r_options ) const override ;
# endif
2024-04-18 22:50:34 +08:00
PlaybackType get_default_playback_type ( ) const ;
bool is_stream_registered_as_sample ( const Ref < AudioStream > & p_stream ) ;
void register_stream_as_sample ( const Ref < AudioStream > & p_stream ) ;
void unregister_stream_as_sample ( const Ref < AudioStream > & p_stream ) ;
void register_sample ( const Ref < AudioSample > & p_sample ) ;
void unregister_sample ( const Ref < AudioSample > & p_sample ) ;
void start_sample_playback ( const Ref < AudioSamplePlayback > & p_playback ) ;
void stop_sample_playback ( const Ref < AudioSamplePlayback > & p_playback ) ;
void set_sample_playback_pause ( const Ref < AudioSamplePlayback > & p_playback , bool p_paused ) ;
bool is_sample_playback_active ( const Ref < AudioSamplePlayback > & p_playback ) ;
2024-08-06 21:46:37 +08:00
double get_sample_playback_position ( const Ref < AudioSamplePlayback > & p_playback ) ;
2024-04-18 22:50:34 +08:00
void update_sample_playback_pitch_scale ( const Ref < AudioSamplePlayback > & p_playback , float p_pitch_scale = 0.0f ) ;
2014-02-10 09:10:30 +08:00
AudioServer ( ) ;
virtual ~ AudioServer ( ) ;
} ;
2017-01-16 03:06:14 +08:00
VARIANT_ENUM_CAST ( AudioServer : : SpeakerMode )
2024-04-18 22:50:34 +08:00
VARIANT_ENUM_CAST ( AudioServer : : PlaybackType )
2014-02-10 09:10:30 +08:00
2017-01-26 01:30:40 +08:00
class AudioBusLayout : public Resource {
2019-03-20 02:35:57 +08:00
GDCLASS ( AudioBusLayout , Resource ) ;
2017-01-26 01:30:40 +08:00
friend class AudioServer ;
struct Bus {
StringName name ;
2022-05-02 22:28:25 +08:00
bool solo = false ;
bool mute = false ;
bool bypass = false ;
2017-01-26 01:30:40 +08:00
struct Effect {
Ref < AudioEffect > effect ;
2022-05-02 22:28:25 +08:00
bool enabled = false ;
2017-01-26 01:30:40 +08:00
} ;
Vector < Effect > effects ;
2022-05-02 22:28:25 +08:00
float volume_db = 0.0f ;
2017-01-26 01:30:40 +08:00
StringName send ;
2022-05-02 22:28:25 +08:00
Bus ( ) { }
2017-01-26 01:30:40 +08:00
} ;
Vector < Bus > buses ;
protected :
bool _set ( const StringName & p_name , const Variant & p_value ) ;
bool _get ( const StringName & p_name , Variant & r_ret ) const ;
void _get_property_list ( List < PropertyInfo > * p_list ) const ;
public :
AudioBusLayout ( ) ;
} ;
2014-02-10 09:10:30 +08:00
typedef AudioServer AS ;
# endif // AUDIO_SERVER_H