%   Uebung 9   Berechnung der Parameter der Grundfrequenzmodelle
% -----------------------------------------------------------------------
%   fuer die linguistischen Einflussfaktoren, die bestimmt werden in
%    a) get_F0_rule_conditions_frame.m   -->  F0Model0.mat
%    b) get_F0_rule_conditions.m         -->  F0Model1.mat
%    c) get_F0_rule_conditions_sol.m     -->  F0Model2.mat
% ----------------------------------------------------------------------------

clear all;


%   Prosodiekorpus laden
%---------------------------------------
%
corpfln = ['training_data.dat'];
disp('Laden der Trainingsdaten ... ');
if exist('.dur_train_data.mat', 'file'),
  load('.dur_train_data.mat');
else
  disp('(kann bis zu einer Minute dauern!)')
  [F,d, f0] = load_training_data(corpfln);
  save('.dur_train_data.mat','F','d', 'f0');
end


%   Grundfrequenz des Silbenkerns berechnen
%--------------------------------------------------
%
F0 = f0(phone_has_properties(F, 'nucleus'));

nucleusIndexes = find(phone_has_properties(F, 'nucleus')); 
numberOfNuclei = size(nucleusIndexes, 1);

%   Parameter der Grundfrequenzmodelle berechnen
%--------------------------------------------------
%
display('Berechne Grundfrequenzmodelle ... ');
%-----------------------------------------
for imod = 1:3
  if imod == 1
    rule_fln = 'get_F0_rule_conditions_frame';
  elseif imod == 2
    rule_fln = 'get_F0_rule_conditions';
  else
    rule_fln = 'get_F0_rule_conditions_sol';
  end 
 
  if exist('C','var') 
    clear('C');
  end
  if exist([rule_fln '.m'],'file'),
    disp('================================================================')
    disp(['Regelbedingungen mit "' rule_fln '" setzen ...']);
    %   Regelbedingungen berechnen    
    cmd = ['[C Cdesc] = ' rule_fln '(F);'];
    eval(cmd);
  end

  if exist('C','var')
    if size(C,1) ~= numberOfNuclei
      error(['*** Falsche Dimension der Matrix C! ' char(10) ...
             '    Die Anzahl der Zeilen in C muss mit der Anzahl ' char(10) ...
             '    der Silben in F uebereinstimmen.']);
    end  
    if sum(C(:,1)) ~= size(C,1)
      error(['*** alle Elemente der ersten Spalte der Matrix C ' char(10) ...
             '    muessen 1 sein!'])
    end
                          
    q0 = mean(F0);       % mittlere Grundfrequenz

    if size(C,2) > 1     % q ist die Loesung des ueberbestimmten 
      C1 = C(:,2:end);   % linearen Gleichungssystems: 
      q = C1\(F0-q0);    %      F0-q0 = q * C 
                         % mit dem kleinsten quadratischen Fehler
    else
      q = [];
    end
    F0mod.q = [q0; q];

    %   Fehler der Grundfrequenzmodelle berechnen
    %----------------------------------------------
    %
    F0mod.err = sqrt(sum(((F0-C*F0mod.q).^2))/length(F0));   
    fprintf('Mittlerer Fehler: %.4f Hz\n\n',F0mod.err);

    model_fln = ['F0Model' num2str(imod-1) '.mat'];
    disp(['Speichern des Grundfrequenzmodells fuer ' rule_fln char(10) ... 
          'in der Datei: ' model_fln]);
    save(model_fln,'F0mod');
    disp(' ')

    if ~isempty(C),
      %   Regelbedingungen nach Parametergroesse ordnen
      %--------------------------------------------------
      %
      [x qi] = sort(abs(F0mod.q));
      fprintf('Regelparameter  Regelbedingung\n');
      fprintf('  [Hz]                  \n');
      fprintf('-----------------------------------\n');
      for i = 1:length(qi),
        fprintf(' % 3.2f  \t%s\n',F0mod.q(qi(i)),Cdesc{qi(i)});
      end
    end
  end
end


