12 u8
*view_texture_buffer
;
15 float echo_distances
[14],
22 static float *dsp_allocate( u32 samples
)
24 samples
= vg_align4( samples
);
26 if( vg_dsp
.allocations
+ samples
> (1024*1024)/4 )
27 vg_fatal_error( "too much dsp" );
29 float *buf
= &vg_dsp
.buffer
[ vg_dsp
.allocations
];
30 vg_dsp
.allocations
+= samples
;
38 * ----------------------------------------------
59 static inline void dsp_read_delay( struct dsp_delay
*delay
, float *s
)
61 u32 index
= delay
->cur
+1;
63 if( index
>= delay
->length
)
66 *s
= delay
->buffer
[ index
];
69 static inline void dsp_write_delay( struct dsp_delay
*delay
, float *s
)
71 u32 index
= delay
->cur
;
72 delay
->buffer
[ index
] = *s
;
76 if( delay
->cur
>= delay
->length
)
80 static void dsp_init_delay( struct dsp_delay
*delay
, float length
)
82 delay
->length
= 44100.0f
* length
;
84 delay
->buffer
= dsp_allocate( delay
->length
);
86 for( int i
=0; i
<delay
->length
; i
++ )
87 delay
->buffer
[i
] = 0.0f
;
90 static void dsp_update_lpf( struct dsp_lpf
*lpf
, float freq
)
92 lpf
->exponent
= 1.0f
-expf( -(1.0f
/44100.0f
) * 2.0f
* VG_PIf
* freq
);
95 static void dsp_init_lpf( struct dsp_lpf
*lpf
, float freq
)
97 lpf
->buffer
= dsp_allocate( 4 );
98 lpf
->buffer
[0] = 0.0f
;
99 dsp_update_lpf( lpf
, freq
);
102 static inline void dsp_write_lpf( struct dsp_lpf
*lpf
, float *s
)
104 float diff
= *s
- lpf
->buffer
[0];
105 lpf
->buffer
[0] += diff
* lpf
->exponent
;
108 static inline void dsp_read_lpf( struct dsp_lpf
*lpf
, float *s
)
113 static void dsp_init_schroeder( struct dsp_schroeder
*sch
, float length
,
116 dsp_init_delay( &sch
->M
, length
);
120 static inline void dsp_process_schroeder( struct dsp_schroeder
*sch
,
121 float *input
, float *output
)
126 dsp_read_delay( &sch
->M
, &delay_output
);
128 float feedback_attenuated
= delay_output
* sch
->gain
,
129 input_feedback_sum
= dry
+ feedback_attenuated
;
131 dsp_write_delay( &sch
->M
, &input_feedback_sum
);
133 *output
= delay_output
- input_feedback_sum
*sch
->gain
;
136 /* temporary global design */
137 static struct dsp_lpf __lpf_mud_free
;
138 static struct dsp_delay __echos
[8];
139 static struct dsp_lpf __echos_lpf
[8];
140 static struct dsp_schroeder __diffusion_chain
[8];
142 static void async_vg_dsp_alloc_texture( void *payload
, u32 size
)
144 glGenTextures( 1, &vg_dsp
.view_texture
);
145 glBindTexture( GL_TEXTURE_2D
, vg_dsp
.view_texture
);
146 glTexImage2D( GL_TEXTURE_2D
, 0, GL_RGBA
, 256, 256, 0,
147 GL_RGBA
, GL_UNSIGNED_BYTE
, vg_dsp
.view_texture_buffer
);
148 glTexParameteri( GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
, GL_NEAREST
);
149 glTexParameteri( GL_TEXTURE_2D
, GL_TEXTURE_MAG_FILTER
, GL_NEAREST
);
152 static void vg_dsp_init( void )
154 vg_dsp
.buffer
= vg_linear_alloc( vg_mem
.rtmemory
, 1024*1024*1 );
155 vg_dsp
.view_texture_buffer
= vg_linear_alloc( vg_mem
.rtmemory
, 512*512 );
157 vg_async_item
*call
= vg_async_alloc(0);
158 vg_async_dispatch( call
, async_vg_dsp_alloc_texture
);
160 /* temporary global design */
161 dsp_init_lpf( &__lpf_mud_free
, 125.0f
);
164 { 2.0f
, 4.0f
, 8.0f
, 16.0f
, 32.0f
, 64.0f
, 128.0f
, 256.0f
};
166 float reflection_variance
= 0.1f
;
168 for( int i
=0; i
<8; i
++ ){
169 float reflection_time
= ((sizes
[i
])/343.0f
) * 1000.0f
;
171 float var
= 1.0f
+ (vg_randf()*2.0f
- 1.0f
) * reflection_variance
,
172 total
= reflection_time
* var
;
174 dsp_init_delay( &__echos
[i
], total
/ 1000.0f
);
176 float freq
= vg_lerpf( 800.0f
, 350.0f
, sizes
[i
] / 256.0f
);
177 dsp_init_lpf( &__echos_lpf
[i
], freq
);
180 float diffusions
[] = { 187.0f
, 159.0f
, 143.0f
, 121.0f
,
181 79.0f
, 57.0f
, 27.0f
, 11.0f
};
183 for( int i
=0; i
<8; i
++ ){
184 dsp_init_schroeder( __diffusion_chain
+i
, diffusions
[i
]/1000.0f
, 0.7f
);
188 static void vg_dsp_process( float *stereo_in
, float *stereo_out
)
190 float in_total
= (stereo_in
[0]+stereo_in
[1])*0.5f
;
191 float recieved
= 0.0f
;
193 for( int i
=0; i
<8; i
++ ){
195 dsp_read_delay( __echos
+i
, &echo
);
196 dsp_write_lpf( __echos_lpf
+i
, &echo
);
197 dsp_read_lpf( __echos_lpf
+i
, &echo
);
199 recieved
+= echo
* vg_dsp
.echo_tunings
[i
]*0.98;
202 float diffused
= recieved
;
204 for( int i
=0; i
<8; i
++ ){
205 dsp_process_schroeder( __diffusion_chain
+i
, &diffused
, &diffused
);
208 float diffuse_mix
= vg_dsp
.reverb_wet_mix
;
209 diffuse_mix
= vg_lerpf( recieved
, diffused
, diffuse_mix
);
210 float total
= in_total
+ diffuse_mix
;
213 dsp_write_lpf( &__lpf_mud_free
, &total
);
214 dsp_read_lpf( &__lpf_mud_free
, &low_mud
);
218 for( int i
=0; i
<8; i
++ )
219 dsp_write_delay( __echos
+i
, &total
);
221 stereo_out
[0] = stereo_in
[0]*vg_dsp
.reverb_dry_mix
;
222 stereo_out
[1] = stereo_in
[1]*vg_dsp
.reverb_dry_mix
;
223 stereo_out
[0] += diffuse_mix
*2.0f
*vg_dsp
.reverb_wet_mix
;
224 stereo_out
[1] += diffuse_mix
*2.0f
*vg_dsp
.reverb_wet_mix
;
227 static void dsp_update_tunings(void)
230 { 2.0f
, 4.0f
, 8.0f
, 16.0f
, 32.0f
, 64.0f
, 128.0f
, 256.0f
};
232 { 0.2f
, 0.3f
, 0.5f
, 0.7f
, 0.8f
, 0.9f
, 1.0f
, 1.0f
};
234 float avg_distance
= 0.0f
;
236 for( int i
=0; i
<8; i
++ )
237 vg_dsp
.echo_tunings
[i
] = 0.5f
;
239 for( int j
=0; j
<14; j
++ ){
240 float d
= vg_dsp
.echo_distances
[j
];
242 for( int i
=0; i
<7; i
++ ){
243 if( d
< sizes
[i
+1] ){
244 float range
= sizes
[i
+1]-sizes
[i
];
245 float t
= vg_clampf( (d
- sizes
[i
])/range
, 0.0f
, 1.0f
);
247 vg_dsp
.echo_tunings
[i
] += 1.0f
-t
;
248 vg_dsp
.echo_tunings
[i
+1] += t
;
256 avg_distance
/= 14.0f
;
259 vg_dsp
.reverb_wet_mix
=1.0f
-vg_clampf((avg_distance
-30.0f
)/200.0f
,0.0f
,1.0f
);
260 vg_dsp
.reverb_dry_mix
=1.0f
-vg_dsp
.reverb_wet_mix
*0.4f
;
263 for( int i
=0; i
<8; i
++ )
264 total
+= vg_dsp
.echo_tunings
[i
];
267 float inverse
= 1.0f
/total
;
269 for( int i
=0;i
<8; i
++ ){
270 vg_dsp
.echo_tunings
[i
] *= inverse
;
274 for( int i
=0; i
<8; i
++ ){
275 float freq
= vg_lerpf( 200.0f
, 500.0f
, vg_dsp
.echo_tunings
[i
] );
276 dsp_update_lpf( &__echos_lpf
[i
], freq
);
279 for( int i
=0;i
<8; i
++ ){
280 vg_dsp
.echo_tunings
[i
] *= volumes
[i
];
284 static void vg_dsp_free( void )
286 glDeleteTextures( 1, &vg_dsp
.view_texture
);
289 static void vg_dsp_update_texture( void )
291 for( int i
=0; i
<512*512; i
++ ){
292 float v
= vg_clampf( vg_dsp
.buffer
[i
] * 0.5f
+ 0.5f
, 0.0f
, 1.0f
);
293 vg_dsp
.view_texture_buffer
[i
] = v
* 255.0f
;
297 #endif /* VG_AUDIO_DSP_H */