You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
OpenAudio_ArduinoLibrary/docs/scripts/functions/buildNewNodes.m

376 lines
11 KiB

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(new_node_data(Iclass,:))
str = [str ','];
end
end
disp(str);
end
if nargout == 0
disp(' ');
disp(['Copy the text above into a spreadsheet (like myNodes.xlsx)']);
end
end
%% %%%%%%%%%%%%%%%%%%555
function [names, class_lines] = findClassNames(fname)
if isstruct(fname)
%assume it is output from Matlab's "dir"
fname = [fname.folder '\' fname.name];
end
%load the file
all_lines = readAllLines(fname);
%find all of the class names
targ_str = 'class ';
names = {};
row_ind_class = [];
for Iline = 1:length(all_lines)
line = all_lines{Iline};
if length(line) >= 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