吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 3833|回复: 24
收起左侧

[其他原创] 【Matlab】音乐跳动条特效分析与模仿

  [复制链接]
jjjzw 发表于 2021-8-29 03:39
本帖最后由 jjjzw 于 2021-9-5 14:05 编辑

一、频谱图分析

无意中在b站看到有up在某项目中实现了常见的音乐跳动特效,想到这就是音频的频谱图,于是想试着分析并模仿这种特效的制作。

3413336-86a41b9d1dc09a92.png

所谓频谱图,即以横轴纵轴的波纹方式,记录画出信号在各种频率的图形资料。横轴为频率,纵轴为强度,即信号在这个频率的能量是多还是少。符合认知的是,当观察音乐特效时,高音部分出现后右边的音乐条会变高,左边会变低,是不同频率强度不同导致的。

因此要得到会变化的特效图,只要不断地画频谱图即可。因为同步和计算力的原因,我设计每次画出0.2秒信号的频谱图,0.2秒更新一次。

为了得到0.2秒的频谱,我使用快速傅立叶变换(FFT)。

3413336-6e1b46bbdf34354c.png

二、Matlab实现

(随便下载一首歌"汪苏泷 - 年轮.mp3")

%% begin
clc;
clear;
close all;

%% settings
div = 0.2; % 设置间隔

%% read file
[y, Fs] = audioread("汪苏泷 - 年轮.mp3");
T = 1/Fs;
L = length(y)-mod(length(y),2); % 防止索引报错
t = (0:L-1)*T;
l = div*Fs;

%% play music
sound(y,Fs);

%% FFT
for i=1:L/(l-1)
    t1 = clock; % 计时
    x = y(i*l:(i+1)*l);
    FFT(x,l,Fs); % 变换、绘画
    t2 = etime(clock,t1); % 计时
    pause(div-t2); % 确保0.2秒同步,同时给电脑绘画的时间
end

function [] = FFT(x,l,Fs) % 对0.2秒信号进行FFT
Y = fft(x);
P2 = abs(Y/l);
P1 = P2(1:l/2+1);
P1(2:end-1) = 2*P1(2:end-1);
f = Fs*(0:(l/2))/l;
plot(f,P1); % 绘画频谱图
axis([1e3 2.5e4 0 0.15]);
end

效果:
1971630174908_.pic.jpg

看得出来不是很好,原因在于低频太多,强度太大,因此用高通滤波器滤掉这部分。用工具设计一个巴特沃斯高通滤波器,滤掉0-1500Hz左右的频率。

1961630174763_.pic_hd.jpg

function Hd = btw
%BTW 返回离散时间滤波器对象。

% MATLAB Code
% Generated by MATLAB(R) 9.8 and Signal Processing Toolbox 8.4.
% Generated on: 29-Aug-2021 01:48:30

% Butterworth Highpass filter designed using FDESIGN.HIGHPASS.

% All frequency values are in Hz.
Fs = 44100;  % Sampling Frequency

Fstop = 1000;        % Stopband Frequency
Fpass = 2000;        % Passband Frequency
Astop = 80;          % Stopband Attenuation (dB)
Apass = 1;           % Passband Ripple (dB)
match = 'stopband';  % Band to match exactly

% Construct an FDESIGN object and call its BUTTER method.
h  = fdesign.highpass(Fstop, Fpass, Astop, Apass, Fs);
Hd = design(h, 'butter', 'MatchExactly', match);

% [EOF]

在源代码中添加:

%% HPF
Hlp = btw;
y1 = filtfilt(Hlp.sosMatrix, 1, y);

效果图:

2001630175082_.pic.jpg

这次就好看很多。完整代码:

%% begin
clc;
clear;
close all;

%% settings
div = 0.2;

%% read file
[y, Fs] = audioread("汪苏泷 - 年轮.mp3");
T = 1/Fs;
L = length(y)-mod(length(y),2);
t = (0:L-1)*T;
l = div*Fs;

%% HPF
Hlp = btw;
y1 = filtfilt(Hlp.sosMatrix, 1, y);

%% play music
sound(y,Fs);

%% FFT
for i=1:L/(l-1)
    t1 = clock;
    x = y1(i*l:(i+1)*l);
    FFT(x,l,Fs);
    t2 = etime(clock,t1);
    pause(div-t2);
end

function [] = FFT(x,l,Fs)
Y = fft(x);
P2 = abs(Y/l);
P1 = P2(1:l/2+1);
P1(2:end-1) = 2*P1(2:end-1);
f = Fs*(0:(l/2))/l;
plot(f,P1);
%axis([1e3 1.8e4 0 0.15]);
end

运行代码:

2021-08-29 02-38-28.2021-08-29 02_39_38.gif

三、进阶

到这里就只剩下采样和上色等事情了,不是Matlab需要做的(笑),要实现音乐条,只需要从FFT的横坐标(共20000个点)中均匀取十几个点,然后放上不同长度的矩形即可,这点计算量对电脑来说还是很轻松的。

要想把图形变得更好看一点,可以尝试带通滤波器,可以有效修饰两端不美观的部分。


免费评分

参与人数 5威望 +1 吾爱币 +23 热心值 +5 收起 理由
abcde1224 + 1 + 1 鼓励转贴优秀软件安全工具和文档!感谢楼主分享,想转载
xianyuamiao123 + 1 + 1 学废了学废了
zrf1980 + 1 + 1 我很赞同!
苏紫方璇 + 1 + 20 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
Atnil + 1 谢谢@Thanks!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

 楼主| jjjzw 发表于 2021-8-29 03:47
网上搜寻一番教程都是用库解决的,在此记录一下设计实现思路
 楼主| jjjzw 发表于 2021-9-5 14:04
xiaoyu111 发表于 2021-9-5 13:44
for循环那里应该是1:L/l-1吧,y1有两个声道,最后一次循环分析到下一个声道的第一个0.2秒了

是我疏忽了,还是大佬思维缜密
吾爱石皮姐 发表于 2021-8-29 08:21
头像被屏蔽
mokson 发表于 2021-8-29 08:31
提示: 作者被禁止或删除 内容自动屏蔽
chuqi26 发表于 2021-8-29 09:43
谢谢分享,很厉害
sapin 发表于 2021-8-29 10:56
做得很好看,若是合并成柱状图肯定更好看~~
twostudy 发表于 2021-8-29 11:17
的确是个好办法,可以继续研究下。
szhanyutian 发表于 2021-8-29 11:42
谢谢分享,楼主辛苦了

能活学活用matlab软件,楼主应该是学工科的吧
 楼主| jjjzw 发表于 2021-8-29 11:53
szhanyutian 发表于 2021-8-29 11:42
谢谢分享,楼主辛苦了

能活学活用matlab软件,楼主应该是学工科的吧

是的通信学渣
zrf1980 发表于 2021-8-29 14:14
继续期待!
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-25 02:25

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表