首页 > 其他分享 >matlab中文注释nmat2snd

matlab中文注释nmat2snd

时间:2022-11-25 11:38:25浏览次数:40  
标签:采样 max fs envelope notes nmat 注释 matlab nmat2snd


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

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.
% [email protected]
%
% 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 :
% Date Time Prog Note
% 29.9.2003 20:13 TE Created 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.2005 9:30 TE Almost a total revision if the shepard function
%�Part of the MIDI Toolbox, Copyright �2004, University of Jyvaskyla, Finland
% See License.txt

if isempty(nmat), return; end%如果没有待转换数据结束
if nargin<3, fs = 22050; end%如果没有设置采样频率,启动默认设置22050hz
if nargin<2, synthtype='fm'; end%如果没有设置合成方式,启动默认设置

%%%%%%%%%%%% WARNINGS
sample_in_K = (fs*(1+nmat(end,6) + nmat(end,7)))/1024;
%从开始到目前的采样点数/1024(采样频率*开始播放到播完这行的时间/1024)

if sample_in_K<1000
disp([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;%结束判断是否合成
end
switch 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
end
end

% 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 waveform
y=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 waveform
tt=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 waveform
y=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 waveform
y1 = 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 vertices
numv=size(v,1);%行数

% Set the time column to occur over duration
v(:,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防止分母出现零 这个公式我没弄懂?假装懂
end
end

% 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


标签:采样,max,fs,envelope,notes,nmat,注释,matlab,nmat2snd
From: https://blog.51cto.com/datrilla/5886056

相关文章

  • matlab工具voicebox函数中文说明
    需要自己去下载文件解压到toolbox里面并设置路径方可使用Voicebox:在matlab使用的语音程序工具 一些文件使用加前缀"v_"避免命名冲突  音频文件输入或输出   ......
  • matlab带有自变量(参数)的累加求因变量
    这个代码需要小号很大的空间,如果数量大到一定的话,那么系统会内存占99%,然后电脑就宕机了。如果用时间换空间,那么多加及格循环就可以咯求解当t=0.5、0.75、1时函数f(t)=Σ......
  • matlab使用readmidi以后统计
    这个算法速度很慢就是了,更改算法后发现break和continue和我像的不一样,还是先保持这个全部遍历的clearall;[nmatnstr]=readmidi('再回首.mid');Cchannel=8;%统计nstr里面......
  • matlab注释分析高斯混合模型
    ​​Rachel-Zhang​​ 提供的源码。高斯混合模型没有输入参数判断,没有协方差是否可逆验证。我要用语音处理的,电脑卡死机,逆矩阵不是所有的都有的。或者用文库里面的代码​......
  • matlab纵向一维数组(向量)维数不一样尾部延展合成
    matlab纵向一维数据维数不一致合成两个语音波形数据简单合成一个试听播放sound(w,18000)sound(波形数据,采样频率)%两个维度不一样的纵向数组波形文件合成一个音轨%codeby......
  • matlab与C对照以及matlab之_极限_微分_积分_定积分
    名称matlabC++介绍脚本语言,类似科学计算器输入式子如果没有赋值默认赋值给ans,每条语句默认窗口输出计算结果编程语言,面向对象基于过程基本位置在.m文件(命令/函数文件)或命令......
  • matlab带UI界面编译成可执行文件问题汇总
    **********************************mcc全部直接无法使用我是下载的matlabR2014a然后出现mcc无法使用(即,随便一个file.m进行编译成可执行文件mcc-mfile.m都报错)我根据以......
  • matlab单帧频谱16个高斯混合拟合
    本来毕设是这个类型的(后来去了这个环节。总的来说也有所收获)看了各种论文,都是GMM-EM,概率论朝天。还会聚类分析预测一下,然后就是很多不懂的东西。我只知道我根据语音分析工具......
  • matlab倒计时启动录音
     本来毕设要用,后来没有用了function[y,fs2,noisy]=lrcrecorderV2(secs,fs,nbits,channel)%lrcrecorder根据采样频率fs和通道数channel录音lrcrecorderV2(secs,fs,nbit......
  • COCO-WholeBody 注释详解
    官方数据集说明:https://github.com/jin-s13/COCO-WholeBody1.如何预览json文件?使用Vscode,右键格式化文档即可。2.字段解读2.1关键字段之"images""images":[......