function [headings,new_node_data]=buildNewNodes(source_pname) %Look into directory of objects and build node info from the contents if nargin < 1 source_pname = 'C:\Users\wea\Documents\Arduino\libraries\OpenAudio_ArduinoLibrary\'; end %get all header files fnames = dir([source_pname '*.h']); %now look into each header file and find all class definitions all_class_names={}; all_num_inputs=[]; all_class_lines={}; for Ifile=1:length(fnames) [class_names,class_lines] = findClassNames(fnames(Ifile)); all_class_names(end+[1:length(class_names)]) = class_names; %all_num_inputs(end+[1:length(class_names)]) = num_class_inputs; all_class_lines(end+[1:length(class_lines)]) = class_lines; end %guess a shortname for each one all_short_names = guessShortName(all_class_names); %read (or estimate) the number of inputs and outputs [all_num_inputs, all_num_outputs]= getNumberOfInputsOutputs(all_class_names,all_class_lines); %guess the number of outputs %all_num_outputs = guessNumOutputs(all_class_names,all_num_inputs); %guess the category all_categories = guessCategory(all_class_names); %choose icon based on categories all_icons = chooseIcon(all_class_names,all_categories); %display results headings = {'type';'shortName';'inputs';'outputs';'category';'color';'icon'};new_node_data={}; for Iclass=1:length(all_class_names) new_node_data{Iclass,1} = all_class_names{Iclass}; new_node_data{Iclass,2} = all_short_names{Iclass}; new_node_data{Iclass,3} = all_num_inputs(Iclass); new_node_data{Iclass,4} = all_num_outputs(Iclass); new_node_data{Iclass,5} = all_categories{Iclass}; new_node_data{Iclass,6} = '#E6E0F8'; %default color new_node_data{Iclass,7} = all_icons{Iclass}; %default icon str=[]; for I=1:length(new_node_data(Iclass,:)) val = new_node_data{Iclass,I}; if isnumeric(val) str = [str num2str(val)]; else str = [str val]; end if I= length(targ_str) if strcmpi(line(1:length(targ_str)),targ_str) %this is a "class" statment %strip off the "class" part I=strfind(line,targ_str); line = line((I(1)+length(targ_str)):end); %find the end of the name, white or ':' I=find((line == ' ') | (line == ':')); if isempty(I); I=length(line); end name = line(1:I(1)); %strip off leading/trailing white space while (name(1) == ' ') %strip off leading white space name = name(2:end); end while (name(end) == ' ') %strip off trailing white space name = name(1:end-1); end while (name(end) == ';') %strip off trailing semicolon name = name(1:end-1); end while (name(end) == ':') %strip off trailing colon name = name(1:end-1); end %skip if class itself is AudioStream_F32 or AudioConnection_F32 if (strcmpi(name,'AudioStream_F32') | strcmpi(name,'AudioConnection_F32')) %ignore else %save the class name names{end+1} = name; row_ind_class(end+1) = Iline; end end end end %find the constructor for each class to find the number of inputs class_lines={}; num_class_inputs=zeros(length(row_ind_class),1); for Iclass = 1:length(row_ind_class) %extract the lines just for this class line_inds = row_ind_class(Iclass); if (Iclass < length(row_ind_class)) line_inds(2) = row_ind_class(Iclass+1); else line_inds(2) = length(all_lines); end class_lines{Iclass} = all_lines(line_inds(1):line_inds(2)); end end %end function %% %%%%%%%%%%%%%%%%%%% fu function [all_num_inputs, all_num_outputs]= getNumberOfInputsOutputs(all_class_names,all_class_lines) %first, look for comment that is a directive to the "GUI" about number of ins and outs all_num_inputs = NaN*ones(length(all_class_names),1); all_num_outputs = NaN*ones(length(all_class_names),1); for Iclass = 1:length(all_class_names) lines = all_class_lines{Iclass}; targ_str = '//GUI:'; GUI_lines = find(contains(lines,targ_str)); do_test = 1; for Iline=1:length(GUI_lines) if do_test line = lines{GUI_lines(Iline)}; targ_str = 'inputs:'; I=strfind(line,targ_str); if ~isempty(I) line = line((I(1)+length(targ_str)):end); I = strfind(line,','); all_num_inputs(Iclass) = str2num(line(1:I(1)-1)); line = line(I(1)+1:end); targ_str = 'outputs:'; I=strfind(line,targ_str); if ~isempty(I) line = line((I(1)+length(targ_str)):end); I = find((line == ',') | (line == '/')); line = line(1:I(1)-1); all_num_outputs(Iclass) = str2num(line); do_test = 0; %we've got our answer. end end end end end %now, do the old method if an answer is missing...look at constructor for inputs for Iclass = 1:length(all_class_names) if isnan(all_num_inputs(Iclass)) class_lines = all_class_lines{Iclass}; %find the constructor targ_str = all_class_names{Iclass}; I=find(contains(class_lines,targ_str)); if length(I) < 2 %disp(['*** WARNING ***: buildNewNodes: could not find constructor for ' names{Iclass}]); %disp([' : Number of audio inputs is unknown. Continuing...']); else constuctor_str = class_lines{I(2)}; %constructor should be first one after the name of the class %find the number of inputs...after AudioStream or AudioStream_F32 targ_str = 'AudioStream_F32('; I=strfind(constuctor_str,targ_str); if isempty(I) targ_str = 'AudioStream('; I=strfind(constuctor_str,targ_str); end if isempty(I) %disp(['*** WARNING ***: buildNewNodes: could not find inputs for ' names{Iclass}]); %disp([' : Number of audio inputs is unknown. Continuing...']); else str = constuctor_str((I(1)+length(targ_str)):end); I=find(str==','); all_num_inputs(Iclass) = str2num(str(1:I(1)-1)); end end end end %look for missing outputs, set equal to inputs for Iclass = 1:length(all_class_names) if isnan(all_num_outputs(Iclass)) all_num_outputs(Iclass) = all_num_inputs(Iclass); end end end %end function %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%55 function short_names = guessShortName(class_names) short_names={}; for Iname=1:length(class_names) name = class_names{Iname}; if strcmpi(name(1:5),'Audio') name = name(6:end); end if strcmpi(name(end-3:end),'_F32') name = name(1:end-4); end %strip off known pre-fixes strs = {'Control' 'Convert' 'Effect' 'Filter' 'Synth'}; for Istr=1:length(strs) str = strs{Istr}; if length(name) >= length(str) if strcmpi(name(1:length(str)),str) name = name((length(str)+1):end); end end end %handle special cases targ_str='Waveform'; %remove "Waveform" from "WaveformSine" if (length(name) > length(targ_str)) if strcmpi(name(1:length(targ_str)),targ_str) name = name((length(targ_str)+1):end); end end if strcmpi(name,'sgtl5000_extended') name = 'sgtl5000ext'; end %strop off leading space or underscore while( (name(1) == ' ') | (name(1) == '_')); name=name(2:end); end %strop off trailing space or underscore while( (name(end) == ' ') | (name(end) == '_')); name=name(1:end-1); end %adjust the case if strcmpi(name(1:3),'I16') | strcmpi(name(1:3),'F32'); %don't change the case else %do change the case name(1) = lower(name(1)); %remove any leading capital letter if strcmpi(name(1:3),'SGT') | strcmpi(name(1:3),'TLV') | strcmpi(name(1:3),'FIR') | strcmpi(name(1:3),'IIR') name=lower(name); %go all lower case; end end %save the name short_names{Iname} = name; end end %end function %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% function num_outputs = guessNumOutputs(class_names,num_inputs) num_outputs = num_inputs; %default rule % apply corrections for Iclass=1:length(class_names) name = class_names{Iclass}; if contains(name,'Mixer') num_outputs(Iclass) = 1; end end end %end function %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%5 function all_categories = guessCategory(class_names) all_categories={}; for Iname=1:length(class_names) name = class_names{Iname}; %strip off leading 'Audio' if strcmpi(name(1:5),'Audio') name = name(6:end); end %find the first capital letter *after* the leading capital expr = '[A-Z]'; capStartIndex = regexp(name,expr); if isempty(capStartIndex); Icap=length(name)+1; else if capStartIndex(1) == 1; Icap = capStartIndex(2); else Icap = capStartIndex(1); end; end expr = '[0-9]'; numStartIndex = regexp(name,expr); if isempty(numStartIndex) Inum = length(name)+1; else Inum = numStartIndex(1); end I = find(name == '_'); if isempty(I) Iund = length(name)+1; else Iund = I(1); end %get the category name = name(1:(min([Icap Inum Iund])-1)); name = lower(name); %convert to lower case %translate the category name to an existing one switch lower(name) case 'synth' name = 'synth'; case 'multiply' name = 'effect'; case 'divide' name = 'effect'; end %append "function" name = [name '-function']; %save the name all_categories{Iname} = name; end end %end function %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% function all_icons = chooseIcon(all_class_names,all_categories) all_icons = {}; for Iclass = 1:length(all_class_names) category = all_categories(Iclass); icon = 'arrow-in.png'; %default if strcmpi(lower(category),'control-function') icon = 'debug.png'; end all_icons{end+1} = icon; end end %end function