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_call( async_vg_dsp_alloc_texture
, NULL
, 0 );
159 /* temporary global design */
160 dsp_init_lpf( &__lpf_mud_free
, 125.0f
);
163 { 2.0f
, 4.0f
, 8.0f
, 16.0f
, 32.0f
, 64.0f
, 128.0f
, 256.0f
};
165 float reflection_variance
= 0.1f
;
167 for( int i
=0; i
<8; i
++ ){
168 float reflection_time
= ((sizes
[i
])/343.0f
) * 1000.0f
;
170 float var
= 1.0f
+ (vg_randf64()*2.0f
- 1.0f
) * reflection_variance
,
171 total
= reflection_time
* var
;
173 dsp_init_delay( &__echos
[i
], total
/ 1000.0f
);
175 float freq
= vg_lerpf( 800.0f
, 350.0f
, sizes
[i
] / 256.0f
);
176 dsp_init_lpf( &__echos_lpf
[i
], freq
);
179 float diffusions
[] = { 187.0f
, 159.0f
, 143.0f
, 121.0f
,
180 79.0f
, 57.0f
, 27.0f
, 11.0f
};
182 for( int i
=0; i
<8; i
++ ){
183 dsp_init_schroeder( __diffusion_chain
+i
, diffusions
[i
]/1000.0f
, 0.7f
);
187 static void vg_dsp_process( float *stereo_in
, float *stereo_out
)
189 float in_total
= (stereo_in
[0]+stereo_in
[1])*0.5f
;
190 float recieved
= 0.0f
;
192 for( int i
=0; i
<8; i
++ ){
194 dsp_read_delay( __echos
+i
, &echo
);
195 dsp_write_lpf( __echos_lpf
+i
, &echo
);
196 dsp_read_lpf( __echos_lpf
+i
, &echo
);
198 recieved
+= echo
* vg_dsp
.echo_tunings
[i
]*0.98;
201 float diffused
= recieved
;
203 for( int i
=0; i
<8; i
++ ){
204 dsp_process_schroeder( __diffusion_chain
+i
, &diffused
, &diffused
);
207 float diffuse_mix
= vg_dsp
.reverb_wet_mix
;
208 diffuse_mix
= vg_lerpf( recieved
, diffused
, diffuse_mix
);
209 float total
= in_total
+ diffuse_mix
;
212 dsp_write_lpf( &__lpf_mud_free
, &total
);
213 dsp_read_lpf( &__lpf_mud_free
, &low_mud
);
217 for( int i
=0; i
<8; i
++ )
218 dsp_write_delay( __echos
+i
, &total
);
220 stereo_out
[0] = stereo_in
[0]*vg_dsp
.reverb_dry_mix
;
221 stereo_out
[1] = stereo_in
[1]*vg_dsp
.reverb_dry_mix
;
222 stereo_out
[0] += diffuse_mix
*2.0f
*vg_dsp
.reverb_wet_mix
;
223 stereo_out
[1] += diffuse_mix
*2.0f
*vg_dsp
.reverb_wet_mix
;
226 static void dsp_update_tunings(void)
229 { 2.0f
, 4.0f
, 8.0f
, 16.0f
, 32.0f
, 64.0f
, 128.0f
, 256.0f
};
231 { 0.2f
, 0.3f
, 0.5f
, 0.7f
, 0.8f
, 0.9f
, 1.0f
, 1.0f
};
233 float avg_distance
= 0.0f
;
235 for( int i
=0; i
<8; i
++ )
236 vg_dsp
.echo_tunings
[i
] = 0.5f
;
238 for( int j
=0; j
<14; j
++ ){
239 float d
= vg_dsp
.echo_distances
[j
];
241 for( int i
=0; i
<7; i
++ ){
242 if( d
< sizes
[i
+1] ){
243 float range
= sizes
[i
+1]-sizes
[i
];
244 float t
= vg_clampf( (d
- sizes
[i
])/range
, 0.0f
, 1.0f
);
246 vg_dsp
.echo_tunings
[i
] += 1.0f
-t
;
247 vg_dsp
.echo_tunings
[i
+1] += t
;
255 avg_distance
/= 14.0f
;
258 vg_dsp
.reverb_wet_mix
=1.0f
-vg_clampf((avg_distance
-30.0f
)/200.0f
,0.0f
,1.0f
);
259 vg_dsp
.reverb_dry_mix
=1.0f
-vg_dsp
.reverb_wet_mix
*0.4f
;
262 for( int i
=0; i
<8; i
++ )
263 total
+= vg_dsp
.echo_tunings
[i
];
266 float inverse
= 1.0f
/total
;
268 for( int i
=0;i
<8; i
++ ){
269 vg_dsp
.echo_tunings
[i
] *= inverse
;
273 for( int i
=0; i
<8; i
++ ){
274 float freq
= vg_lerpf( 200.0f
, 500.0f
, vg_dsp
.echo_tunings
[i
] );
275 dsp_update_lpf( &__echos_lpf
[i
], freq
);
278 for( int i
=0;i
<8; i
++ ){
279 vg_dsp
.echo_tunings
[i
] *= volumes
[i
];
283 static void vg_dsp_free( void )
285 glDeleteTextures( 1, &vg_dsp
.view_texture
);
288 static void vg_dsp_update_texture( void )
290 for( int i
=0; i
<512*512; i
++ ){
291 float v
= vg_clampf( vg_dsp
.buffer
[i
] * 0.5f
+ 0.5f
, 0.0f
, 1.0f
);
292 vg_dsp
.view_texture_buffer
[i
] = v
* 255.0f
;
296 #endif /* VG_AUDIO_DSP_H */