ogl_beamforming

Ultrasound Beamforming Implemented with OpenGL
git clone anongit@rnpnr.xyz:ogl_beamforming.git
Log | Files | Refs | Feed | Submodules | README | LICENSE

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 }