Matlab:实时播放音频并显示波形

写在前面

以前的版本会出现音频播放与波形显示不同步的情况,且还需手动调整步长,并不能算是严格意义上的播放器。为此,在新版本中添加了定时器功能。
“最近整理音频相关的资料,有时候需要根据音频的波形来人为地判断哪一段数据是可取的,哪一段又是该删掉的。这个小问题却连续困扰了我多日:普通的音频播放软件只能流畅的播放音频,却无法显示数据波形. 为此,我利用Matlab编写一个小程序来解决这个问题。”

先看效果

如图所示:
在这里插入图片描述

随着音频的播放,窗口中有两个实时显示的图像:
第一个图像为整段音频的波形,红色部分为当前播放处的实时波形.
第二个图像聚焦于上图音频中的红色部分,用于查看实时波形的细节.

函数代码

两个子程序:
第一个为定时器结构;第二个为播放器。

% 定时器:播放窗口设置
function sound_timer(signal,player,half_space)
% 计算片段左右侧索引
left = player.CurrentSample - half_space;
right = player.CurrentSample + half_space;
left = max(1,left);
right = min(right,length(signal));
fragment = signal(left:right);
t = ([left:right]-1)/player.SampleRate;
if left<=1
    fragment = [zeros(1,right-left+1),fragment];
    t = [(2*left-right-1:left-1)/player.SampleRate,t];
end
if right>=length(signal)
    fragment = [fragment,zeros(1,right-left+1)];
    t = [t,(right+1:2*right-left+1)/player.SampleRate];
end
subplot(2,1,1)
plot(([1:length(signal)]-1)/player.SampleRate,signal,'k-')
hold on,plot(t,fragment,'r-')
set(gca,'xlim',([1 length(signal)]+[-1 1]*half_space)/player.SampleRate,'ylim',[min(signal) max(signal)]);
xlabel('时间/s')
ylabel('幅值')
subplot(2,1,2)
plot(t,fragment,'r-')
set(gca,'xlim',[t(1),t(end)],'ylim',[min(signal) max(signal)]);
xlabel('时间/s')
ylabel('幅值')
end

% 播放器
function sound_play(signal,fs,fragment)
warning off
if nargin<4
    fragment = length(signal)/fs/50;
end
player = audioplayer(signal,fs);
half_space = round(fragment*fs/2);
figure,set(gcf,'position',[680   673   683   305]);
subplot(2,1,1)
plot(([1:length(signal)]-1)/fs,signal,'k-')
set(gca,'xlim',([1 length(signal)]+[-1 1]*half_space)/fs,'ylim',[min(signal) max(signal)]);
xlabel('时间/s')
ylabel('幅值')
subplot(2,1,2)
set(gca,'xlim',([1 length(signal)]+[-1 1]*half_space)/fs,'ylim',[min(signal) max(signal)]);
xlabel('时间/s')
ylabel('幅值')
pause(fragment);
play(player);
my_timer = timer('BusyMode','drop','ExecutionMode', 'fixedSpacing', 'Period', fragment);
my_timer.StartDelay = 0;
my_timer.TimerFcn = @(~,~) sound_timer(signal,player,half_space);
start(my_timer)
pause(length(signal)/fs+2)
delete(my_timer)
end

运行示例:

clear;clc;close all;warning off
fs = 20000;
signal = sin(2*pi*1000*[0:4*fs]/fs)+randn(1,4*fs+1);
sound_play(signal,fs,0.1);

输入参数有三个,分别为音频信号(signal)、采样率(fs)、定时器时间(fragment);
其中,定时器时间可省略,定时器的时间设置越小,看起来越流畅,但对计算机内存的占用也越多.

2021/01/11

  • 18
    点赞
  • 89
    收藏
    觉得还不错? 一键收藏
  • 8
    评论
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值