[BGM] Try cubic instead of sinc interpolation
Ported the godot implementation
This commit is contained in:
parent
72dcc11945
commit
961c1344eb
|
@ -103,7 +103,7 @@ highp vec2 pack_float_to_int16(highp float value) {
|
|||
const highp float HEADER_LENGTH_TEXELS = 5.0;
|
||||
const highp int INSTRUMENT_SAMPLES_WIDTH = 2048;
|
||||
highp float sinc(highp float x) {
|
||||
x = abs(x) + 0.00000000000001; // Avoid division by zero
|
||||
x = abs(x * 3.14159265359) + 0.00000000001; // Avoid division by zero
|
||||
return min(sin(x)/x, 1.0);
|
||||
}
|
||||
|
||||
|
@ -133,21 +133,40 @@ highp float get_instrument_sample(highp float instrument_index, highp float note
|
|||
// If we're past the end of the sample, we need to wrap it back to within the loop range
|
||||
highp float overshoot = max(smp_t - smp_loop_begin, 0.0);
|
||||
smp_t -= floor(overshoot/smp_loop_length) * smp_loop_length;
|
||||
// if (smp_t > smp_loop_begin) {
|
||||
// // return 0.0;
|
||||
// smp_t = mod(smp_t - smp_loop_begin, smp_loop_length) + smp_loop_begin;
|
||||
// }
|
||||
|
||||
highp int smp_window_start = smp_start + int(smp_t) - 6;
|
||||
highp float smp_rel_filter_target = fract(smp_t) + 6.0;
|
||||
highp float output = 0.0;
|
||||
for (int i = 0; i < 12; i++) {
|
||||
highp int smp_filter = smp_window_start + i;
|
||||
highp float s = get_inst_texel_int16(smp_filter);
|
||||
// TODO: determine proper value for this. Might be based on instrument base mixrate.
|
||||
output += s * sinc((smp_rel_filter_target - float(i)) * 3.1);
|
||||
}
|
||||
return rescale_int16(output);
|
||||
// // Linear interpolation
|
||||
// highp int smp_window_start = smp_start + int(smp_t);
|
||||
// highp float x0 = get_inst_texel_int16(smp_window_start);
|
||||
// highp float x1 = get_inst_texel_int16(smp_window_start+1);
|
||||
// return rescale_int16(mix(x0, x1, fract(smp_t)));
|
||||
|
||||
// Cubic interpolation
|
||||
highp int smp_window_start = smp_start + int(smp_t);
|
||||
highp float x0 = get_inst_texel_int16(smp_window_start-1);
|
||||
highp float x1 = get_inst_texel_int16(smp_window_start);
|
||||
highp float x2 = get_inst_texel_int16(smp_window_start+1);
|
||||
highp float x3 = get_inst_texel_int16(smp_window_start+2);
|
||||
highp float a0 = 3.0*x1 - 3.0*x2 + x3 - x0;
|
||||
highp float a1 = 2.0*x0 - 5.0*x1 + 4.0*x2 - x3;
|
||||
highp float a2 = x2 - x0;
|
||||
highp float a3 = 2.0*x1;
|
||||
highp float T = fract(smp_t);
|
||||
highp float T2 = T*T;
|
||||
return rescale_int16((a0*T2*T + a1*T2 + a2*T + a3) / 2.0);
|
||||
|
||||
// // Windowed Sinc interpolation
|
||||
// highp int smp_window_start = smp_start + int(smp_t) - 6;
|
||||
// highp float smp_rel_filter_target = fract(smp_t) + 6.0;
|
||||
// highp float output = 0.0;
|
||||
// for (int i = 0; i < 12; i++) {
|
||||
// highp int smp_filter = smp_window_start + i;
|
||||
// highp float s = get_inst_texel_int16(smp_filter);
|
||||
// // TODO: determine proper value for this. Might be based on instrument base mixrate.
|
||||
// output += s * sinc(smp_rel_filter_target - float(i));
|
||||
// }
|
||||
// return rescale_int16(output);
|
||||
|
||||
// // Nearest sample
|
||||
// int target_texel = int(smp_t) + smp_start;
|
||||
// return rescale_int16(get_inst_texel_int16(target_texel));
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue