% Return cell or mat array of values of tempered scales
% Возвращает простой или ячейковый массив значений темперированных звукорядов
% Copyright (c) 2008 Sasha Poltavsky (vasnas)
% more info at: http://www.vasnas.narod.ru
% 25.08.2008 г.

function y=tempered_scales(p_from, base_note, r_what, how_many, type_of_array, octavies)

% p_from        - 1st scale (tempered rows), 0-narural, 12-default
% how_many      - how many tempered scales produce with rows + 1
% base_note     - freqience of 1st note

% r_what        - returns array:
% - 'rows'      - frequencies of notes (default)
% - 'diff'      - differencies frequencies of from natural notes from base
% - 'ratio'     - raties to base note.

% type_of_array - 'array' (default), 'cell'
% octavies      - how many octavies produse, default - 1

% генерирование отсутствующих переменных
% defaults

if not(exist('p_from','var')); p_from=12; end
if not(exist('how_many','var')); how_many=1; end
if not(exist('base_note','var')); base_note=440; end
if not(exist('r_what','var')); r_what='rows'; end
if not(exist('type_of_array','var')); type_of_array='array'; end
if not(exist('octavies','var')); octavies=1; end

if (p_from < 0) || (p_from > 1000);p_from = 1;end
if ((how_many < 1) || (how_many > 1000));how_many = 1;end
if (base_note <= 0) || (how_many > 100000); base_note = 440;end
if (not(strcmp(r_what,'rows')) && not(strcmp(r_what,'diff')) && not(strcmp(r_what,'ratio'))); r_what='rows';end
if (not(strcmp(type_of_array,'mat')) && not(strcmp(type_of_array,'cell'))); type_of_array='mat';end


a=cell(how_many,1);             % прямоугольный массив для нот
v=a;                            % прямоугольный массив для отклонений нот от природного звукоряда
r=a;

an=ones(how_many*octavies,how_many); % прямоугольный массив для нот
an=an./0;                       % вместо нулей исключения, чтобы не рисовались эти векторы
vn=an;                          % прямоугольный массив для отклонений нот от природного звукоряда
rn=an;                          % прямоугольный массив для отношений нот к базовой

%temp_v=0; temp_v2=0;  % временные переменные

% формирование натурального звукоряда для сравнения с темперированными

n= [1 1.25   1.5   1.75   2   2.25   2.5   2.75   3   3.25   3.5   3.75   4   4.25   4.5   4.75   5   5.25   5.5   5.75   6];    % частоты натурального звукоряда от ля 440 Гц

n=n.*base_note;

if (p_from > 0) % если не натуральный


for i=p_from:(p_from + how_many - 1)    % пройти все звукоряды

    rows=i*octavies;                    % сколько рядов в стольких октавах

    ax=ones(1,i);                       % вектор для всех ступеней текущего ряда
    vx=ax; rx=ax;
    b=base_note;                        % 440 Гц - нота Ля - основание

    s=2^(1/i);                          % коэффициент геометрической прогрессии звукоряда
    rx(1,1)=1; rn(1,i - p_from +1)=1;   % отношение первой нотиы к самой себе 1/1=1

    for j=1:rows                       % пройти все ступени i ряда
       ax(1,j)=b;  an(j,i-p_from + 1)=b;   % частота

       b=b*s;                           % формирование следующей ноты
       rx(1,j+1)=rx(1,j)*s;
       rn(j+1,i - p_from +1)=rx(1,j)*s;
       temp_v= abs(n(1)- b);            % разница между нотой и основанием 440 Гц

       for k=1:5
           temp_v2= abs(n(k)- b);                   %перебираем в сравнении с натуральным звукорядом
            if temp_v <= temp_v2
                if temp_v < 0.01
                temp_v=inf; end    % не рисуем лишние октавные совпадения
                vx(1,j)= temp_v; vn(j,i-p_from + 1)= temp_v;     % записываем результат
            else
                if temp_v2 < 0.01
                    temp_v2=inf;
                end
             vx(1,j)= temp_v2; vn(j,i-p_from + 1)= temp_v2;    % записываем результат
             if temp_v2 < abs(n(k+1)- b)            % если удаляемся от ближайшей ноты то прерываем удаление
                break
             end
            end
       end
    end

a(i - p_from +1,1)={ax};
v(i - p_from +1,1)={vx};
r(i - p_from +1,1)={rx};
end

elseif (p_from == 0) % если натуральный
r=[1 1.25 1.5 1.75 2];
a=r.*base_note;
v=[0 0 0 0 0];
an=a;
vn=v;
rn=r;
end



if strcmp(r_what,'rows')
    if strcmp(type_of_array,'cell')
        y=a;
    elseif strcmp(type_of_array,'mat')
        y=an;
   end
elseif strcmp(r_what,'diff')
  if strcmp(type_of_array,'cell')
        y=v;
    else
        y=vn;
  end
elseif strcmp(r_what,'ratio')
  if strcmp(type_of_array,'cell')
        y=r;
    else
        y=rn;
  end
end
Сайт управляется системой uCoz