audio_stream_interactive.h 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271
  1. /**************************************************************************/
  2. /* audio_stream_interactive.h */
  3. /**************************************************************************/
  4. /* This file is part of: */
  5. /* GODOT ENGINE */
  6. /* https://godotengine.org */
  7. /**************************************************************************/
  8. /* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
  9. /* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
  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 AUDIO_STREAM_INTERACTIVE_H
  31. #define AUDIO_STREAM_INTERACTIVE_H
  32. #include "servers/audio/audio_stream.h"
  33. class AudioStreamPlaybackInteractive;
  34. class AudioStreamInteractive : public AudioStream {
  35. GDCLASS(AudioStreamInteractive, AudioStream)
  36. OBJ_SAVE_TYPE(AudioStream)
  37. public:
  38. enum TransitionFromTime {
  39. TRANSITION_FROM_TIME_IMMEDIATE,
  40. TRANSITION_FROM_TIME_NEXT_BEAT,
  41. TRANSITION_FROM_TIME_NEXT_BAR,
  42. TRANSITION_FROM_TIME_END,
  43. TRANSITION_FROM_TIME_MAX
  44. };
  45. enum TransitionToTime {
  46. TRANSITION_TO_TIME_SAME_POSITION,
  47. TRANSITION_TO_TIME_START,
  48. TRANSITION_TO_TIME_PREVIOUS_POSITION,
  49. TRANSITION_TO_TIME_MAX,
  50. };
  51. enum FadeMode {
  52. FADE_DISABLED,
  53. FADE_IN,
  54. FADE_OUT,
  55. FADE_CROSS,
  56. FADE_AUTOMATIC,
  57. FADE_MAX
  58. };
  59. enum AutoAdvanceMode {
  60. AUTO_ADVANCE_DISABLED,
  61. AUTO_ADVANCE_ENABLED,
  62. AUTO_ADVANCE_RETURN_TO_HOLD,
  63. };
  64. enum {
  65. CLIP_ANY = -1
  66. };
  67. private:
  68. friend class AudioStreamPlaybackInteractive;
  69. int sample_rate = 44100;
  70. bool stereo = true;
  71. int initial_clip = 0;
  72. double time = 0;
  73. enum {
  74. MAX_CLIPS = 63, // Because we use bitmasks for transition matching.
  75. MAX_TRANSITIONS = 63,
  76. };
  77. struct Clip {
  78. StringName name;
  79. Ref<AudioStream> stream;
  80. AutoAdvanceMode auto_advance = AUTO_ADVANCE_DISABLED;
  81. int auto_advance_next_clip = 0;
  82. };
  83. Clip clips[MAX_CLIPS];
  84. struct Transition {
  85. TransitionFromTime from_time = TRANSITION_FROM_TIME_NEXT_BEAT;
  86. TransitionToTime to_time = TRANSITION_TO_TIME_START;
  87. FadeMode fade_mode = FADE_AUTOMATIC;
  88. int fade_beats = 1;
  89. bool use_filler_clip = false;
  90. int filler_clip = 0;
  91. bool hold_previous = false;
  92. };
  93. struct TransitionKey {
  94. uint32_t from_clip;
  95. uint32_t to_clip;
  96. bool operator==(const TransitionKey &p_key) const {
  97. return from_clip == p_key.from_clip && to_clip == p_key.to_clip;
  98. }
  99. TransitionKey(uint32_t p_from_clip = 0, uint32_t p_to_clip = 0) {
  100. from_clip = p_from_clip;
  101. to_clip = p_to_clip;
  102. }
  103. };
  104. struct TransitionKeyHasher {
  105. static _FORCE_INLINE_ uint32_t hash(const TransitionKey &p_key) {
  106. uint32_t h = hash_murmur3_one_32(p_key.from_clip);
  107. return hash_murmur3_one_32(p_key.to_clip, h);
  108. }
  109. };
  110. HashMap<TransitionKey, Transition, TransitionKeyHasher> transition_map;
  111. uint64_t version = 1; // Used to stop playback instances for incompatibility.
  112. int clip_count = 0;
  113. HashSet<AudioStreamPlaybackInteractive *> playbacks;
  114. #ifdef TOOLS_ENABLED
  115. mutable String stream_name_cache;
  116. String _get_streams_hint() const;
  117. PackedStringArray _get_linked_undo_properties(const String &p_property, const Variant &p_new_value) const;
  118. void _inspector_array_swap_clip(uint32_t p_item_a, uint32_t p_item_b);
  119. #endif
  120. void _set_transitions(const Dictionary &p_transitions);
  121. Dictionary _get_transitions() const;
  122. public:
  123. // CLIPS
  124. void set_clip_count(int p_count);
  125. int get_clip_count() const;
  126. void set_initial_clip(int p_clip);
  127. int get_initial_clip() const;
  128. void set_clip_name(int p_clip, const StringName &p_name);
  129. StringName get_clip_name(int p_clip) const;
  130. void set_clip_stream(int p_clip, const Ref<AudioStream> &p_stream);
  131. Ref<AudioStream> get_clip_stream(int p_clip) const;
  132. void set_clip_auto_advance(int p_clip, AutoAdvanceMode p_mode);
  133. AutoAdvanceMode get_clip_auto_advance(int p_clip) const;
  134. void set_clip_auto_advance_next_clip(int p_clip, int p_index);
  135. int get_clip_auto_advance_next_clip(int p_clip) const;
  136. // TRANSITIONS
  137. void add_transition(int p_from_clip, int p_to_clip, TransitionFromTime p_from_time, TransitionToTime p_to_time, FadeMode p_fade_mode, float p_fade_beats, bool p_use_filler_flip = false, int p_filler_clip = -1, bool p_hold_previous = false);
  138. TransitionFromTime get_transition_from_time(int p_from_clip, int p_to_clip) const;
  139. TransitionToTime get_transition_to_time(int p_from_clip, int p_to_clip) const;
  140. FadeMode get_transition_fade_mode(int p_from_clip, int p_to_clip) const;
  141. float get_transition_fade_beats(int p_from_clip, int p_to_clip) const;
  142. bool is_transition_using_filler_clip(int p_from_clip, int p_to_clip) const;
  143. int get_transition_filler_clip(int p_from_clip, int p_to_clip) const;
  144. bool is_transition_holding_previous(int p_from_clip, int p_to_clip) const;
  145. bool has_transition(int p_from_clip, int p_to_clip) const;
  146. void erase_transition(int p_from_clip, int p_to_clip);
  147. PackedInt32Array get_transition_list() const;
  148. virtual Ref<AudioStreamPlayback> instantiate_playback() override;
  149. virtual String get_stream_name() const override;
  150. virtual double get_length() const override { return 0; }
  151. AudioStreamInteractive();
  152. protected:
  153. virtual void get_parameter_list(List<Parameter> *r_parameters) override;
  154. static void _bind_methods();
  155. void _validate_property(PropertyInfo &r_property) const;
  156. };
  157. VARIANT_ENUM_CAST(AudioStreamInteractive::TransitionFromTime)
  158. VARIANT_ENUM_CAST(AudioStreamInteractive::TransitionToTime)
  159. VARIANT_ENUM_CAST(AudioStreamInteractive::AutoAdvanceMode)
  160. VARIANT_ENUM_CAST(AudioStreamInteractive::FadeMode)
  161. class AudioStreamPlaybackInteractive : public AudioStreamPlayback {
  162. GDCLASS(AudioStreamPlaybackInteractive, AudioStreamPlayback)
  163. friend class AudioStreamInteractive;
  164. private:
  165. Ref<AudioStreamInteractive> stream;
  166. uint64_t version = 0;
  167. enum {
  168. BUFFER_SIZE = 1024
  169. };
  170. AudioFrame mix_buffer[BUFFER_SIZE];
  171. AudioFrame temp_buffer[BUFFER_SIZE];
  172. struct State {
  173. Ref<AudioStream> stream;
  174. Ref<AudioStreamPlayback> playback;
  175. bool active = false;
  176. double fade_wait = 0; // Time to wait until fade kicks-in
  177. double fade_volume = 1.0;
  178. double fade_speed = 0; // Fade speed, negative or positive
  179. int auto_advance = -1;
  180. bool first_mix = true;
  181. double previous_position = 0;
  182. void reset_fade() {
  183. fade_wait = 0;
  184. fade_volume = 1.0;
  185. fade_speed = 0;
  186. }
  187. };
  188. State states[AudioStreamInteractive::MAX_CLIPS];
  189. int playback_current = -1;
  190. bool active = false;
  191. int return_memory = -1;
  192. void _mix_internal(int p_frames);
  193. void _mix_internal_state(int p_state_idx, int p_frames);
  194. void _queue(int p_to_clip_index, bool p_is_auto_advance);
  195. int switch_request = -1;
  196. protected:
  197. static void _bind_methods();
  198. public:
  199. virtual void start(double p_from_pos = 0.0) override;
  200. virtual void stop() override;
  201. virtual bool is_playing() const override;
  202. virtual int get_loop_count() const override; // times it looped
  203. virtual double get_playback_position() const override;
  204. virtual void seek(double p_time) override;
  205. virtual int mix(AudioFrame *p_buffer, float p_rate_scale, int p_frames) override;
  206. virtual void tag_used_streams() override;
  207. void switch_to_clip_by_name(const StringName &p_name);
  208. void switch_to_clip(int p_index);
  209. virtual void set_parameter(const StringName &p_name, const Variant &p_value) override;
  210. virtual Variant get_parameter(const StringName &p_name) const override;
  211. AudioStreamPlaybackInteractive();
  212. ~AudioStreamPlaybackInteractive();
  213. };
  214. #endif // AUDIO_STREAM_INTERACTIVE_H