Image Framing Script - Used by the Transmitter for Frame Generation
The code loads the image to be transmitted and implements a segmentation process to store columns of the image in individual frames. These frames are constructed from a header which contains the preamble sequence and information fields, and the payload with appended padding. The padding ensures that all frames are of equal length.
The frame structure used is shown here:
General Frame Structure: [___Header___|_____________Payload_____________]
Normal Frame - with pad: [___Header___|__________Data_________|_Padding_]
When the data in a frame is less than the data field length:
Padding increases: [___Header___|______Data_____|_____Padding_____]
Contents
- Obtain Parameters Set in the Simulink Block Mask
- Declare Protocol Parameters
- Frame Header Structure
- Message Acquisition & Frame/ Padding Calculation
- Data Segmentation, Payload Creation & Frame Construction
- Software, Simulation Examples and Design Exercises Licence Agreement %%
- Audio Tracks used in Simulations Examples and Design Exercises
Obtain Parameters Set in the Simulink Block Mask
frm.filename = get_param(gcbh,'filename'); % obtain the filename of the image to be sent frm.binary_len = str2num( get_param(gcbh,'binary_len') ); % obtain the ASCII length and convert char type to num frm.fs = str2num( get_param(gcbh,'fs') ); % obtain the sampling rate and convert char type to num
Declare Protocol Parameters
% frame length declaration frm.frame_len = 1000; % total length of a frame % bit length declarations frm.seq_num_bit_len = 8; % # of bits in header - frame sequence number length frm.end_flag_bit_len = 1; % # of bits in header - end frame flag length frm.header_bit_len = 8; % # of bits in header - header length frm.payload_bit_len = 10; % # of bits in header - payload length frm.pad_bit_len = 9; % # of bits in header - padding length
Frame Header Structure
%-------------------------------------------------------------------------% % Frame Header- [preamble, sequence number, end flag, header length, % payload length, padding length] %-------------------------------------------------------------------------% % set the preamble in unipolar form - used at the beginning of each frame frm.preamble = [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1]; frm.preamble_len = length(frm.preamble); % calculate decimal length of the preamble sequence frm.preamble_pad_len = rem(frm.preamble_len,2); % determine if preamble requires padding frm.preamble_pad = zeros(1,frm.preamble_pad_len); % create padding to make preamble an even length (if required) % determine the length of the header from the individual field lengths frm.header_len = frm.preamble_len... % calculate the full length of the header (bits) + frm.preamble_pad_len... + frm.seq_num_bit_len... + frm.end_flag_bit_len... + frm.header_bit_len... + frm.payload_bit_len... + frm.pad_bit_len; frm.payload_len = frm.frame_len - frm.header_len; % calculate the # of available payload storage bits in a frame frm.data_len = 800; % set at this value to transmit one pixel column per frame %-------------------------------------------------------------------------% % convert decimal lengths of fields to binary and construct header frm.end_flag_low = 0; % declare data end flag low for all frames but last frm.end_flag_high = 1; % declare data end flag high for last frame frm.header_len_bits = de2bi(frm.header_len,frm.header_bit_len,'left-msb'); % convert decimal header length to binary representation frm.payload_len_bits = de2bi(frm.payload_len,frm.payload_bit_len,'left-msb'); % convert decimal payload length to binary representation frm.header_norm = [frm.preamble,... % construct normal frame header with end flag low frm.preamble_pad,... frm.end_flag_low,... frm.header_len_bits,... frm.payload_len_bits]; frm.header_final = [frm.preamble,... % construct final frame header with end flag high frm.preamble_pad,... frm.end_flag_high,... frm.header_len_bits,... frm.payload_len_bits];
Message Acquisition & Frame/ Padding Calculation
%-------------------------------------------------------------------------% % -Load image data % -Calculate length of data to be transmitted in bits % -Calculate # of frames required and pad lengths; three possibilities: % > Only one frame is needed to transmit data: % Either - [___Header___|__________Data_________|_Padding_] % Or - [___Header___|______Data_____|_____Padding_____] % % > More than one frame is needed; last frame's data field is full: % All Frames - [___Header___|__________Data_________|_Padding_] % % > More than one frame is needed; last frame's data field is not % full and requires a larger amount of padding: % Normal Frames - [___Header___|__________Data_________|_Padding_] % Last Frame - [___Header___|______Data_____|_____Padding_____] % %-------------------------------------------------------------------------% frm.input = load(frm.filename); % acquire the data to be sent frm.image_size = size(frm.input.image); % find the dimensions of the image frm.total_img_pixels = frm.image_size(:,1)*frm.image_size(:,2); % find the number of pixels in the image frm.pixels_bit_len = frm.total_img_pixels*frm.binary_len; % convert this length to a binary representation length frm.padding_len = frm.payload_len - frm.data_len; % calculate the # of padding bits required in a 'normal' frame frm.normal_frame_pad = randi([0 1], 1, frm.padding_len); % create variable and store normal frame padding frm.pad_bits_norm = de2bi(int8(frm.padding_len),frm.pad_bit_len,'left-msb'); % convert padding length to binary representation frm.header_norm = [frm.header_norm, frm.pad_bits_norm]; % append binary representation to normal frame header if frm.pixels_bit_len > frm.data_len % execute if the data to be transmitted is longer than the data length of one frame frm.final_data_bits = rem(frm.pixels_bit_len,frm.data_len); % calculate the amount of data that will be sent in the last frame if frm.final_data_bits > 0 % execute if the last frame's data does not exactly equal the data_len frm.no_of_frames = floor(frm.pixels_bit_len/frm.data_len) + 1; % calculate the # of frames required, including the additional last frame frm.final_frame_pad = randi([0 1], 1, frm.payload_len - frm.final_data_bits); % calculate the padding required for the last frame else frm.no_of_frames = floor(frm.pixels_bit_len/frm.data_len); % calculate the # of frames when the image data is exactly divisible by the data_len frm.final_frame_pad = frm.normal_frame_pad; % final frame padding is the same as a normal frame padding in this case end frm.pad_len_final = length(frm.final_frame_pad); % find decimal length of final frame padding frm.pad_bits_final = de2bi(frm.pad_len_final,frm.pad_bit_len,'left-msb'); % convert value to binary form frm.header_final = [frm.header_final, frm.pad_bits_final]; % append binary representation to final frame header else % execute if data to be transmitted can be sent using one frame frm.no_of_frames = 1; % set frame # to 1 if frm.pixels_bit_len == frm.data_len % execute if the data to be transmitted exactly fills the data_len space in the frame frm.one_frame_pad = frm.normal_frame_pad; % set the padding for this one frame equal to normal frame padding else % execute if the data to be transmitted is less than the data_len space in the frame frm.one_frame_pad = randi([0 1], 1, frm.payload_len-frm.pixels_bit_len); % create the larger padding required for this frame end frm.pad_len_one = length(frm.one_frame_pad); % find decimal length of the one frame padding frm.pad_bits_one = de2bi(frm.pad_len_one,frm.pad_bit_len,'left-msb'); % convert value to binary form frm.header_one = [frm.header_final, frm.pad_bits_one]; % append binary representation to final frame header; as one frame in this case is the final frame end
Data Segmentation, Payload Creation & Frame Construction
% convert decimal pixel values to a matrix of binary bits frm.binary_image = reshape(frm.input.image,1,frm.total_img_pixels)'; % reshape loaded data to a single column of data frm.binary_image = de2bi(frm.binary_image,frm.binary_len,'left-msb'); % convert decimal values to binary representations % reshape ascii matrix into a single vector frm.temp_storage = reshape(frm.binary_image',frm.pixels_bit_len,1)'; % reshape binary row representations to a single row of data frm.hasField = isfield(frm , 'master_frame'); % test to see if 'master_frame' already exists in the 'frm' structure if frm.hasField frm = rmfield(frm , 'master_frame'); % if it exists, remove it end for i = 1:1:frm.no_of_frames % loop for # of frames calculated earlier if frm.no_of_frames == 1; % if only one frame - construct frame with header_one and one_frame_pad frm.master_frame = [frm.header_one(1:frm.preamble_len+frm.preamble_pad_len),... % preamble sequence de2bi(i,frm.seq_num_bit_len,'left-msb'),... % convert frame number to binary representation for sequence number frm.header_one(frm.preamble_len+frm.preamble_pad_len+1:end),... % remaining header fields frm.temp_storage(1:end),... % all of the data to be transmitted in data field of frame frm.one_frame_pad]; % one frame padding else if i ~= frm.no_of_frames frm.temp_frame = [frm.header_norm(1:frm.preamble_len+frm.preamble_pad_len),... % preamble sequence de2bi(i,frm.seq_num_bit_len,'left-msb'),... % convert frame number to binary representation for sequence number frm.header_norm(frm.preamble_len+frm.preamble_pad_len+1:end),... % remaining header fields frm.temp_storage(((i-1)*frm.data_len)+1:i*frm.data_len),... % fill data_len field with a part of the image data frm.normal_frame_pad]; % normal frame padding else frm.temp_frame = [frm.header_final(1:frm.preamble_len+frm.preamble_pad_len),... % preamble sequence de2bi(i,frm.seq_num_bit_len,'left-msb'),... % convert frame number to binary representation for sequence number frm.header_final(frm.preamble_len+frm.preamble_pad_len+1:end),... % remaining header fields frm.temp_storage(((i-1)*frm.data_len)+1:end),... % fill data_len field with remaining image data frm.final_frame_pad]; % final frame padding end frm.master_frame(:,i) = frm.temp_frame; % store each generated frame in a master_frame variable end end clear('i'); % clear the frame # counter frm.master_frame_len = length(frm.temp_frame); % determine length of master frame %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Software, Simulation Examples and Design Exercises Licence Agreement %%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % This license agreement refers to the simulation examples, design % exercises and files, and associated software MATLAB and Simulink % resources that accompany the book: % % Title: Software Defined Radio using MATLAB & Simulink and the RTL-SDR % Published by Strathclyde Academic Media, 2015 % Authored by Robert W. Stewart, Kenneth W. Barlee, Dale S.W. Atkinson, % and Louise H. Crockett % % and made available as a download from www.desktopSDR.com or variously % acquired by other means such as via USB storage, cloud storage, disk or % any other electronic or optical or magnetic storage mechanism. These % files and associated software may be used subject to the terms of % agreement of the conditions below: % % Copyright © 2015 Robert W. Stewart, Kenneth W. Barlee, % Dale S.W. Atkinson, and Louise H. Crockett. All rights reserved. % % Redistribution and use in source and binary forms, with or without % modification, are permitted provided that the following conditions are % met: % % (1) Redistributions of source code must retain the above copyright % notice, this list of conditions and the following disclaimer. % % (2) Redistributions in binary form must reproduce the above copyright % notice, this list of conditions and the following disclaimer in % the documentation and/or other materials provided with the % distribution. % % (3) Neither the name of the copyright holder nor the names of its % contributors may be used to endorse or promote products derived % from this software without specific prior written permission. % % (4) In all cases, the software is, and all modifications and % derivatives of the software shall be, licensed to you solely for % use in conjunction with The MathWorks, Inc. products and service % offerings. % % THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS % "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT % LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR % A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT % HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, % SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT % LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, % DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY % THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT % (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE % OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. %
Audio Tracks used in Simulations Examples and Design Exercises
The music and vocal files used within the Examples files and software within the book were variously written, arranged, performed, recorded and produced by Garrey Rice, Adam Struth, Jamie Struth, Iain Thistlethwaite and also Marshall Craigmyle who collectively, and individually where appropriate, assert and retain all of their copyright, performance and artistic rights. Permission to use and reproduce this music is granted for all purposes associated with MATLAB and Simulink software and the simulation examples and design exercises files that accompany this book. Requests to use the music for any other purpose should be directed to: info@desktopSDR.com. For information on music track names, full credits, and links to the musicians please refer to www.desktopSDR.com/more/audio.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%