kopia lustrzana https://github.com/proto17/dji_droneid
69 wiersze
3.6 KiB
Matlab
69 wiersze
3.6 KiB
Matlab
% Read in complex IQ samples from the specified file
|
|
%
|
|
% @param input_file Path to input file. Must be string, char array, or cell string
|
|
% @param sample_offset How many complex samples to skip from the beginning of the file
|
|
% @param sample_count Number of samples after `sample_offset` to extract from the file. Must be -1 or inf to read all
|
|
% samples after `sample_offset` or > 0 to limit the number of samples read
|
|
% @param sample_type Data type of each real/imaginary value. Example: 'single' for 32-bit float, 'int16' for 16-bit
|
|
% shorts
|
|
% @return samples Samples read from the input file as a column vector of complex values
|
|
function [samples] = read_complex(input_file, sample_offset, sample_count, sample_type)
|
|
assert(isstring(input_file) || ischar(input_file) || iscellstr(input_file), ...
|
|
'Input file must be a string, char array, or cell string');
|
|
assert(isnumeric(sample_offset), 'Sample offset must be a number')
|
|
assert(sample_offset >= 0, 'Sample offset must be >= 0')
|
|
assert(isnumeric(sample_count) || isinf(sample_count), 'Sample count must be a number or `inf`');
|
|
assert(sample_count == -1 || sample_count > 0 || sample_count == inf, 'Sample count must be -1, inf, or > 0');
|
|
assert(isstring(sample_type) || ischar(sample_type) || iscellstr(sample_type), ...
|
|
'Sample type must be a string, char array, or cell string');
|
|
|
|
% Open the sample file and verify that was successful
|
|
file_handle = fopen(input_file, 'r');
|
|
assert(file_handle ~= -1, "Could not open input file '%s'", input_file);
|
|
|
|
try
|
|
% Create a value using the sample type
|
|
sample_type_example = cast(1, sample_type);
|
|
|
|
% Get information about the created variable
|
|
sample_type_info = whos('sample_type_example');
|
|
|
|
% Get the number of bytes in sample_type from the type info
|
|
bytes_per_real_sample = sample_type_info.bytes;
|
|
catch
|
|
error('Failed to determine byte size of type "%s"', sample_type);
|
|
end
|
|
|
|
% Get the total number of samples (reals and complex) in the file
|
|
fseek(file_handle, 0, 'eof');
|
|
total_real_samples = floor(ftell(file_handle) / bytes_per_real_sample);
|
|
total_complex_samples = total_real_samples / 2;
|
|
|
|
% Sanity check that the sample offset requested actually exists
|
|
assert(sample_offset < total_complex_samples, ...
|
|
"Asked for sample offset of %d, but there are only %d samples", sample_offset, total_complex_samples);
|
|
|
|
% Move the file handle to the starting sample offset (each real is 2 bytes, and a complex value is 4)
|
|
fseek(file_handle, sample_offset * (bytes_per_real_sample * 2), 'bof');
|
|
|
|
% If the user supplied -1 or inf update the sample count to include all remaining samples in the file
|
|
if (sample_count == -1 || sample_count == inf)
|
|
sample_count = total_complex_samples - sample_offset;
|
|
end
|
|
|
|
% Warn the user when asking for more samples than are available
|
|
if (sample_count + sample_offset > total_complex_samples)
|
|
warning('Attempting to read %d samples with an offset of %d when only %d total samples are available', ...
|
|
sample_count, sample_offset, total_complex_samples);
|
|
end
|
|
|
|
% Read in samples from the file. These come in as individual int16 values, not complex. Using an explicit cast
|
|
% here because MATLAB seems to treat everything as double precision floats unless told not to
|
|
real_samples = cast(fread(file_handle, sample_count * 2, sample_type), sample_type);
|
|
fclose(file_handle);
|
|
|
|
% Convert the interleaved samples into a column vector of complex values
|
|
samples = complex(real_samples(1:2:end), real_samples(2:2:end));
|
|
end
|
|
|