ogl_beamforming

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

Commit: b8b0525a614c00336f84f97a3cda8545b0bb54ae
Parent: e24808b8ab4cd15bebda7f800e9aa70dc6a3633c
Author: Randy Palamar
Date:   Mon, 10 Nov 2025 12:30:42 -0700

core: move cursed filter gen macro into meta code

Diffstat:
Mbeamformer.c | 24++++++++++--------------
Mbeamformer.h | 1-
Mbeamformer.meta | 74++++++++++++++++++++++++++++++++++++++++++++++++++++++--------------------
Mbeamformer_parameters.h | 11-----------
Mbeamformer_shared_memory.c | 15+--------------
Mbuild.c | 74+++-----------------------------------------------------------------------
Mgenerated/beamformer.meta.c | 199++++++++++++++++++++++++++++++++++++++++++++-----------------------------------
Mhelpers/ogl_beamformer_lib.c | 24++++++++++--------------
Mhelpers/ogl_beamformer_lib_base.h | 7+++----
Mtests/throughput.c | 11+++++------
10 files changed, 197 insertions(+), 243 deletions(-)

diff --git a/beamformer.c b/beamformer.c @@ -121,15 +121,12 @@ beamformer_compute_plan_for_block(BeamformerComputeContext *cc, u32 block, Arena } function void -beamformer_filter_update(BeamformerFilter *f, BeamformerFilterKind kind, - BeamformerFilterParameters fp, u32 block, u32 slot, Arena arena) +beamformer_filter_update(BeamformerFilter *f, BeamformerFilterParameters fp, u32 block, u32 slot, Arena arena) { - #define X(k, ...) s8_comp(#k "Filter"), - read_only local_persist s8 filter_kinds[] = {BEAMFORMER_FILTER_KIND_LIST(,)}; - #undef X - Stream sb = arena_stream(arena); - stream_append_s8s(&sb, filter_kinds[kind % countof(filter_kinds)], s8("[")); + stream_append_s8s(&sb, + beamformer_filter_kind_strings[fp.kind % countof(beamformer_filter_kind_strings)], + s8("Filter[")); stream_append_u64(&sb, block); stream_append_s8(&sb, s8("][")); stream_append_u64(&sb, slot); @@ -137,17 +134,17 @@ beamformer_filter_update(BeamformerFilter *f, BeamformerFilterKind kind, s8 label = arena_stream_commit(&arena, &sb); void *filter = 0; - switch (kind) { + switch (fp.kind) { case BeamformerFilterKind_Kaiser:{ /* TODO(rnp): this should also support complex */ /* TODO(rnp): implement this as an IFIR filter instead to reduce computation */ - filter = kaiser_low_pass_filter(&arena, fp.Kaiser.cutoff_frequency, fp.sampling_frequency, - fp.Kaiser.beta, (i32)fp.Kaiser.length); - f->length = (i32)fp.Kaiser.length; + filter = kaiser_low_pass_filter(&arena, fp.kaiser.cutoff_frequency, fp.sampling_frequency, + fp.kaiser.beta, (i32)fp.kaiser.length); + f->length = (i32)fp.kaiser.length; f->time_delay = (f32)f->length / 2.0f / fp.sampling_frequency; }break; case BeamformerFilterKind_MatchedChirp:{ - typeof(fp.MatchedChirp) *mc = &fp.MatchedChirp; + typeof(fp.matched_chirp) *mc = &fp.matched_chirp; f32 fs = fp.sampling_frequency; f->length = (i32)(mc->duration * fs); if (fp.complex) { @@ -161,7 +158,6 @@ beamformer_filter_update(BeamformerFilter *f, BeamformerFilterKind kind, InvalidDefaultCase; } - f->kind = kind; f->parameters = fp; glDeleteBuffers(1, &f->ssbo); @@ -1205,7 +1201,7 @@ complete_queue(BeamformerCtx *ctx, BeamformWorkQueue *q, Arena *arena, iptr gl_c u32 block = fctx->parameter_block; u32 slot = fctx->filter_slot; BeamformerComputePlan *cp = beamformer_compute_plan_for_block(cs, block, arena); - beamformer_filter_update(cp->filters + slot, fctx->kind, fctx->parameters, block, slot, *arena); + beamformer_filter_update(cp->filters + slot, fctx->parameters, block, slot, *arena); }break; case BeamformerWorkKind_ComputeIndirect:{ fill_frame_compute_work(ctx, work, work->compute_indirect_context.view_plane, diff --git a/beamformer.h b/beamformer.h @@ -105,7 +105,6 @@ typedef struct { } BeamformerRenderModel; typedef struct { - BeamformerFilterKind kind; BeamformerFilterParameters parameters; f32 time_delay; i32 length; diff --git a/beamformer.meta b/beamformer.meta @@ -10,12 +10,7 @@ [Float32Complex 4 2] } -@Table([name name_lower]) EmissionKind -{ - [Sine sine] - [SineAM sine_am] - [Chirp chirp] -} +@Enumeration(EmissionKind [Sine SineAM Chirp]) @Table([c_type m_type name]) SineParameters { @@ -43,6 +38,31 @@ ChirpParameters ]) Emission +@Table([name name_lower]) FilterKind +{ + [Kaiser kaiser] + [MatchedChirp matched_chirp] +} + +@Table([c_type m_type name]) KaiserFilterParameters +{ + [f32 single cutoff_frequency] + [f32 single beta] + [u32 uint32 length] +} + +@Table([c_type m_type name]) ChirpFilterParameters +{ + [f32 single duration] + [f32 single min_frequency] + [f32 single max_frequency] +} + +@MUnion(FilterKind [ + KaiserFilterParameters + ChirpFilterParameters +]) Filter + @Table([name pretty_name fixed_transmits]) AcquisitionKind { [FORCES FORCES 1] @@ -68,30 +88,40 @@ @Expand(AcquisitionKind) @Enumeration(AcquisitionKind `$(name)`) @Expand(DataKind) @Enumeration(DataKind `$(name)`) -@Expand(EmissionKind) @Enumeration(EmissionKind `$(name)`) +@Expand(FilterKind) @Enumeration(FilterKind `$(name)`) @Expand(InterpolationMode) @Enumeration(InterpolationMode `$(name)`) @Emit { `typedef struct {` - @Expand(SineParameters) ` $(c_type)$(|)$(name);` - `} BeamformerEmissionSineParameters;` - `` - `typedef struct {` - @Expand(SineAMParameters) ` $(c_type)$(|)$(name);` - `} BeamformerEmissionSineAMParameters;` - `` - `typedef struct {` - @Expand(ChirpParameters) ` $(c_type)$(|)$(name);` - `} BeamformerEmissionChirpParameters;` - `` - `typedef struct {` ` BeamformerEmissionKind kind;` ` union {` - @Expand(EmissionKind) ` BeamformerEmission$(name)Parameters$(|)$(name_lower);` + ` struct {` + @Expand(SineParameters) ` $(c_type)$(|)$(name);` + ` } sine;` + ` struct {` + @Expand(SineAMParameters) ` $(c_type)$(|)$(name);` + ` } sine_am;` + ` struct {` + @Expand(ChirpParameters) ` $(c_type)$(|)$(name);` + ` } chirp;` ` };` `} BeamformerEmission;` `` + `typedef struct {` + ` BeamformerFilterKind kind;` + ` union {` + ` struct {` + @Expand(KaiserFilterParameters) ` $(c_type)$(|)$(name);` + ` } kaiser;` + ` struct {` + @Expand(ChirpFilterParameters) ` $(c_type)$(|)$(name);` + ` } matched_chirp;` + ` };` + ` f32 sampling_frequency;` + ` b16 complex;` + `} BeamformerFilterParameters;` + `` `read_only global u8 beamformer_data_kind_element_size[] = {` @Expand(DataKind) ` $(size),` `};` @@ -112,6 +142,10 @@ @Expand(AcquisitionKind) ` s8_comp("$(pretty_name)"),` `};` `` + `read_only global s8 beamformer_filter_kind_strings[] = {` + @Expand(FilterKind) ` s8_comp("$(name)"),` + `};` + `` `read_only global s8 beamformer_interpolation_mode_strings[] = {` @Expand(InterpolationMode) ` s8_comp("$(name)"),` `};` diff --git a/beamformer_parameters.h b/beamformer_parameters.h @@ -17,17 +17,6 @@ typedef struct { float rf_time_deltas[32]; } BeamformerComputeStatsTable; -/* TODO(rnp): this is an absolute abuse of the preprocessor, but now is - * not a good time to write a full metaprogram */ -#define BEAMFORMER_FILTER_KIND_LIST(type, _) \ - X(Invalid, type unused) \ - X(Kaiser, type cutoff_frequency _ type beta _ type length) \ - X(MatchedChirp, type duration _ type min_frequency _ type max_frequency) - -#define X(kind, ...) BeamformerFilterKind_##kind, -typedef enum {BEAMFORMER_FILTER_KIND_LIST(,) BeamformerFilterKind_Count} BeamformerFilterKind; -#undef X - /* X(type, id, pretty name) */ #define BEAMFORMER_VIEW_PLANE_TAG_LIST \ X(XZ, 0, "XZ") \ diff --git a/beamformer_shared_memory.c b/beamformer_shared_memory.c @@ -1,5 +1,5 @@ /* See LICENSE for license details. */ -#define BEAMFORMER_SHARED_MEMORY_VERSION (20UL) +#define BEAMFORMER_SHARED_MEMORY_VERSION (21UL) typedef struct BeamformerFrame BeamformerFrame; @@ -12,20 +12,7 @@ typedef enum { BeamformerWorkKind_UploadBuffer, } BeamformerWorkKind; -/* TODO(rnp): this is massively bloating the queue; think of some other - * way to communicate these to the beamformer */ typedef struct { - union { - #define X(kind, ...) struct {__VA_ARGS__ ;} kind; - BEAMFORMER_FILTER_KIND_LIST(f32, ;) - #undef X - }; - f32 sampling_frequency; - b16 complex; -} BeamformerFilterParameters; - -typedef struct { - BeamformerFilterKind kind; BeamformerFilterParameters parameters; u8 filter_slot; u8 parameter_block; diff --git a/build.c b/build.c @@ -845,17 +845,6 @@ s8_trim(s8 in) return result; } -function void -s8_list_from_s8(s8_list *list, Arena *arena, s8 str) -{ - s8 right = str, left; - while (right.len > 0) { - s8_split(right, &left, &right, ' '); - left = s8_trim(left); - if (left.len > 0) { *da_push(arena, list) = left; } - } -} - typedef struct { Stream stream; Arena scratch; @@ -908,15 +897,6 @@ meta_push_matlab_property(MetaprogramContext *m, s8 name, u64 length, s8 kind) meta_end_line(m, s8(")"), kind.len > 0 ? s8(" ") : s8(""), kind); } -function void -meta_push_matlab_enum_with_value(MetaprogramContext *m, s8 name, i32 value) -{ - meta_indent(m); - stream_append_s8s(&m->stream, name, s8(" (")); - stream_append_i64(&m->stream, value); - stream_append_s8(&m->stream, s8(")\n")); -} - function b32 meta_end_and_write_matlab(MetaprogramContext *m, char *path) { @@ -2526,6 +2506,8 @@ metagen_emit_c_code(MetaContext *ctx, Arena arena) metagen_push_table(m, m->scratch, s8(""), s8(";"), (s8 *[]){types, names}, countof(names), 2); } meta_end_scope(m, s8("} BeamformerShaderBakeParameters;\n")); + metagen_run_emit(m, ctx); + ///////////////////////////////// // NOTE(rnp): shader info tables meta_begin_scope(m, s8("read_only global s8 beamformer_shader_names[] = {")); @@ -2607,8 +2589,6 @@ metagen_emit_c_code(MetaContext *ctx, Arena arena) } meta_end_scope(m, s8("};\n")); - metagen_run_emit(m, ctx); - //fprintf(stderr, "%.*s\n", (i32)m.stream.widx, m.stream.data); result = meta_write_and_reset(m, out_meta); @@ -2717,7 +2697,7 @@ function b32 metagen_emit_matlab_code(MetaContext *ctx, Arena arena) { b32 result = 1; - if (!needs_rebuild(OUTPUT("matlab/OGLBeamformerFilterKind.m"), "beamformer_parameters.h", "beamformer.meta")) + if (!needs_rebuild(OUTPUT("matlab/OGLBeamformerLiveImagingParameters.m"), "beamformer_parameters.h", "beamformer.meta")) return result; build_log_generate("MATLAB Bindings"); @@ -2742,54 +2722,6 @@ metagen_emit_matlab_code(MetaContext *ctx, Arena arena) result &= meta_end_and_write_matlab(m, OUTPUT("matlab/OGLBeamformerLiveFeedbackFlags.m")); #undef X - #define X(kind, ...) meta_push_matlab_enum_with_value(m, s8(#kind), BeamformerFilterKind_## kind); - meta_begin_matlab_class(m, "OGLBeamformerFilterKind", "int32"); - meta_begin_scope(m, s8("enumeration")); - BEAMFORMER_FILTER_KIND_LIST(,) - result &= meta_end_and_write_matlab(m, OUTPUT("matlab/OGLBeamformerFilterKind.m")); - #undef X - - os_make_directory(OUTPUT("matlab/+OGLBeamformerFilter")); - #define X(kind, ...) {OUTPUT("matlab/+OGLBeamformerFilter/" #kind ".m"), s8_comp(#kind), s8_comp(#__VA_ARGS__)}, - read_only local_persist struct {char *out; s8 class, args;} filter_table[] = { - BEAMFORMER_FILTER_KIND_LIST(,) - }; - #undef X - - s8_list members = {0}; - for EachNonZeroEnumValue(BeamformerFilterKind, filter) { - typeof(*filter_table) *f = filter_table + filter; - members.count = 0; - s8_list_from_s8(&members, &m->scratch, f->args); - meta_begin_scope(m, s8("classdef "), f->class, s8(" < OGLBeamformerFilter.BaseFilter")); - - meta_begin_scope(m, s8("properties")); - for (iz it = 0; it < members.count; it++) - meta_push_matlab_property(m, members.data[it], 1, s8("single")); - meta_end_scope(m, s8("end")); - - meta_begin_scope(m, s8("methods")); - meta_begin_line(m, s8("function obj = "), f->class, s8("(")); - for (iz it = 0; it < members.count; it++) - meta_push(m, it > 0 ? s8(", ") : s8(""), members.data[it]); - meta_end_line(m, s8(")")); - - m->indentation_level++; - for (iz it = 0; it < members.count; it++) - meta_push_line(m, s8("obj."), members.data[it], s8(" = "), members.data[it], s8(";")); - result &= meta_end_and_write_matlab(m, f->out); - } - m->scratch = ctx->scratch; - - meta_begin_matlab_class(m, "BaseFilter"); - meta_begin_scope(m, s8("methods")); - meta_begin_scope(m, s8("function out = Flatten(obj)")); - meta_push_line(m, s8("fields = struct2cell(struct(obj));")); - meta_push_line(m, s8("out = zeros(1, numel(fields));")); - meta_begin_scope(m, s8("for i = 1:numel(fields)")); - meta_push_line(m, s8("out(i) = fields{i};")); - result &= meta_end_and_write_matlab(m, OUTPUT("matlab/+OGLBeamformerFilter/BaseFilter.m")); - #define X(name, __t, __s, kind, elements, ...) meta_push_matlab_property(m, s8(#name), (u64)elements, s8(#kind)); meta_begin_matlab_class(m, "OGLBeamformerParameters"); meta_begin_scope(m, s8("properties")); diff --git a/generated/beamformer.meta.c b/generated/beamformer.meta.c @@ -22,6 +22,13 @@ typedef enum { } BeamformerSamplingMode; typedef enum { + BeamformerEmissionKind_Sine = 0, + BeamformerEmissionKind_SineAM = 1, + BeamformerEmissionKind_Chirp = 2, + BeamformerEmissionKind_Count, +} BeamformerEmissionKind; + +typedef enum { BeamformerAcquisitionKind_FORCES = 0, BeamformerAcquisitionKind_UFORCES = 1, BeamformerAcquisitionKind_HERCULES = 2, @@ -46,11 +53,10 @@ typedef enum { } BeamformerDataKind; typedef enum { - BeamformerEmissionKind_Sine = 0, - BeamformerEmissionKind_SineAM = 1, - BeamformerEmissionKind_Chirp = 2, - BeamformerEmissionKind_Count, -} BeamformerEmissionKind; + BeamformerFilterKind_Kaiser = 0, + BeamformerFilterKind_MatchedChirp = 1, + BeamformerFilterKind_Count, +} BeamformerFilterKind; typedef enum { BeamformerInterpolationMode_Nearest = 0, @@ -150,6 +156,106 @@ typedef struct { u32 flags; } BeamformerShaderBakeParameters; +typedef struct { + BeamformerEmissionKind kind; + union { + struct { + f32 cycles; + f32 frequency; + } sine; + struct { + f32 cycles; + f32 frequency; + u32 emissions; + } sine_am; + struct { + f32 duration; + f32 min_frequency; + f32 max_frequency; + } chirp; + }; +} BeamformerEmission; + +typedef struct { + BeamformerFilterKind kind; + union { + struct { + f32 cutoff_frequency; + f32 beta; + u32 length; + } kaiser; + struct { + f32 duration; + f32 min_frequency; + f32 max_frequency; + } matched_chirp; + }; + f32 sampling_frequency; + b16 complex; +} BeamformerFilterParameters; + +read_only global u8 beamformer_data_kind_element_size[] = { + 2, + 2, + 4, + 4, +}; + +read_only global u8 beamformer_data_kind_element_count[] = { + 1, + 2, + 1, + 2, +}; + +read_only global u8 beamformer_data_kind_byte_size[] = { + 2 * 1, + 2 * 2, + 4 * 1, + 4 * 2, +}; + +read_only global u8 beamformer_acquisition_kind_has_fixed_transmits[] = { + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, +}; + +read_only global s8 beamformer_acquisition_kind_strings[] = { + s8_comp("FORCES"), + s8_comp("UFORCES"), + s8_comp("HERCULES"), + s8_comp("VLS"), + s8_comp("TPW"), + s8_comp("UHERCULES"), + s8_comp("RACES"), + s8_comp("EPIC-FORCES"), + s8_comp("EPIC-UFORCES"), + s8_comp("EPIC-UHERCULES"), + s8_comp("Flash"), + s8_comp("HERO-PA"), +}; + +read_only global s8 beamformer_filter_kind_strings[] = { + s8_comp("Kaiser"), + s8_comp("MatchedChirp"), +}; + +read_only global s8 beamformer_interpolation_mode_strings[] = { + s8_comp("Nearest"), + s8_comp("Linear"), + s8_comp("Cubic"), +}; + read_only global s8 beamformer_shader_names[] = { s8_comp("CudaDecode"), s8_comp("CudaHilbert"), @@ -353,86 +459,3 @@ read_only global i32 beamformer_shader_bake_parameter_counts[] = { 0, }; -typedef struct { - f32 cycles; - f32 frequency; -} BeamformerEmissionSineParameters; - -typedef struct { - f32 cycles; - f32 frequency; - u32 emissions; -} BeamformerEmissionSineAMParameters; - -typedef struct { - f32 duration; - f32 min_frequency; - f32 max_frequency; -} BeamformerEmissionChirpParameters; - -typedef struct { - BeamformerEmissionKind kind; - union { - BeamformerEmissionSineParameters sine; - BeamformerEmissionSineAMParameters sine_am; - BeamformerEmissionChirpParameters chirp; - }; -} BeamformerEmission; - -read_only global u8 beamformer_data_kind_element_size[] = { - 2, - 2, - 4, - 4, -}; - -read_only global u8 beamformer_data_kind_element_count[] = { - 1, - 2, - 1, - 2, -}; - -read_only global u8 beamformer_data_kind_byte_size[] = { - 2 * 1, - 2 * 2, - 4 * 1, - 4 * 2, -}; - -read_only global u8 beamformer_acquisition_kind_has_fixed_transmits[] = { - 1, - 0, - 1, - 0, - 0, - 0, - 1, - 1, - 0, - 0, - 0, - 0, -}; - -read_only global s8 beamformer_acquisition_kind_strings[] = { - s8_comp("FORCES"), - s8_comp("UFORCES"), - s8_comp("HERCULES"), - s8_comp("VLS"), - s8_comp("TPW"), - s8_comp("UHERCULES"), - s8_comp("RACES"), - s8_comp("EPIC-FORCES"), - s8_comp("EPIC-UFORCES"), - s8_comp("EPIC-UHERCULES"), - s8_comp("Flash"), - s8_comp("HERO-PA"), -}; - -read_only global s8 beamformer_interpolation_mode_strings[] = { - s8_comp("Nearest"), - s8_comp("Linear"), - s8_comp("Cubic"), -}; - diff --git a/helpers/ogl_beamformer_lib.c b/helpers/ogl_beamformer_lib.c @@ -323,7 +323,7 @@ beamformer_push_pipeline(i32 *shaders, u32 shader_count, BeamformerDataKind data } function b32 -beamformer_create_filter_base(BeamformerFilterKind kind, BeamformerFilterParameters params, u8 filter_slot, u8 parameter_block) +beamformer_create_filter_base(BeamformerFilterParameters params, u8 filter_slot, u8 parameter_block) { b32 result = 0; if (check_shared_memory()) { @@ -331,7 +331,6 @@ beamformer_create_filter_base(BeamformerFilterKind kind, BeamformerFilterParamet if (work) { BeamformerCreateFilterContext *ctx = &work->create_filter_context; work->kind = BeamformerWorkKind_CreateFilter; - ctx->kind = kind; ctx->parameters = params; ctx->filter_slot = filter_slot % BeamformerFilterSlots; ctx->parameter_block = parameter_block % BeamformerMaxParameterBlockSlots; @@ -343,22 +342,19 @@ beamformer_create_filter_base(BeamformerFilterKind kind, BeamformerFilterParamet } b32 -beamformer_create_filter(BeamformerFilterKind kind, f32 *filter_parameters, u32 filter_parameter_count, +beamformer_create_filter(BeamformerFilterKind kind, void *filter_parameters, u32 filter_size, f32 sampling_frequency, b32 complex, u8 filter_slot, u8 parameter_block) { b32 result = 0; if (lib_error_check(kind >= 0 && kind < BeamformerFilterKind_Count, BF_LIB_ERR_KIND_INVALID_FILTER_KIND)) { - BeamformerFilterParameters fp = {.sampling_frequency = sampling_frequency, .complex = complex != 0}; - #define X(kind, ...) sizeof(fp.kind), - read_only local_persist u32 kind_sizes[] = {BEAMFORMER_FILTER_KIND_LIST(,)}; - #undef X - if (lib_error_check(kind_sizes[kind] == sizeof(f32) * filter_parameter_count, - BF_LIB_ERR_KIND_INVALID_FILTER_PARAM_COUNT)) - { - /* NOTE(rnp): any filter kind struct works as base offset of union */ - mem_copy(&fp.Kaiser, filter_parameters, kind_sizes[kind]); - result = beamformer_create_filter_base(kind, fp, filter_slot, parameter_block); - } + BeamformerFilterParameters fp = {0}; + /* NOTE(rnp): any parameter struct works as base offset */ + filter_size = MIN(filter_size, sizeof(fp) - offsetof(BeamformerFilterParameters, kaiser)); + mem_copy(&fp.kaiser, filter_parameters, filter_size); + fp.kind = kind; + fp.complex = complex != 0; + fp.sampling_frequency = sampling_frequency; + result = beamformer_create_filter_base(fp, filter_slot, parameter_block); } return result; } diff --git a/helpers/ogl_beamformer_lib_base.h b/helpers/ogl_beamformer_lib_base.h @@ -26,8 +26,7 @@ X(SYNC_VARIABLE, 15, "failed to acquire lock within timeout period") \ X(INVALID_TIMEOUT, 16, "invalid timeout value") \ X(INVALID_FILTER_KIND, 17, "invalid filter kind") \ - X(INVALID_FILTER_PARAM_COUNT, 18, "invalid parameters count passed for filter") \ - X(INVALID_SIMPLE_PARAMETERS, 19, "invalid simple parameters struct") + X(INVALID_SIMPLE_PARAMETERS, 18, "invalid simple parameters struct") #define X(type, num, string) BF_LIB_ERR_KIND_ ##type = num, typedef enum {BEAMFORMER_LIB_ERRORS} BeamformerLibErrorKind; @@ -127,8 +126,8 @@ LIB_FN uint32_t beamformer_push_transmit_receive_orientations_at(uint8_t *values * M = (A - 8) / (2.285 (ω_s - ω_p)) */ -LIB_FN uint32_t beamformer_create_filter(BeamformerFilterKind kind, float *filter_parameters, - uint32_t filter_parameter_count, float sampling_frequency, +LIB_FN uint32_t beamformer_create_filter(BeamformerFilterKind kind, void *filter_parameters, + uint32_t filter_size, float sampling_frequency, uint32_t complex, uint8_t filter_slot, uint8_t parameter_block); ////////////////////////// diff --git a/tests/throughput.c b/tests/throughput.c @@ -334,23 +334,22 @@ execute_study(s8 study, Arena arena, Stream path, Options *options) kaiser.Kaiser.cutoff_frequency = 2.0e6f; kaiser.Kaiser.length = 36; - beamformer_create_filter(BeamformerFilterKind_Kaiser, (f32 *)&kaiser.Kaiser, - sizeof(kaiser.Kaiser) / sizeof(f32), bp.sampling_frequency / 2, 0, 0, 0); + beamformer_create_filter(BeamformerFilterKind_Kaiser, (f32 *)&kaiser.kaiser, + sizeof(kaiser.kaiser), bp.sampling_frequency / 2, 0, 0, 0); beamformer_set_pipeline_stage_parameters(0, 0); #endif #if 1 BeamformerFilterParameters matched = {0}; - typeof(matched.MatchedChirp) *mp = &matched.MatchedChirp; + typeof(matched.matched_chirp) *mp = &matched.matched_chirp; mp->duration = 18e-6f; mp->min_frequency = 2.9e6f - bp.demodulation_frequency; mp->max_frequency = 6.0e6f - bp.demodulation_frequency; bp.time_offset += mp->duration / 2; - beamformer_create_filter(BeamformerFilterKind_MatchedChirp, (f32 *)&matched.MatchedChirp, - sizeof(matched.MatchedChirp) / sizeof(f32), bp.sampling_frequency / 2, - 1, 0, 0); + beamformer_create_filter(BeamformerFilterKind_MatchedChirp, (f32 *)mp, sizeof(*mp), + bp.sampling_frequency / 2, 1, 0, 0); beamformer_set_pipeline_stage_parameters(0, 0); #endif