demod.glsl (2283B)
1 /* See LICENSE for license details. */ 2 #if defined(INPUT_DATA_TYPE_FLOAT) 3 #define DATA_TYPE vec2 4 #define RESULT_TYPE_CAST(v) (v) 5 #define SAMPLE_TYPE_CAST(v) (v) 6 #else 7 #define DATA_TYPE uint 8 #define RESULT_TYPE_CAST(v) packSnorm2x16(v) 9 #define SAMPLE_TYPE_CAST(v) unpackSnorm2x16(v) 10 #endif 11 12 layout(std430, binding = 1) readonly restrict buffer buffer_1 { 13 DATA_TYPE in_data[]; 14 }; 15 16 layout(std430, binding = 2) writeonly restrict buffer buffer_2 { 17 DATA_TYPE out_data[]; 18 }; 19 20 layout(r32f, binding = 0) readonly restrict uniform image1D filter_coefficients; 21 layout(r16i, binding = 1) readonly restrict uniform iimage1D channel_mapping; 22 23 vec2 rotate_iq(vec2 iq, uint index) 24 { 25 float arg = radians(360) * demodulation_frequency * index / sampling_frequency; 26 mat2 phasor = mat2( cos(arg), sin(arg), 27 -sin(arg), cos(arg)); 28 vec2 result = phasor * iq; 29 return result; 30 } 31 32 vec2 sample_rf(uint index) 33 { 34 vec2 result = SAMPLE_TYPE_CAST(in_data[index]); 35 return result; 36 } 37 38 void main() 39 { 40 uint in_sample = gl_GlobalInvocationID.x * decimation_rate; 41 uint out_sample = gl_GlobalInvocationID.x; 42 uint channel = gl_GlobalInvocationID.y; 43 uint transmit = gl_GlobalInvocationID.z; 44 45 uint in_channel = map_channels ? imageLoad(channel_mapping, int(channel)).x : channel; 46 uint in_offset = input_channel_stride * in_channel + input_transmit_stride * transmit; 47 uint out_offset = output_channel_stride * channel + 48 output_transmit_stride * transmit + 49 output_sample_stride * out_sample; 50 51 int target; 52 if (map_channels) { 53 target = int(output_channel_stride / output_sample_stride); 54 } else { 55 target = int(output_transmit_stride); 56 } 57 58 if (out_sample < target) { 59 vec2 result = vec2(0); 60 int index = int(in_sample) - imageSize(filter_coefficients).x; 61 int start = index < 0 ? -index : 0; 62 index += start; 63 target *= int(decimation_rate); 64 for (int i = start; i < imageSize(filter_coefficients).x && index < target; i++, index++) { 65 vec2 iq = sqrt(2.0f) * rotate_iq(sample_rf(in_offset + index) * vec2(1, -1), index); 66 result += iq * imageLoad(filter_coefficients, imageSize(filter_coefficients).x - i - 1).x; 67 } 68 out_data[out_offset] = RESULT_TYPE_CAST(result); 69 } 70 }