MATLAB利用MATLAB奏乐
Posted 记录无知岁月
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MATLAB利用MATLAB奏乐相关的知识,希望对你有一定的参考价值。
前言
最近在B站上看到一个用MATLAB播放音乐的视频【原视频链接】,虽然没有任何音乐知识背景,但是仍然对这一操作很感兴趣,于是就copy了up主的代码并和室友一起研究了一下,记录一下“研究成果”。
“研究成果”
-
sound()
函数:MTALAB中自带一个播放声音的函数,建议使用help指令查看相关用法。
-
从帮助中我们可以看出实际上MATLAB中给了一些小段音乐,可以使用指令
load
来调用,如load train
得到火车鸣笛的声音。因此我们可以试着用MATLAB播放音乐,方法就是首先读入mp3文件,得到波形数据和采样频率,然后用sound
函数播放。具体可以参考这个链接,感觉讲得很详细。 -
一些基本知识:一段声音的波形一般纵坐标为声音的响度(声压),有时候只需要看声音的趋势就会将其归一化,即所有的值映射到-1~1范围内。所以声音一般用正弦函数描绘,那一般看到的那种声音波形图实质上就是一段一段小的正弦波连接而成的,每一小段正弦波可以视为是一个音,每一个音的频率不一样,即所谓的音调,体现在波形上就是某一小段的频率是固定的(响度可能发生变化),但也有可能是一小段音频是多个频率的叠加,即多个不同频率的正弦波叠加,形成一个混合音。
然后是一些基本术语:采样频率相当于一个周期内采样的点数,可以理解为一个约定的播放时间差,这样就要求播放时间差在录入和输出时要保持一致,类似于异步通信协议的波特率。
采样位数:可以理解为A/D中的位数精度,即把-1~1分成多少小份,每一份对应一个值。体现为纵轴的分解程度,上面那个体现为横轴的分解程度。 -
了解声音的基本知识之后,下面就可以编写一个产生一个固定音调的函数了,下面是我在up主代码的基础上添加了一些内容。
function y = gen_wave( tone, rhythm ) %传入的参数中tone为音调,rhythm为音调持续时间
Fs = 8192; %设定的采样频率,播放时要和这个保持一致,否则音调会发生变化
freqs = [ 262, 294,330, 349, 392, 440, 494, 523, 587, 659, 698, 783, 880, 988, 1047,1175,1319,1397,1568,1760,1976,0,3520];
global speed;
rhythm = rhythm / speed; %设置播放速度,在音乐播放文件中需要再次声明speed,并给speed赋值
x = linspace(0, 2 * pi * rhythm, floor(Fs * rhythm));%持续时间为1s时为一个周期,其他时间以此类推,然后再将这个时间按照采样频率划分
if tone>=262
y = sin(tone * x) .*(1- x/(rhythm * 2 *pi)); %传入具体的音调
else
y = sin(freqs(tone) * x) .*(1- x/(rhythm * 2 *pi)); %按序号传输音调
end
%后面乘的是一个倒三角波,实现音量逐渐消失的效果,同时也可以避免相同音连续播放时不会只能听到一个声音
end
- 有时候播放时间太长想强行终止这段音乐,可以使用命令
clear sound
。 参考链接 - 如果需要两个音叠加,直接两个
sound
函数加上延时可以在一定程度上实现,但是最好的方式是两个音得到的波形图相加再除以2,然后再去播放。多个音同理。
如何利用matlab将数值拟合成函数
比如说x和y都各自由一组数值组成,现在想得到一个拟合函数F,y=F(x)...如何利用matlab来获得F呀。。谢谢。。
首先你得估计你的数据的走向 大致与那个函数像就用那个函数matlab里有多项式拟合函数polyfit
t=1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20;
ni=19 43 59 82 92 113 138 148 151 157 158 155 137 109 89 79 60 53 92 45;
t
目标函数Ni=10^(A-B*t)*加和Ni
i=1
求A、B的值
t=1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20;
ni=19 43 59 82 92 113 138 148 151 157 158 155 137 109 89 79 60 53 92 45;
p=polyfit(t,log10(Ni),1)
%由目标函数知,log10(Ni)与t成一次线形回归,求出其系数
p =
0.0058 1.8802
所以A=1.8802,B=-0.0058
和自定义拟合函数lsqcurvefit
matlab 非线性的拟合有两个命令lsqcurvefit和lsqnonlin。这里用lsqcurvefit(lsqnonlin一样做),先介绍下lsqcurvefit(原理是最小二乘法)
已知数据点:xdata=(xdata1,xdata2,…,xdatan)
ydata=(ydata1,ydata2,…,ydatan)
lsqcurvefit用以求含参量x(向量)的向量值函数
F(x,xdata)=(F(x,xdata1),…,F(x,xdatan))T
中的参变量x(向量),使得1/2*∑[a+b*exp(-0.02*k*t(i))-c(i)]^2最小
1.先定义个函数fun
function y=fun(x,tdata)
y=x(1)*gamma(1-x(2))*gamma(x(2))*cos(x(2)*pi/2)*(x(3)*tdata).^x(2);
保存一下
2调用解题
clc
x0=[0.05 0.1 0.05];
tdata=[0.06283 0.08118 0.1048 0.13534 0.17486 0.22581 0.29166];
ydata=[0.02797 0.04477 0.06839 0.101 0.145 0.2 0.27];
x=lsqcurvefit('fun',x0,tdata,ydata)
结果x =0.1163 1.3353 4.1766 即分别是A,n,B 参考技术A 你得先画个散点图,看大致成什么函数的图像
才能根据该函数
以上是关于MATLAB利用MATLAB奏乐的主要内容,如果未能解决你的问题,请参考以下文章