1% ldpc_gen_c_h_file.m 2% David Rowe Sep 2015, B. Van Slyke 2019 3% 4% Create .c and h files for use in LDPC decoders 5% 6% NOTE: You'll need to install the CML library as a number of functions involved 7% in LDPC use it. See ldpc.m for instructions in installing the CML 8% library. 9% 10% usage examples: 11% 12% 1/ Using codes defined in external files: 13% 14% octave:1> ldpc_gen_c_h_file("HRA_112_112.txt") 15% octave:1> ldpc_gen_c_h_file(""H_4096_8192_3d.mat") 16% 17% 2/ Using built in CML codes: 18% 19% octave:1> ldpc_gen_c_h_file("dvbs2", 0.6, 16200) 20% 21% Output: Two files with the same filename as the LDPC input, but with .c and .h 22% extensions. 23 24function ldpc_gen_c_h_file(varargin) 25 26 ldpc % load ldpc functions 27 ldpc_fsk_lib % for ldpc_encode 28 29 % Assuming cml has been installed in the users' home folder, which is the 30 % default install location 31 init_cml(); 32 33 if nargin == 0 34 printf("Error - you must specify a file containing the LDPC codes (e.g. HRA_112_112.txt).\n"); 35 return; 36 end 37 loadStr = varargin{1}; 38 39 max_iterations = 100; 40 decoder_type = 0; 41 % the tests are performed using BPSK modulation, but in practice codes can be used 42 % with other modulation, e.g. QPSK 43 mod_order = 2; modulation = 'BPSK'; mapping = 'gray'; 44 45 if strcmp(loadStr, "dvbs2") 46 rate = varargin{2}; 47 framesize = varargin{3}; 48 code_param = ldpc_init_builtin(loadStr, rate, framesize, modulation, mod_order, mapping); 49 n = code_param.ldpc_coded_bits_per_frame; 50 k = code_param.ldpc_data_bits_per_frame; 51 ldpcArrayName = sprintf("H_%d_%d",n,k); 52 includeFileName = strcat(ldpcArrayName, '.h'); 53 sourceFileName = strcat(ldpcArrayName, '.c'); 54 else 55 % The ldpc variable name may not be what we want for a file/variable names, but 56 % the load filename will be, so use it. 57 [~,ldpcArrayName,ext] = fileparts(loadStr); 58 includeFileName = strcat(ldpcArrayName, '.h'); 59 sourceFileName = strcat(ldpcArrayName, '.c'); 60 61 % Get the ext of the file first. If it's a txt, then do what we 62 % are doing. If .mat, then just load, knowing the variable is HRA 63 if strcmp(ext, '.mat') == 1 64 load(loadStr); 65 if exist("H") & !exist("HRA") 66 printf("renaming H to HRA...\n"); 67 HRA=H; 68 end 69 else 70 % When calling 'load' this way, it returns a struct. The code assumes the 71 % struct has one element, and the one/first element is the array 72 % to process 73 tempStruct = load(loadStr); 74 b = fieldnames(tempStruct); 75 ldpcArrayName = b{1,1}; 76 % extract the array from the struct 77 HRA = tempStruct.(ldpcArrayName); 78 endif 79 80 code_param = ldpc_init_user(HRA, modulation, mod_order, mapping); 81 end 82 83 code_length = code_param.coded_syms_per_frame; 84 85 % First, create the H file 86 f = fopen(includeFileName, "wt"); 87 printHeader(f, includeFileName, ldpcArrayName, mfilename()); 88 89 fprintf(f,"#define %s_NUMBERPARITYBITS %d\n", ldpcArrayName, rows(code_param.H_rows)); 90 fprintf(f,"#define %s_MAX_ROW_WEIGHT %d\n", ldpcArrayName, columns(code_param.H_rows)); 91 fprintf(f,"#define %s_CODELENGTH %d\n", ldpcArrayName, code_param.coded_syms_per_frame); 92 fprintf(f,"#define %s_NUMBERROWSHCOLS %d\n", ldpcArrayName, rows(code_param.H_cols)); 93 fprintf(f,"#define %s_MAX_COL_WEIGHT %d\n", ldpcArrayName, columns(code_param.H_cols)); 94 fprintf(f,"#define %s_DEC_TYPE %d\n", ldpcArrayName, decoder_type); 95 fprintf(f,"#define %s_MAX_ITER %d\n", ldpcArrayName, max_iterations); 96 fprintf(f,"\n"); 97 fprintf(f,"extern const uint16_t %s_H_rows[];\n", ldpcArrayName); 98 fprintf(f,"extern const uint16_t %s_H_cols[];\n", ldpcArrayName); 99 100 fclose(f); 101 102 103 % Then, the C file 104 f = fopen(sourceFileName, "wt"); 105 printHeader(f, sourceFileName, ldpcArrayName, mfilename()); 106 fprintf(f, "#include <stdint.h>\n"); 107 fprintf(f, "#include \"%s\"\n", includeFileName); 108 109 % clock out 2D array to linear C array in row order .... 110 fprintf(f,"\nconst uint16_t %s_H_rows[] = {\n", ldpcArrayName); 111 [r c] = size(code_param.H_rows); 112 for j=1:c 113 for i=1:r 114 fprintf(f, "%d", code_param.H_rows(i,j)); 115 if (i == r) && (j ==c) % weird, this does nothing 116 fprintf(f,"\n};\n"); 117 else 118 fprintf(f,", "); 119 end 120 end 121 end 122 123 fprintf(f,"\nconst uint16_t %s_H_cols[] = {\n", ldpcArrayName); 124 [r c] = size(code_param.H_cols); 125 for j=1:c 126 for i=1:r 127 fprintf(f, "%d", code_param.H_cols(i,j)); 128 if (i == r) && (j == c) 129 fprintf(f,"\n};\n"); 130 else 131 fprintf(f,", "); 132 end 133 end 134 end 135 136 fclose(f); 137endfunction 138 139function printHeader(f, includeFileName, ldpcArrayName, mFilename) 140 fprintf(f, "/*\n FILE....: %s\n\n", includeFileName); 141 fprintf(f, " Static arrays for LDPC codec %s, generated by %s.m.\n*/\n\n", ldpcArrayName, mFilename); 142endfunction 143