Commit: 8e5c7c889c3184a964cd4aefe64d2e84d364c807
Parent: 71fb9f2d5da8048740f00116798e221dcf671801
Author: Randy Palamar
Date: Mon, 5 Oct 2026 18:55:06 -0700
tests: move some code into test_common.c
this file can be shared between other specialized tests
Diffstat:
| A | tests/test_common.c | | | 326 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| M | tests/throughput.c | | | 384 | +------------------------------------------------------------------------------ |
2 files changed, 330 insertions(+), 380 deletions(-)
diff --git a/tests/test_common.c b/tests/test_common.c
@@ -0,0 +1,326 @@
+/* See LICENSE for license details. */
+#define BASE_EXPORT function
+#define BASE_IMPORT function
+#define BEAMFORMER_LIB_EXPORT function
+#include "base_platform.h"
+#include "ogl_beamformer_lib.c"
+
+#include <signal.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <zstd.h>
+
+#include "external/zemp_bp.h"
+
+typedef struct {
+ ZBP_DataKind kind;
+ ZBP_DataCompressionKind compression_kind;
+ str8 bytes;
+} ZBP_Data;
+
+#define shift_n(v, c, n) v += n, c -= n
+#define shift(v, c) shift_n(v, c, 1)
+
+#define die(...) die_((char *)__func__, __VA_ARGS__)
+function no_return void
+die_(char *function_name, char *format, ...)
+{
+ if (function_name)
+ fprintf(stderr, "%s: ", function_name);
+
+ va_list ap;
+
+ va_start(ap, format);
+ vfprintf(stderr, format, ap);
+ va_end(ap);
+
+ os_exit(1);
+}
+
+function b32
+beamformer_simple_parameters_from_zbp_file(Arena *arena, BeamformerSimpleParameters *bp, char *path, ZBP_Data *raw_data, u32 *data_frame_count)
+{
+ str8 raw = os_read_entire_file(arena, path);
+ if (raw.length < (i64)sizeof(ZBP_BaseHeader) || ((ZBP_BaseHeader *)raw.data)->magic != ZBP_HeaderMagic)
+ return 0;
+
+ switch (((ZBP_BaseHeader *)raw.data)->major) {
+
+ case 1:{
+ ZBP_HeaderV1 *header = (ZBP_HeaderV1 *)raw.data;
+
+ bp->sample_count = header->sample_count;
+ bp->channel_count = header->channel_count;
+ bp->acquisition_count = header->receive_event_count;
+
+ bp->sampling_mode = BeamformerSamplingMode_4X;
+ bp->acquisition_kind = header->beamform_mode;
+ bp->decode_mode = header->decode_mode;
+ bp->sampling_frequency = header->sampling_frequency;
+ bp->demodulation_frequency = header->sampling_frequency / 4;
+ bp->speed_of_sound = header->speed_of_sound;
+ bp->time_offset = header->time_offset;
+
+ memory_copy(bp->channel_mapping, header->channel_mapping, sizeof(*bp->channel_mapping) * bp->channel_count);
+ memory_copy(bp->xdc_transform.E, header->transducer_transform_matrix, sizeof(bp->xdc_transform));
+ memory_copy(bp->xdc_element_pitch.E, header->transducer_element_pitch, sizeof(bp->xdc_element_pitch));
+ // NOTE(rnp): ignores emission count and ensemble count
+ memory_copy(bp->raw_data_dimensions.E, header->raw_data_dimension, sizeof(bp->raw_data_dimensions));
+ if (data_frame_count) *data_frame_count = header->raw_data_dimension[2];
+ //if (data_frame_count) *data_frame_count = header->raw_data_dimension[3];
+
+ bp->data_kind = (BeamformerDataKind)ZBP_DataKind_Int16;
+ raw_data->kind = ZBP_DataKind_Int16;
+ raw_data->compression_kind = ZBP_DataCompressionKind_ZSTD;
+
+ read_only u8 transmit_mode_to_orientation[] = {
+ [0] = (ZBP_RCAOrientation_Rows << 4) | ZBP_RCAOrientation_Rows,
+ [1] = (ZBP_RCAOrientation_Rows << 4) | ZBP_RCAOrientation_Columns,
+ [2] = (ZBP_RCAOrientation_Columns << 4) | ZBP_RCAOrientation_Rows,
+ [3] = (ZBP_RCAOrientation_Columns << 4) | ZBP_RCAOrientation_Columns,
+ };
+ if (header->transmit_mode >= countof(transmit_mode_to_orientation))
+ return 0;
+
+ bp->transmit_receive_orientation = transmit_mode_to_orientation[header->transmit_mode];
+
+ ZBP_AcquisitionKind acquisition_kind = header->beamform_mode;
+ if (acquisition_kind == ZBP_AcquisitionKind_FORCES ||
+ acquisition_kind == ZBP_AcquisitionKind_HERCULES ||
+ acquisition_kind == ZBP_AcquisitionKind_UFORCES ||
+ acquisition_kind == ZBP_AcquisitionKind_UHERCULES)
+ {
+ bp->single_focus = 1;
+ bp->single_orientation = 1;
+ bp->focal_vector.E[0] = header->steering_angles[0];
+ bp->focal_vector.E[1] = header->focal_depths[0];
+ }
+
+ if (acquisition_kind == ZBP_AcquisitionKind_UFORCES ||
+ acquisition_kind == ZBP_AcquisitionKind_UHERCULES)
+ {
+ memory_copy(bp->sparse_elements, header->sparse_elements, sizeof(*bp->sparse_elements) * bp->acquisition_count);
+ }
+
+ if (acquisition_kind == ZBP_AcquisitionKind_RCA_TPW ||
+ acquisition_kind == ZBP_AcquisitionKind_RCA_VLS)
+ {
+ memory_copy(bp->focal_depths, header->focal_depths, sizeof(*bp->focal_depths) * bp->acquisition_count);
+ memory_copy(bp->steering_angles, header->steering_angles, sizeof(*bp->steering_angles) * bp->acquisition_count);
+ for EachIndex(bp->acquisition_count, it)
+ bp->transmit_receive_orientations[it] = bp->transmit_receive_orientation;
+ }
+
+ bp->emission_parameters.kind = BeamformerEmissionKind_Sine;
+ bp->emission_parameters.sine.cycles = 2;
+ bp->emission_parameters.sine.frequency = bp->demodulation_frequency;
+ }break;
+
+ case 2:{
+ ZBP_HeaderV2 *header = (ZBP_HeaderV2 *)raw.data;
+
+ bp->sample_count = header->sample_count;
+ bp->channel_count = header->channel_count;
+ bp->acquisition_count = header->receive_event_count;
+
+ read_only BeamformerSamplingMode zbp_sampling_mode_to_beamformer[] = {
+ [ZBP_SamplingMode_Standard] = BeamformerSamplingMode_4X,
+ [ZBP_SamplingMode_Bandpass] = BeamformerSamplingMode_2X,
+ };
+ bp->sampling_mode = zbp_sampling_mode_to_beamformer[header->sampling_mode];
+
+ bp->acquisition_kind = (BeamformerAcquisitionKind)header->acquisition_mode;
+ bp->decode_mode = (BeamformerDecodeMode)header->decode_mode;
+ bp->sampling_frequency = header->sampling_frequency;
+ bp->demodulation_frequency = header->demodulation_frequency;
+ bp->speed_of_sound = header->speed_of_sound;
+ bp->time_offset = header->time_offset;
+
+ bp->contrast_mode = (BeamformerContrastMode)header->contrast_mode;
+
+ if (header->channel_mapping_offset != -1) {
+ memory_copy(bp->channel_mapping, raw.data + header->channel_mapping_offset,
+ sizeof(*bp->channel_mapping) * bp->channel_count);
+ } else {
+ for EachIndex(bp->channel_count, it)
+ bp->channel_mapping[it] = it;
+ }
+
+ memory_copy(bp->xdc_transform.E, header->transducer_transform_matrix, sizeof(bp->xdc_transform));
+ memory_copy(bp->xdc_element_pitch.E, header->transducer_element_pitch, sizeof(bp->xdc_element_pitch));
+ // NOTE(rnp): ignores group count and ensemble count
+ memory_copy(bp->raw_data_dimensions.E, header->raw_data_dimension, sizeof(bp->raw_data_dimensions));
+ if (data_frame_count) *data_frame_count = header->raw_data_dimension[2];
+ //if (data_frame_count) *data_frame_count = header->raw_data_dimension[3];
+
+ bp->data_kind = (BeamformerDataKind)header->raw_data_kind;
+ raw_data->kind = header->raw_data_kind;
+ raw_data->compression_kind = header->raw_data_compression_kind;
+
+ if (header->raw_data_offset != -1) {
+ raw_data->bytes.data = raw.data + header->raw_data_offset;
+ if (raw_data->compression_kind == ZBP_DataCompressionKind_ZSTD) {
+ // NOTE(rnp): limitation in the header format
+ raw_data->bytes.length = raw.length - header->raw_data_offset;
+ } else {
+ raw_data->bytes.length = header->raw_data_dimension[0] * header->raw_data_dimension[1] *
+ header->raw_data_dimension[2] * header->raw_data_dimension[3];
+ raw_data->bytes.length *= beamformer_data_kind_byte_size[header->raw_data_kind];
+ }
+ }
+
+ // NOTE(rnp): only look at the first emission descriptor, other cases aren't currently relevant
+ {
+ ZBP_EmissionDescriptor *ed = (ZBP_EmissionDescriptor *)(raw.data + header->emission_descriptors_offset);
+ switch (ed->emission_kind) {
+
+ case ZBP_EmissionKind_Sine:{
+ ZBP_EmissionSineParameters *ep = (ZBP_EmissionSineParameters *)(raw.data + ed->parameters_offset);
+ bp->emission_parameters.kind = BeamformerEmissionKind_Sine;
+ bp->emission_parameters.sine.cycles = ep->cycles;
+ bp->emission_parameters.sine.frequency = ep->frequency;
+ }break;
+
+ case ZBP_EmissionKind_Chirp:{
+ ZBP_EmissionChirpParameters *ep = (ZBP_EmissionChirpParameters *)(raw.data + ed->parameters_offset);
+ bp->emission_parameters.kind = BeamformerEmissionKind_Chirp;
+ bp->emission_parameters.chirp.duration = ep->duration;
+ bp->emission_parameters.chirp.min_frequency = ep->min_frequency;
+ bp->emission_parameters.chirp.max_frequency = ep->max_frequency;
+ }break;
+
+ InvalidDefaultCase;
+ static_assert(ZBP_EmissionKind_Count == (ZBP_EmissionKind_Chirp + 1), "");
+ }
+ }
+
+ switch (header->acquisition_mode) {
+ case ZBP_AcquisitionKind_FORCES:{}break;
+
+ case ZBP_AcquisitionKind_HERCULES:{
+ ZBP_HERCULESParameters *p = (ZBP_HERCULESParameters *)(raw.data + header->acquisition_parameters_offset);
+ bp->transmit_receive_orientation = p->transmit_focus.transmit_receive_orientation;
+ bp->focal_vector.E[0] = p->transmit_focus.steering_angle;
+ bp->focal_vector.E[1] = p->transmit_focus.focal_depth;
+
+ bp->single_focus = 1;
+ bp->single_orientation = 1;
+ }break;
+
+ case ZBP_AcquisitionKind_UFORCES:{
+ ZBP_uFORCESParameters *p = (ZBP_uFORCESParameters *)(raw.data + header->acquisition_parameters_offset);
+ memory_copy(bp->sparse_elements, raw.data + p->sparse_elements_offset,
+ sizeof(*bp->sparse_elements) * bp->acquisition_count);
+ }break;
+
+ case ZBP_AcquisitionKind_UHERCULES:{
+ ZBP_uHERCULESParameters *p = (ZBP_uHERCULESParameters *)(raw.data + header->acquisition_parameters_offset);
+ bp->transmit_receive_orientation = p->transmit_focus.transmit_receive_orientation;
+ bp->focal_vector.E[0] = p->transmit_focus.steering_angle;
+ bp->focal_vector.E[1] = p->transmit_focus.focal_depth;
+
+ bp->single_focus = 1;
+ bp->single_orientation = 1;
+
+ memory_copy(bp->sparse_elements, raw.data + p->sparse_elements_offset,
+ sizeof(*bp->sparse_elements) * bp->acquisition_count);
+ }break;
+
+ case ZBP_AcquisitionKind_RCA_TPW:{
+ ZBP_TPWParameters *p = (ZBP_TPWParameters *)(raw.data + header->acquisition_parameters_offset);
+
+ memory_copy(bp->transmit_receive_orientations, raw.data + p->transmit_receive_orientations_offset,
+ sizeof(*bp->transmit_receive_orientations) * bp->acquisition_count);
+ memory_copy(bp->steering_angles, raw.data + p->tilting_angles_offset,
+ sizeof(*bp->steering_angles) * bp->acquisition_count);
+
+ for EachIndex(bp->acquisition_count, it)
+ bp->focal_depths[it] = inf32();
+ }break;
+
+ case ZBP_AcquisitionKind_RCA_VLS:{
+ ZBP_VLSParameters *p = (ZBP_VLSParameters *)(raw.data + header->acquisition_parameters_offset);
+
+ memory_copy(bp->transmit_receive_orientations, raw.data + p->transmit_receive_orientations_offset,
+ sizeof(*bp->transmit_receive_orientations) * bp->acquisition_count);
+
+ f32 *focal_depths = (f32 *)(raw.data + p->focal_depths_offset);
+ f32 *origin_offsets = (f32 *)(raw.data + p->origin_offsets_offset);
+
+ for EachIndex(bp->acquisition_count, it) {
+ f32 sign = Sign(focal_depths[it]);
+ f32 depth = focal_depths[it];
+ f32 origin = origin_offsets[it];
+ bp->steering_angles[it] = atan2_f32(origin, -depth) * 180.0f / PI;
+ bp->focal_depths[it] = sign * sqrt_f32(depth * depth + origin * origin);
+ }
+ }break;
+
+ InvalidDefaultCase;
+ }
+
+ }break;
+
+ default:{return 0;}break;
+ }
+
+ return 1;
+}
+
+function void
+stream_ensure_termination(Stream *s, u8 byte)
+{
+ b32 found = 0;
+ if (!s->errors && s->widx > 0)
+ found = s->data[s->widx - 1] == byte;
+ if (!found) {
+ s->errors |= s->cap - 1 < s->widx;
+ if (!s->errors)
+ s->data[s->widx++] = byte;
+ }
+}
+
+function str8
+zstd_decompress_data(Arena *arena, str8 raw)
+{
+ u64 requested_size = ZSTD_getFrameContentSize(raw.data, (u64)raw.length);
+ void *out = push_array_no_zero(arena, u8, requested_size);
+ str8 result = {.data = out};
+ u64 decompressed = ZSTD_decompress(out, requested_size, raw.data, (u64)raw.length);
+ if (decompressed == requested_size) result.length = requested_size;
+ return result;
+}
+
+function void *
+zbp_data_pointer(Arena *arena, ZBP_Data *raw, Stream path, u32 frame_number)
+{
+ void *result = 0;
+ if (raw->bytes.length == 0) {
+ // NOTE(rnp): strip ".bp"
+ stream_reset(&path, path.widx - 3);
+
+ b32 compressed = raw->compression_kind == ZBP_DataCompressionKind_ZSTD;
+ stream_append_byte(&path, '_');
+ stream_append_u64_width(&path, frame_number, 2);
+ stream_append_str8(&path, compressed ? str8(".zst") : str8(".bin"));
+ stream_ensure_termination(&path, 0);
+ str8 compressed_data = os_read_entire_file(arena, (char *)path.data);
+
+ str8 bytes = compressed_data;
+ if (compressed) {
+ bytes = zstd_decompress_data(arena, compressed_data);
+ if (!bytes.length)
+ die("failed to decompress data: %s\n", path.data);
+ }
+ result = bytes.data;
+ } else {
+ if (raw->compression_kind == ZBP_DataCompressionKind_ZSTD) {
+ str8 bytes = zstd_decompress_data(arena, raw->bytes);
+ result = bytes.data;
+ } else {
+ result = raw->bytes.data;
+ }
+ }
+ return result;
+}
diff --git a/tests/throughput.c b/tests/throughput.c
@@ -5,17 +5,7 @@
* [ ]: bug: we aren't inserting rf data between each frame
*/
-#define BASE_EXPORT function
-#define BASE_IMPORT function
-#define BEAMFORMER_LIB_EXPORT function
-#include "base_platform.h"
-#include "ogl_beamformer_lib.c"
-
-#include <signal.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <zstd.h>
+#include "test_common.c"
global iv3 g_output_points = {{512, 1, 1024}};
global v2 g_axial_extent = {{ 10e-3f, 165e-3f}};
@@ -30,352 +20,8 @@ typedef struct {
i32 remaining_count;
} Options;
-#include "external/zemp_bp.h"
-
-typedef struct {
- ZBP_DataKind kind;
- ZBP_DataCompressionKind compression_kind;
- str8 bytes;
-} ZBP_Data;
-
global b32 g_should_exit;
-#define die(...) die_((char *)__func__, __VA_ARGS__)
-function no_return void
-die_(char *function_name, char *format, ...)
-{
- if (function_name)
- fprintf(stderr, "%s: ", function_name);
-
- va_list ap;
-
- va_start(ap, format);
- vfprintf(stderr, format, ap);
- va_end(ap);
-
- os_exit(1);
-}
-
-#if OS_LINUX
-
-#include <fcntl.h>
-#include <sys/stat.h>
-#include <unistd.h>
-
-function str8
-os_read_file_simp(char *fname)
-{
- str8 result;
- i32 fd = open(fname, O_RDONLY);
- if (fd < 0)
- die("couldn't open file: %s\n", fname);
-
- struct stat st;
- if (stat(fname, &st) < 0)
- die("couldn't stat file\n");
-
- result.length = st.st_size;
- result.data = malloc((u64)st.st_size);
- if (!result.data)
- die("couldn't alloc space for reading\n");
-
- i64 rlen = read(fd, result.data, (u32)st.st_size);
- close(fd);
-
- if (rlen != st.st_size)
- die("couldn't read file: %s\n", fname);
-
- return result;
-}
-
-#elif OS_WINDOWS
-
-function str8
-os_read_file_simp(char *fname)
-{
- str8 result;
- iptr h = CreateFileA(fname, GENERIC_READ, 0, 0, OPEN_EXISTING, 0, 0);
- if (h == INVALID_FILE)
- die("couldn't open file: %s\n", fname);
-
- w32_file_info fileinfo;
- if (!GetFileInformationByHandle(h, &fileinfo))
- die("couldn't get file info\n", stderr);
-
- result.length = fileinfo.nFileSizeLow;
- result.data = malloc(fileinfo.nFileSizeLow);
- if (!result.data)
- die("couldn't alloc space for reading\n");
-
- i32 rlen = 0;
- if (!ReadFile(h, result.data, (i32)fileinfo.nFileSizeLow, &rlen, 0) && rlen != (i32)fileinfo.nFileSizeLow)
- die("couldn't read file: %s\n", fname);
- CloseHandle(h);
-
- return result;
-}
-
-#else
-#error Unsupported Platform
-#endif
-
-function void
-stream_ensure_termination(Stream *s, u8 byte)
-{
- b32 found = 0;
- if (!s->errors && s->widx > 0)
- found = s->data[s->widx - 1] == byte;
- if (!found) {
- s->errors |= s->cap - 1 < s->widx;
- if (!s->errors)
- s->data[s->widx++] = byte;
- }
-}
-
-function void *
-decompress_zstd_data(str8 raw)
-{
- u64 requested_size = ZSTD_getFrameContentSize(raw.data, (u64)raw.length);
- void *out = malloc(requested_size);
- if (out) {
- u64 decompressed = ZSTD_decompress(out, requested_size, raw.data, (u64)raw.length);
- if (decompressed != requested_size) {
- free(out);
- out = 0;
- }
- }
- return out;
-}
-
-function b32
-beamformer_simple_parameters_from_zbp_file(BeamformerSimpleParameters *bp, char *path, ZBP_Data *raw_data)
-{
- str8 raw = os_read_file_simp(path);
- if (raw.length < (i64)sizeof(ZBP_BaseHeader) || ((ZBP_BaseHeader *)raw.data)->magic != ZBP_HeaderMagic)
- return 0;
-
- switch (((ZBP_BaseHeader *)raw.data)->major) {
-
- case 1:{
- ZBP_HeaderV1 *header = (ZBP_HeaderV1 *)raw.data;
-
- bp->sample_count = header->sample_count;
- bp->channel_count = header->channel_count;
- bp->acquisition_count = header->receive_event_count;
-
- bp->sampling_mode = BeamformerSamplingMode_4X;
- bp->acquisition_kind = header->beamform_mode;
- bp->decode_mode = header->decode_mode;
- bp->sampling_frequency = header->sampling_frequency;
- bp->demodulation_frequency = header->sampling_frequency / 4;
- bp->speed_of_sound = header->speed_of_sound;
- bp->time_offset = header->time_offset;
-
- memory_copy(bp->channel_mapping, header->channel_mapping, sizeof(*bp->channel_mapping) * bp->channel_count);
- memory_copy(bp->xdc_transform.E, header->transducer_transform_matrix, sizeof(bp->xdc_transform));
- memory_copy(bp->xdc_element_pitch.E, header->transducer_element_pitch, sizeof(bp->xdc_element_pitch));
- // NOTE(rnp): ignores emission count and ensemble count
- memory_copy(bp->raw_data_dimensions.E, header->raw_data_dimension, sizeof(bp->raw_data_dimensions));
-
- bp->data_kind = (BeamformerDataKind)ZBP_DataKind_Int16;
- raw_data->kind = ZBP_DataKind_Int16;
- raw_data->compression_kind = ZBP_DataCompressionKind_ZSTD;
-
- read_only u8 transmit_mode_to_orientation[] = {
- [0] = (ZBP_RCAOrientation_Rows << 4) | ZBP_RCAOrientation_Rows,
- [1] = (ZBP_RCAOrientation_Rows << 4) | ZBP_RCAOrientation_Columns,
- [2] = (ZBP_RCAOrientation_Columns << 4) | ZBP_RCAOrientation_Rows,
- [3] = (ZBP_RCAOrientation_Columns << 4) | ZBP_RCAOrientation_Columns,
- };
- if (header->transmit_mode >= countof(transmit_mode_to_orientation))
- return 0;
-
- bp->transmit_receive_orientation = transmit_mode_to_orientation[header->transmit_mode];
-
- ZBP_AcquisitionKind acquisition_kind = header->beamform_mode;
- if (acquisition_kind == ZBP_AcquisitionKind_FORCES ||
- acquisition_kind == ZBP_AcquisitionKind_HERCULES ||
- acquisition_kind == ZBP_AcquisitionKind_UFORCES ||
- acquisition_kind == ZBP_AcquisitionKind_UHERCULES)
- {
- bp->single_focus = 1;
- bp->single_orientation = 1;
- bp->focal_vector.E[0] = header->steering_angles[0];
- bp->focal_vector.E[1] = header->focal_depths[0];
- }
-
- if (acquisition_kind == ZBP_AcquisitionKind_UFORCES ||
- acquisition_kind == ZBP_AcquisitionKind_UHERCULES)
- {
- memory_copy(bp->sparse_elements, header->sparse_elements, sizeof(*bp->sparse_elements) * bp->acquisition_count);
- }
-
- if (acquisition_kind == ZBP_AcquisitionKind_RCA_TPW ||
- acquisition_kind == ZBP_AcquisitionKind_RCA_VLS)
- {
- memory_copy(bp->focal_depths, header->focal_depths, sizeof(*bp->focal_depths) * bp->acquisition_count);
- memory_copy(bp->steering_angles, header->steering_angles, sizeof(*bp->steering_angles) * bp->acquisition_count);
- for EachIndex(bp->acquisition_count, it)
- bp->transmit_receive_orientations[it] = bp->transmit_receive_orientation;
- }
-
- bp->emission_parameters.kind = BeamformerEmissionKind_Sine;
- bp->emission_parameters.sine.cycles = 2;
- bp->emission_parameters.sine.frequency = bp->demodulation_frequency;
- }break;
-
- case 2:{
- ZBP_HeaderV2 *header = (ZBP_HeaderV2 *)raw.data;
-
- bp->sample_count = header->sample_count;
- bp->channel_count = header->channel_count;
- bp->acquisition_count = header->receive_event_count;
-
- read_only BeamformerSamplingMode zbp_sampling_mode_to_beamformer[] = {
- [ZBP_SamplingMode_Standard] = BeamformerSamplingMode_4X,
- [ZBP_SamplingMode_Bandpass] = BeamformerSamplingMode_2X,
- };
- bp->sampling_mode = zbp_sampling_mode_to_beamformer[header->sampling_mode];
-
- bp->acquisition_kind = header->acquisition_mode;
- bp->decode_mode = header->decode_mode;
- bp->sampling_frequency = header->sampling_frequency;
- bp->demodulation_frequency = header->demodulation_frequency;
- bp->speed_of_sound = header->speed_of_sound;
- bp->time_offset = header->time_offset;
-
- bp->contrast_mode = header->contrast_mode;
-
- if (header->channel_mapping_offset != -1) {
- memory_copy(bp->channel_mapping, raw.data + header->channel_mapping_offset,
- sizeof(*bp->channel_mapping) * bp->channel_count);
- } else {
- for EachIndex(bp->channel_count, it)
- bp->channel_mapping[it] = it;
- }
-
- memory_copy(bp->xdc_transform.E, header->transducer_transform_matrix, sizeof(bp->xdc_transform));
- memory_copy(bp->xdc_element_pitch.E, header->transducer_element_pitch, sizeof(bp->xdc_element_pitch));
- // NOTE(rnp): ignores group count and ensemble count
- memory_copy(bp->raw_data_dimensions.E, header->raw_data_dimension, sizeof(bp->raw_data_dimensions));
-
- bp->data_kind = header->raw_data_kind;
- raw_data->kind = header->raw_data_kind;
- raw_data->compression_kind = header->raw_data_compression_kind;
-
- if (header->raw_data_offset != -1) {
- raw_data->bytes.data = raw.data + header->raw_data_offset;
- if (raw_data->compression_kind == ZBP_DataCompressionKind_ZSTD) {
- // NOTE(rnp): limitation in the header format
- raw_data->bytes.length = raw.length - header->raw_data_offset;
- } else {
- raw_data->bytes.length = header->raw_data_dimension[0] * header->raw_data_dimension[1] *
- header->raw_data_dimension[2] * header->raw_data_dimension[3];
- raw_data->bytes.length *= beamformer_data_kind_byte_size[header->raw_data_kind];
- }
- }
-
- // NOTE(rnp): only look at the first emission descriptor, other cases aren't currently relevant
- {
- ZBP_EmissionDescriptor *ed = (ZBP_EmissionDescriptor *)(raw.data + header->emission_descriptors_offset);
- switch (ed->emission_kind) {
-
- case ZBP_EmissionKind_Sine:{
- ZBP_EmissionSineParameters *ep = (ZBP_EmissionSineParameters *)(raw.data + ed->parameters_offset);
- bp->emission_parameters.kind = BeamformerEmissionKind_Sine;
- bp->emission_parameters.sine.cycles = ep->cycles;
- bp->emission_parameters.sine.frequency = ep->frequency;
- }break;
-
- case ZBP_EmissionKind_Chirp:{
- ZBP_EmissionChirpParameters *ep = (ZBP_EmissionChirpParameters *)(raw.data + ed->parameters_offset);
- bp->emission_parameters.kind = BeamformerEmissionKind_Chirp;
- bp->emission_parameters.chirp.duration = ep->duration;
- bp->emission_parameters.chirp.min_frequency = ep->min_frequency;
- bp->emission_parameters.chirp.max_frequency = ep->max_frequency;
- }break;
-
- InvalidDefaultCase;
- static_assert(ZBP_EmissionKind_Count == (ZBP_EmissionKind_Chirp + 1), "");
- }
- }
-
- switch (header->acquisition_mode) {
- case ZBP_AcquisitionKind_FORCES:{}break;
-
- case ZBP_AcquisitionKind_HERCULES:{
- ZBP_HERCULESParameters *p = (ZBP_HERCULESParameters *)(raw.data + header->acquisition_parameters_offset);
- bp->transmit_receive_orientation = p->transmit_focus.transmit_receive_orientation;
- bp->focal_vector.E[0] = p->transmit_focus.steering_angle;
- bp->focal_vector.E[1] = p->transmit_focus.focal_depth;
-
- bp->single_focus = 1;
- bp->single_orientation = 1;
- }break;
-
- case ZBP_AcquisitionKind_UFORCES:{
- ZBP_uFORCESParameters *p = (ZBP_uFORCESParameters *)(raw.data + header->acquisition_parameters_offset);
- memory_copy(bp->sparse_elements, raw.data + p->sparse_elements_offset,
- sizeof(*bp->sparse_elements) * bp->acquisition_count);
- }break;
-
- case ZBP_AcquisitionKind_UHERCULES:{
- ZBP_uHERCULESParameters *p = (ZBP_uHERCULESParameters *)(raw.data + header->acquisition_parameters_offset);
- bp->transmit_receive_orientation = p->transmit_focus.transmit_receive_orientation;
- bp->focal_vector.E[0] = p->transmit_focus.steering_angle;
- bp->focal_vector.E[1] = p->transmit_focus.focal_depth;
-
- bp->single_focus = 1;
- bp->single_orientation = 1;
-
- memory_copy(bp->sparse_elements, raw.data + p->sparse_elements_offset,
- sizeof(*bp->sparse_elements) * bp->acquisition_count);
- }break;
-
- case ZBP_AcquisitionKind_RCA_TPW:{
- ZBP_TPWParameters *p = (ZBP_TPWParameters *)(raw.data + header->acquisition_parameters_offset);
-
- memory_copy(bp->transmit_receive_orientations, raw.data + p->transmit_receive_orientations_offset,
- sizeof(*bp->transmit_receive_orientations) * bp->acquisition_count);
- memory_copy(bp->steering_angles, raw.data + p->tilting_angles_offset,
- sizeof(*bp->steering_angles) * bp->acquisition_count);
-
- for EachIndex(bp->acquisition_count, it)
- bp->focal_depths[it] = inf32();
- }break;
-
- case ZBP_AcquisitionKind_RCA_VLS:{
- ZBP_VLSParameters *p = (ZBP_VLSParameters *)(raw.data + header->acquisition_parameters_offset);
-
- memory_copy(bp->transmit_receive_orientations, raw.data + p->transmit_receive_orientations_offset,
- sizeof(*bp->transmit_receive_orientations) * bp->acquisition_count);
-
- f32 *focal_depths = (f32 *)(raw.data + p->focal_depths_offset);
- f32 *origin_offsets = (f32 *)(raw.data + p->origin_offsets_offset);
-
- for EachIndex(bp->acquisition_count, it) {
- f32 sign = Sign(focal_depths[it]);
- f32 depth = focal_depths[it];
- f32 origin = origin_offsets[it];
- bp->steering_angles[it] = atan2_f32(origin, -depth) * 180.0f / PI;
- bp->focal_depths[it] = sign * sqrt_f32(depth * depth + origin * origin);
- }
- }break;
-
- InvalidDefaultCase;
- }
-
- }break;
-
- default:{return 0;}break;
- }
-
- return 1;
-}
-
-#define shift_n(v, c, n) v += n, c -= n
-#define shift(v, c) shift_n(v, c, 1)
-
function void
usage(char *argv0)
{
@@ -437,8 +83,9 @@ execute_study(Arena *arena, Stream path, Options *options)
ZBP_Data raw_data = {0};
BeamformerSimpleParameters bp = {0};
- if (!beamformer_simple_parameters_from_zbp_file(&bp, (char *)path.data, &raw_data))
+ if (!beamformer_simple_parameters_from_zbp_file(arena, &bp, (char *)path.data, &raw_data, 0))
die("failed to load parameters file: %s\n", (char *)path.data);
+ stream_reset(&path, path_work_index);
v3 min_coordinate = (v3){{g_lateral_extent.x, g_axial_extent.x, 0}};
v3 max_coordinate = (v3){{g_lateral_extent.y, g_axial_extent.y, 0}};
@@ -494,30 +141,7 @@ execute_study(Arena *arena, Stream path, Options *options)
beamformer_set_global_timeout(1000);
- void *data = 0;
- if (raw_data.bytes.length == 0) {
- // NOTE(rnp): strip ".bp"
- stream_reset(&path, path_work_index - 3);
-
- stream_append_byte(&path, '_');
- stream_append_u64_width(&path, options->frame_number, 2);
- stream_append_str8(&path, str8(".zst"));
- stream_ensure_termination(&path, 0);
- str8 compressed_data = os_read_file_simp((char *)path.data);
-
- data = decompress_zstd_data(compressed_data);
- if (!data)
- die("failed to decompress data: %s\n", path.data);
- free(compressed_data.data);
- } else {
- if (raw_data.compression_kind == ZBP_DataCompressionKind_ZSTD) {
- data = decompress_zstd_data(raw_data.bytes);
- if (!data)
- die("failed to decompress data: %s\n", path.data);
- } else {
- data = raw_data.bytes.data;
- }
- }
+ void *data = zbp_data_pointer(arena, &raw_data, path, options->frame_number);
if (options->loop) {
BeamformerLiveImagingParameters lip = {