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