我有一个名为dissmeasure
的自定义函数,它从频率的输入向量输出标量。另一个名为music.tone2freq
的函数将整数转换为频率。
我的目标是为所有x,y整数对创建dissmeasure
的曲面图,其中X和Y等于[0:1:11]
。
看起来应该是这样的(这是mesh(X,Y, ones(12,12) )
):
从mesh docs开始,我尝试过的是:
[X,Y] = meshgrid(0:1:12)
Z = dissmeasure(music.tone2freq([X., Y.]))
但我得Error: Expression or statement is incorrect--possibly unbalanced (, {, or [.
。
Z = dissmeasure(music.tone2freq([X(:), Y(:)]))
但[X(:), Y(:)]
似乎没有正确的尺寸。此外,我接受向量的函数返回整个输入的一个标量。我需要的是多次退货。
请注意,dissmeasure(music.tone2freq([X(:), Y(:)]))
和dissmeasure(music.tone2freq([X, Y]))
都有效,但dissmeasure
的结果是单个标量数,而不是每个x,y对的此函数结果的矩阵。
有任何帮助吗?谢谢
tone2freq.m
function f = tone2freq(T)
% MUSIC.TONE2FREQ converts a musical semitone to a frequency.
% F = MUSIC.TONE2FREQ(T) converts the musical semitones in T to frequencies.
%
% Example
% f = music.tone2freq(0:2); % returns [261.63 277.19 293.67]
%
% See also music.tone2interval, music.tone2note, music.freq2tone.
% Author: E. Johnson
% Copyright 2010 The MathWorks, Inc.
fC4 = 261.625565300599; % Middle C (C4) is 261.63 Hz
f = fC4 .* 2 .^ (T / 12);
dissmeasure.m:
% calculate dissonace
% input param fvec - list of frequencies
% input param amp - list of amplitudes
% output is sum of dissonances of each pair of partials (scalar)
function d = dissmeasure(fvec, amp)
if ~exist('amp','var')
amp = ones(size(fvec));
end
Xstar = 0.24; % place with maximum dissonance
S1 = 0.0207; % to fit frequency dependend curves
S2 = 18.96; % so max. dissonance occures at 1/4 critical bandwidth
C1 = 5;
C2 = -5;
B1 = -3.51; % derived from model of Levelt & Plomp
B2 = -5.75;
N = length(fvec);
[fvec, idx_list] = sort(fvec); % sort partial frequencies ascending
amp = amp(idx_list); % rearrange amplitude values
%amp = loudness(amp);
D = 0;
for i=2:N
Fmin = fvec(1 : N-i+1); % get slice as list of Fmin
S = Xstar./(S1*Fmin+S2); % calc list of s-scalings with list of Fmin
% treat vector as tail and head ...
Fdif = fvec(i:N) - fvec(1:N-i+1); % build element wise difference
a = min(amp(i:N), amp(1:N-i+1)); % select element wise a minimum
Dnew = a .* (C1*exp(B1*S.*Fdif) + C2*exp(B2*S.*Fdif));
D = D + sum(Dnew); % sum up last D and vector elements
end
d=D;
答案 0 :(得分:1)
您的函数dissmeasure
不支持向量化操作,这意味着对于大小为N的输入,将为每个元素计算函数,并返回大小为N的输出。
相反,您的函数会返回汇总的不一致。
%assuming you have X and Y already converted
Z=X*0 % initialize Z of same size
for ix = 1:numel(X)
Z(ix)=dissmeasure(X(ix),Y(ix));
end