matlab中文注释nmat2snd

来源:互联网 发布:js时间差计算器 编辑:程序博客网 时间:2024/06/03 17:26

不是很懂,粗浅理解。有误请指出

function w = lrcnmat2snd(nmat,synthtype,fs)%nmat 每行:  启始(拍数) 、 间隔(拍数)、声道、音高(dB)、速率、起始(时间sec)、间隔(时间sec)% Create waveform of NMAT using a simple% synthesisc通过midi文件格式nmat矩阵简单合成波形文件wav% w = nmat2snd(nmat,<synthtype>,<fs>,<f_min>,<f_max>) %波形数据=w';nmat输入矩阵,合成类型,采样频率% Create waveform of NMAT using a simple FM synthesis. The default sampling rate is % 22050 Hz and velocities are scaled to have默认采样频率22050Hz,速率最大为1% a max value of 1.%% SYNTHTYPE 'fm' (default) uses FM synthesis to approximate horn% sound.默认fm合成% SYNTHTYPE 'shepard' creates waveform of NMAT using Shepard tones. %使用shepard创建波形% These tones have also been %  called 'Circular tones' because they are specifically constructed to contain %  frequency components at octave intervals with an emphasis of the spectral %  components between 500Hz and 1000 Hz that effectively %  eliminates octave information (Shepard, 1964). %圆形音调,构造八度音程内的频率分量。重点为500-1000Hz的频谱成分%% Part of the code has been obtained from the work of Ed Doering.%  Ed.Doering@Rose-Hulman.Edu%% Input argument:%NMAT = notematrix矩阵%     SYNTHTYPE (Optional) = Synthesis type, either FM synthesis ('fm', default) %           or Shepard tones ('shepard')两个选择'fm'或者'shepard'%     FS (optional) = sampling rate (default 22050)采样频率设置%% Output:%Y = waveform返回波形数据,行存放%% Example 1: samples1 = nmat2snd(laksin);% Example 2: samples2 = nmat2snd(laksin,'shepard', 22050);%% Reference:%    Moore, F. R. (1990). Elements of Computer Music. New York: Prentice-Hall.%    Shepard, R. N. (1964). Circularity in judgements of %       relative pitch. Journal of the Acoustical Society of America, %       36, 2346-2353. %% Change History :% DateTimeProgNote% 29.9.200320:13TECreated under MATLAB 5.3 (PC)% 4/15/05           JBP added ability to specify number of partials in%                       tone, also shifted harmonic envelope such that tones are actually 3%                       semitones lower than desired. To fix, transpose input up by 3 semitones%                       (3 midi notes) to get correct pitch with better envelope.% 2.5.20059:30TEAlmost a total revision if the shepard function%�Part of the MIDI Toolbox, Copyright �2004, University of Jyvaskyla, Finland% See License.txtif isempty(nmat), return; end%如果没有待转换数据结束if nargin<3, fs = 22050; end%如果没有设置采样频率,启动默认设置22050hzif nargin<2, synthtype='fm'; end%如果没有设置合成方式,启动默认设置%%%%%%%%%%%%  WARNINGSsample_in_K = (fs*(1+nmat(end,6) + nmat(end,7)))/1024;%从开始到目前的采样点数/1024(采样频率*开始播放到播完这行的时间/1024)if sample_in_K<1000disp([num2str(sample_in_K,4) 'K samples']);elseif sample_in_K>1000    %TODO: this needs to be revised需要修正f=1;   while f==1%用于选择是否合成i = input([num2str(sample_in_K,4),'Ks of samples, synthesis may last for an extended period of time. \nDo you wish to continue? Y/N [Y]: '],'s');if isempty(i)    i = 'Y';%输入字符空,默认继续合成    f=2;%结束判断是否合成endswitch lower(i)   case 'y'%继续合成    f=2;%结束判断是否合成   case 'n'disp('synthesis cancelled')%取消合成y=[];f=2; return%程序结束返回  otherwise   disp([i,' is not a valid choice'])%无效输入y=[];%清空f=1;%继续判断是否合成输入end    endend   % END WARNINGS%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%switch lower(synthtype)          case 'fm'%fm合成% convert MIDI numbers to frequencies in Hz把nmat中数据转换成频率%notes 每行:开始时间nmat(:,6)(sec) 、时间间隔nmat(:,7)+0.01、频率(根据nmat(:,4)音高转换)、速率nmat(:,5) notes(:,1)=onset(nmat,'sec');%起始时间notes(:,2)=dur(nmat,'sec')+0.01;%时间间隔notes(:,3)=midi2hz(pitch(nmat));%音高获得的基频notes(:,4)=velocity(nmat);%速率% generate time vector for output waveform; end time is nearest integer% above the last note event time (give some extra room)%时间轴设置:时间轴间隔1/采样频率,只入不舍(最大的起始时间+最大的时间间隔减一轴时间轴间隔)tt=0:1/fs:ceil(max(notes(:,1))+max(notes(:,2)))-(1/fs);%ceil取整数,只入不舍% scale note velocities so max velocity is one速率调整为占最大速率的比例notes(:,4)=notes(:,4)/max(notes(:,4));% convert each note to a waveform, and add the waveform to the output waveformy=zeros(size(tt));%设置波形缓冲区大小for i=1:size(notes,1),   % convert note to waveform using the instrument defined by 'fncname'   w=feval('fmsynth',notes(i,2:4),fs); % 一个音符波形=函数feval根据时间间隔、频率、调整后速率、采样频率   % place waveform in the output file   ttint=round(notes(i,1)*fs)+1:round(notes(i,1)*fs)+length(w);%音符波形存放下标序列=(四舍五入(起始时间):四舍五入(起始时间+音符波形数据))   y(ttint)=y(ttint)+w;%这个音符波形存放进原来的后面end   w=y/4; %rescale to fit between -1 and +1 (4 is a conservative estimate)% play the sound if no output arguments, otherwise return the sound%if nargout<1%   soundsc(y,fs);%else%   out=y;%end          case 'shepard'%shepard合成notes = size(nmat,1);%音符个数duration =dur(nmat,'sec');%时间间隔pitchheight =pitch(nmat);%音高onsets=onset(nmat,'sec');%起始时间% create vector for output waveformtt=0:1/fs:ceil(max(onset(nmat,'sec'))+max(dur(nmat,'sec')+.01))-(1/fs);% convert each note to a waveform, and add the waveform to the output waveformy=zeros(size(tt));for i=1:notes   w=feval('shepardtone',pitchheight(i),duration(i),fs);%音高,时间间隔,采样频率   % place waveform in the output file   ttint=round(onsets(i)*fs)+1:round(onsets(i)*fs)+length(w);   y(ttint)=y(ttint)+w;end   w=y/30; %rescale to fit between -1 and +1 (30 is a conservative estimate)end%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%function y1=fmsynth(note,fs)% FM horn instrument (Moore p. 327)        %最基本的FMinstrument包括两个正弦曲线振荡器,        %一个是稳定不变的载波频率fc(CarrierFrequnecy)振荡器;        %一个是调制频率fm(ModulationFrequency)振荡器%单个音符的【时间间隔、频率、调整后速率】【采样频率】% note is in duration-frequency-amplitude format % (duration in seconds, frequency in Hz, amplitude usually between 0 and 1) %根据 间隔秒、频率Hz、振幅0~1三个参数% generate time vector生成时间向量du=note(1);%取这个音符的时间间隔tt=0:1/fs:du;fc = note(2);%carrier frequency取这个音符的频率h = 1;%harmonicity ratio调和比率fm = h*fc;%modulating frequency调制频率Imin=0;%minimum modulation index最小的调制指数Imaxmin = 5;%modulation index (max value above Imin)调制指数(最大值高于Imin)% envelopes包络        %[0      0      -1;        % 0.2    1      -1;        % 0.3    0.708  0;        %0.8    0.631   -1;        %1       0       0]最后一行数据用于对齐参数        %开始到结束的采样点时间比例               %幅值                           %单调/不单调?env=envelope([0 0 -1; 0.2 1 -1; 0.3 0.708 0; 0.8 .631 -1; 1 0 0],du,fs);%disp(['env ' num2str(size(env)) 'tt ' num2str(size(tt))])aa = note(3)*env; %载波振幅ii = Imin+Imaxmin*env;%调制振幅% output waveformy1 = aa.*sin(2*pi*fc*tt + ii.*sin(2*pi*fm*tt));%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%function y2=envelope(v,du,fs)            %矩阵(这个矩阵什么意思不懂),一个音符的时间间隔序列秒,采样频率hz% envelope function (Moore p. 184, and p. 514)%env=envelope(vlist,du,fs) accepts a matrix 'vlist' where each row is a triple indicating%  time (arbitrary units), value (usually between 0 and 1), and transition type.%  'du' is the envelope duration in seconds, and 'fs' is the sampling frequency in Hz.%%  See p. 184 and p. 514 of F. Richard Moore's text ("Elements of Computer Music", 1990, % Find the number of verticesnumv=size(v,1);%行数% Set the time column to occur over durationv(:,1)=(v(:,1)/v(numv,1))*du;%设置时间% Generate the envelope (guard against divide by zero error by adding% a small number to denominator)防止除以0生成包络。y2=[];for k=1:numv-1    ii=linspace(0,1,(v(k+1,1)-v(k,1))*fs);%k到k+1这段时间内,第i个点的采样比序列。i/这段时间采样点数   if v(k,3)==0      y2=[y2 linspace(v(k,2),v(k+1,2),size(ii,2))];%如果是单调,生成等间隔波加入原来   else      y2=[y2 v(k,2)+(v(k+1,2)-v(k,2))*(1-exp(v(k,3)*ii))/(1-exp(v(k,3)+1e-12))];              %y2=[y2 当前振幅+后前振幅差*(1-e^(k*比例)/(1-e^(k*1)))]    ;1e-12防止分母出现零  这个公式我没弄懂?假装懂           endend% Figure out how many samples are expected指出需要多少样本点nums=size(0:1/fs:du,2);% Figure out how many samples were generated指出多少个样本点生成numg=size(y2,2);% Pad or trim the vector as needed % (NOTE: This method is a bit of a kluge -- maybe someone can suggest a better% way!)样本点过多删除或者不够补零if numg<nums   y2=[y2 zeros(1,nums-numg)];elseif numg>nums   y2(nums+1:numg)=[];end%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%function s = shepardtone(pitch,dur,fs)            %一个音符:音高 间隔 采样频率            t = 0:1/fs:dur;%一个音符的时间            f = midi2hz(pitch);%由这个音符音高获得频率            u = zeros(size(t));%初始化点数                    % Thresholds for the spectra, Krumhansl & Kessler, 1982, p341: "loudness envelope over five-octave range (            %          from 77.8 Hz to 2349 Hz), which consisted of three parts: a gradually increasing section over the             %          first octave and a half, a constant section over the            %          middle two octaves, and a symmetrically decreasing            %          section over the last octave and a half. The            %          corresponding amplitude of the sine wave components            %          at each frequency was determined using the            %          amplitude-loudness curves of Fletcher and Munson            %          (1933), originally introduced by Shepard (1964).                        % Loudness envelope min and max (simpler version than suggested above)响度包络最小和最大            f_min=16;            f_max=20000;                        % Number of partials needed            f_max_part = min(f_max,fs/2);%基频最大小于采样周期的一半,各种文献说的            pl=ceil(log2(f_min/f));%只舍不入            ph=floor(log2(f_max_part/f));%四舍五入            partials = f*2.^(pl:ph);%个数ph-pl+1个                                    % Amplitudes            ampl = 1-cos(2*pi*(log(partials/f_min)./log((f_max)/f_min)));            ampl = ampl/(max(ampl));                        % Calculate waves for the partials            warning off            for j=1:length(partials)               u = u + ampl(j).*sin(2*pi*partials(j)*t);%估计随时间的幅度序列            end                        % Envelope            ramp=.1;%0.1            envelope(1:ramp*fs)=t(1:ramp*fs).*t(1:ramp*fs);%设置一秒采样频率的前十分一时间轴的平方            envelope(length(t)-ramp*fs+1:length(t))=fliplr(envelope(1:ramp*fs));%设置一秒采样频率的后十分一            envelope(ramp*fs:end-ramp*fs)=max(envelope);%中间设置十分之八设置为包络最大            factor=exp(1)/max(envelope);%一个系数因子             y=envelope.*factor;%包络幅度*系数因子 使得范围在0~e            s=y.*u;%包络幅度*随时间的幅度            warning on

1 0