move explicit bezier to vg
[vg.git] / vg_audio.h
1 /* Copyright (C) 2021-2024 Harry Godden (hgn) - All Rights Reserved */
2
3 #pragma once
4
5 #include "vg_platform.h"
6 #include "vg_engine.h"
7 #include "vg_string.h"
8 #include "vg_vorbis.h"
9
10 #define AUDIO_FRAME_SIZE 512
11 #define AUDIO_MIX_FRAME_SIZE 256
12
13 #define AUDIO_CHANNELS 32
14 #define AUDIO_LFOS 8
15 #define AUDIO_FILTERS 16
16 #define AUDIO_FLAG_LOOP 0x1
17 #define AUDIO_FLAG_NO_DOPPLER 0x2
18 #define AUDIO_FLAG_SPACIAL_3D 0x4
19 #define AUDIO_FLAG_AUTO_START 0x8
20 #define AUDIO_FLAG_NO_DSP 0x10
21 #define AUDIO_FLAG_FORMAT 0x1E00
22
23 enum audio_format
24 {
25 k_audio_format_mono = 0x000u,
26 k_audio_format_stereo = 0x200u,
27 k_audio_format_vorbis = 0x400u,
28 k_audio_format_none0 = 0x600u,
29 k_audio_format_none1 = 0x800u,
30 k_audio_format_none2 = 0xA00u,
31 k_audio_format_none3 = 0xC00u,
32 k_audio_format_none4 = 0xE00u,
33
34 k_audio_format_bird = 0x1000u,
35 k_audio_format_gen = 0x1200u,
36 k_audio_format_none6 = 0x1400u,
37 k_audio_format_none7 = 0x1600u,
38 k_audio_format_none8 = 0x1800u,
39 k_audio_format_none9 = 0x1A00u,
40 k_audio_format_none10 = 0x1C00u,
41 k_audio_format_none11 = 0x1E00u,
42 };
43
44 #define AUDIO_DECODE_SIZE (1024*256) /* 256 kb decoding buffers */
45 #define AUDIO_MUTE_VOLUME 0.0f
46 #define AUDIO_BASE_VOLUME 1.0f
47
48 typedef struct audio_clip audio_clip;
49 typedef struct audio_channel audio_channel;
50 typedef struct audio_lfo audio_lfo;
51
52 struct audio_clip
53 {
54 union
55 {
56 const char *path;
57 void *func;
58
59 u64 _p64_; /* force width to be 64 because we save this structure on
60 disk in Skaterift yay */
61 };
62
63 u32 flags;
64 u32 size;
65
66 union
67 {
68 void *data;
69
70 u64 _p64;
71 };
72 };
73
74 struct vg_audio_system
75 {
76 SDL_AudioDeviceID sdl_output_device;
77 vg_str device_choice; /* buffer is null? use default from OS */
78
79 bool always_keep_compressed;
80
81 void *audio_pool,
82 *decode_buffer;
83 u32 samples_last;
84
85 /* synchro */
86 int sync_locked;
87
88 SDL_SpinLock sl_checker,
89 sl_sync;
90
91 struct audio_lfo{
92 u32 time, time_startframe;
93 float sqrt_polynomial_coefficient;
94
95 struct{
96 enum lfo_wave_type{
97 k_lfo_triangle,
98 k_lfo_square,
99 k_lfo_saw,
100 k_lfo_polynomial_bipolar
101 }
102 wave_type;
103
104 u32 period;
105 float polynomial_coefficient;
106 }
107 _, editable_state;
108 u32 editble_state_write_mask;
109 }
110 oscillators[ AUDIO_LFOS ];
111
112 struct audio_channel{
113 int allocated;
114 u16 group;
115 u8 world_id;
116
117 char name[32]; /* only editable while allocated == 0 */
118 audio_clip *source; /* ... */
119 u32 flags; /* ... */
120 u32 colour; /* ... */
121
122 /* internal non-readable state
123 * -----------------------------*/
124 u32 cursor, source_length;
125
126 float volume_movement_start,
127 pan_movement_start;
128
129 u32 volume_movement,
130 pan_movement;
131
132 union{
133 struct synth_bird *bird;
134 stb_vorbis *vorbis;
135 }
136 handle;
137
138 stb_vorbis_alloc vorbis_alloc;
139
140 enum channel_activity{
141 k_channel_activity_reset, /* will advance if allocated==1, to wake */
142 k_channel_activity_wake, /* will advance to either of next two */
143 k_channel_activity_alive,
144 k_channel_activity_end,
145 k_channel_activity_error
146 }
147 activity,
148 readable_activity;
149
150 /*
151 * editable structure, can be modified inside _lock and _unlock
152 * the edit mask tells which to copy into internal _, or to discard
153 * ----------------------------------------------------------------------
154 */
155 struct channel_state{
156 int relinquished;
157
158 float volume, /* current volume */
159 volume_target, /* target volume */
160 pan,
161 pan_target,
162 sampling_rate;
163
164 u32 volume_rate,
165 pan_rate;
166
167 v4f spacial_falloff; /* xyz, range */
168
169 audio_lfo *lfo;
170 float lfo_amount;
171 }
172 _, editable_state;
173 u32 editble_state_write_mask;
174 }
175 channels[ AUDIO_CHANNELS ];
176
177 bool inspector_open;
178 int dsp_enabled;
179
180 v3f internal_listener_pos,
181 internal_listener_ears,
182 internal_listener_velocity,
183
184 external_listener_pos,
185 external_listener_ears,
186 external_lister_velocity;
187
188 float internal_global_volume,
189 external_global_volume;
190 }
191 extern vg_audio;
192
193 void audio_clip_load( audio_clip *clip, void *lin_alloc );
194 void audio_clip_loadn( audio_clip *arr, int count, void *lin_alloc );
195
196 void vg_audio_register(void);
197 void vg_audio_device_init(void);
198 void vg_audio_init(void);
199 void vg_audio_free(void);
200
201 void audio_lock(void);
202 void audio_unlock(void);
203
204 void audio_channel_init( audio_channel *ch, audio_clip *clip, u32 flags );
205 void audio_channel_group( audio_channel *ch, u16 group );
206 void audio_channel_world( audio_channel *ch, u8 world_id );
207 audio_channel *audio_get_first_idle_channel(void);
208 audio_channel *audio_get_group_idle_channel( u16 group, u32 max_count );
209 audio_channel *audio_get_group_first_active_channel( u16 group );
210 int audio_channel_finished( audio_channel *ch );
211 audio_channel *audio_relinquish_channel( audio_channel *ch );
212 void audio_channel_slope_volume( audio_channel *ch, f32 length, f32 new_vol );
213 void audio_channel_set_sampling_rate( audio_channel *ch, float rate );
214 void audio_channel_edit_volume( audio_channel *ch, f32 new_vol, int instant );
215 audio_channel *audio_channel_fadeout( audio_channel *ch, float length );
216 void audio_channel_fadein( audio_channel *ch, float length );
217 audio_channel *audio_channel_crossfade( audio_channel *ch,
218 audio_clip *new_clip,
219 float length, u32 flags );
220 void audio_channel_sidechain_lfo( audio_channel *ch, int lfo_id, f32 amount );
221 void audio_channel_set_spacial( audio_channel *ch, v3f co, float range );
222 int audio_oneshot_3d( audio_clip *clip, v3f position, f32 range, f32 volume );
223 int audio_oneshot( audio_clip *clip, f32 volume, f32 pan );
224 void audio_set_lfo_wave( int id, enum lfo_wave_type type, f32 coefficient );
225 void audio_set_lfo_frequency( int id, float freq );
226 int audio_channel_load_source( audio_channel *ch );