WAV文件格式的介绍:WAV文件是计算机中最常见的存放声音的格式,其扩展名为.wav。WAV文件以RIFF(Resource interchange file format)档案的格式存储,含有不定长度的文件头(header)和数据(data),组成不定长度的区块(chunk)和子区块(sub-chunks)。
WAV文件可以分为三个子区块(chunk):

分区名称 文件长度
RIFF chunk 12 bytes
”fmt” sub-chunk 可变长度, 16 bytes + extra
”data” sub-chunk 可变长度, size of sample data

辅助函数:将wav文件中读取的16进制转为10进制。

% A表示wav文件数据
% start表示起始位
% total表示总位数
% return 得到的十进制数
function tmp = add_helper(A,start,total)tmp = A(start+total-1);for i=total-2:-1:0tmp = tmp*16*16+A(start+i);end
end

(1)采样频率:也称采样速度或采样率。定义了声音信号在“模拟-数字”转化过程中,单位时间内从连续信号中提取并组成离散信号的采样个数。它用赫兹(Hz)表示。

%法一:matlab的audioread函数返回的第二个参数即为采样频率
[~,fs] = audioread([path,file]);%法二:直接读取wav文件的28位到25位四位数据即为采样频率
fs = add_helper(A,25,4);

(2)声道数:

%法一:matlab的audioread函数会将声道数转换为列数
channels_num = size(x,2);%法二:直接读取wav文件的24位到23位即为声道数
channels_num = add_helper(A,23,2);%在第24和23位,24位为高位

(3)样本位数:也称采样位数,即对声音的辨析度。8位或16位,8位采样将取样信号分为256份;16位采样将取样信号分为65536份。

%法一:通过matlab的库函数audioinfo读取
info = audioinfo([path,file]);
bits_per_sample =info.BitsPerSample;
disp(['采样位数为',int2str(bits_per_sample)]);%法二:直接读取wav文件的36位到35位两位即为样本位数
bits_per_sample = add_helper(A,35,2);

(4)求文件长:即音频文件所占用的内存空间,这里以KB为单位。

%法一:通过matlab的dir函数读取
D = dir([path,file]);
[file_length,file_length_type] = calculate_file_len(D.bytes);
fprintf('文件长为%.2f %s\n',file_length,file_length_type);%法二:直接计算得到文件长度,简单进行单位换算
[file_length,file_length_type] = calculate_file_len(length(A));
fprintf('文件长为%.2f %s\n',file_length,file_length_type);

(5)求数据长:即WAV文件中,data子区块所包含的数据的长度,也以KB为单位。

%法一:乘以2的原因是在调用audioread函数时matlab自动将2Byte数据转化为了一个数据,实际数据长度是x长度的两倍
fprintf('数据长为%.2fKB\n',2*length(x)/1024);%法二:直接读取WAV文件的78位到75位的四位数据即为数据部分的长度
data_length = add_helper(A,75,4);
[file_length,file_length_type] = calculate_file_len(data_length);
fprintf('数据长为%.2f %s\n',file_length,file_length_type);

(6)求数码率:表示单位时间(1秒)内传送的比特数bps(bit per second,位/秒),比特率越高质量越好,声音越饱满。码率=采样率×每次采样得到的样本位数×声道数。如果单位一般是k,码率(kbps)=码率(bps)/1000。

%波形数据传输速率(每秒平均字节数) = 采样频率 × 音频通道数 × 每次采样得到的样本位数 / 8
%比特率(kbs) = 波形数据传输速率 × 8 / 1000,除以1000是因为单位是k
kbps = fs * max_track_number * info.BitsPerSample / 8 * 8 / 1000;
fprintf('数码率为%.2f\n',kbps);

(7)求音频文件长度:音频持续的时间,可以通过数据长/采样率计算得到。

%法一:直接调用Matlab的Duration函数
fprintf('音频文件的长度为%.2f\n',info.Duration);%直接计算,单声道数据长度除以采样率即为音频文件长度
info.music_length = roundn(info.real_length/info.fs,-2);

(8)显示李萨如图形:(8)将两个声道的数据分别加至示波器的Y轴输入端和x轴输入端,将出现一个合成图形,这个图形就是李沙育图形。
李沙育图形随两个输入信号的频率、相位、幅度不同,所呈现的波形也不同。当两个信号相位差为90°时,合成图形为正椭圆,此时若两个信号的振幅相同的话,合成图形为圆;当两个信号相位差为0°时,合成图形为直线,此时若两个信号振幅相同则为与x轴成45°的直线 。

%因为李萨如图形是将信号以左声道作为x轴数据,以右声道数据作为y轴数据,因此至少要双声道
if channels_num >= 2figure('Name','李萨如图形','NumberTitle','off');plot(x(:,1),x(:,2));title('李萨图图形','FontSize',20);
end

(9)实现音频播放功能:

choice = input('请选择使用左声道1播放还是右声道2:');
%法一:通过audioplayer函数实现播放
player = audioplayer(x(:,choice),fs);
play(player)%该函数既可以实现播放
pause(player)%该函数既可以实现暂停播放
resume(player)%该函数可以实现暂停后恢复播放
stop(player)%该函数可以实现停止播放%法二:通过sound函数实现播放
sound(x(choice),fs);

(10)绘制波形图:

%法一:matlab的audioread函数会将声道数转换为列数
channels_num = size(x,2);
figure('Name','波形图形','NumberTitle','off');
for i = 1:track_numbersubplot(track_number,1,i);%横坐标表示序号,纵坐标表示归一化的频率值plot(x(:,i));title(['\fontsize{16}第',int2str(i),'声道']);
end

具体代码:
代码一:这个函数基本是通过调用matlab库函数实现的。
可以实现播放.wav文件;
可以选择文件;
显示波形图(单声道,双声道);
在波形图上显示声道数、采样频率、样本位数、文件长、数据长、数码率及音频文件长度等参数;
显示李沙育波形图;
可以选择声道播放。

clc;
clear;
close all;%这里请自己设置路径,这里是以打开文件夹自己选择文件的方式
[file,path] = uigetfile('语音素材/wav_file.wav','*.wav');
if isequal(file,0)disp('没有选择文件')
elsedisp(['选择了文件',file])
end
%fs为采样率
info = audioinfo([path,file]);
[x,fs] = audioread([path,file]);%最大声道数
channels_num = size(x,2);
choice = input('请选择使用左声道1播放还是右声道2还是双声道3:');
if choice == 1sound(x(:,1),fs);
elseif choice == 2sound(x(:,2),fs);
elsesound(x(:,1:2),fs);
end%选择声道数
track_number = input(['总声道数为',int2str(channels_num),'请输入需要的声道数:']);
while track_number>channels_numdisp(['超出范围',int2str(channels_num),'请重新输入']);track_number = input('请输入需要的声道数:');
endfigure('Name','波形图形','NumberTitle','off');
for i = 1:track_numbersubplot(track_number,1,i);%横坐标表示序号,纵坐标表示归一化的频率值plot(x(:,i));title(['\fontsize{16}第',int2str(i),'声道']);
endif channels_num >= 2figure('Name','李萨如图形','NumberTitle','off');plot(x(:,1),x(:,2));title('李萨图图形','FontSize',20);
end%%
%获取相关信息
disp(['采样率为',int2str(fs)]);disp(['声道数为',int2str(channels_num)]);%需要获取文件本身的内容
%typec = class(x);
%fprintf(['采样位数为',typec(1,4:end),'\n']);
disp(['采样位数为',int2str(info.BitsPerSample)]);%fprintf('音频文件的长度为%.2f\n',size(x,1)/fs);
fprintf('音频文件的长度为%.2f\n',info.Duration);D = dir([path,file]);
fprintf('文件长为%dKB\n',round(D.bytes/1024));%乘以2的原因是length(x)并不是真正数据的长度因为一个采样是需要16位,占两个byte
%而wav文件中给出的也是占用的byte数,而非通过audioread函数将16位数据自动换算为float
fprintf('数据长为%.2fKB\n',4*length(x)/1024);%波形数据传输速率(每秒平均字节数) = 采样频率 × 音频通道数 × 每次采样得到的样本位数 / 8
%比特率(kbs) = 波形数据传输速率 × 8 / 1000,除以1000是因为单位是k
kbps = fs * channels_num * info.BitsPerSample / 8 * 8 / 1000;
fprintf('数码率为%.2f\n',kbps);

代码二:代码二的bug是数据长度这里,因为不同的文件数据长度在wav文件中不一定是从75开始的4位数据。只是对当前文件适用,暂时没找到确定数据长度位置的方法。

clc;
clear;
close all;%获得数据长度
filepath = 'speaking.wav';%这里请自己设置路径
fileID = fopen(filepath);
A = fread(fileID);%声道数
info.channels_num = add_helper(A,23,2);%在第24和23位,24位为高位
fprintf('声道数为%d位\n',info.channels_num);
%采样频率
info.fs = add_helper(A,25,4);%从25位开始,持续4位
fprintf('采样频率为%d位\n',info.fs);
%取样位数
info.bits_per_sample = add_helper(A,35,2);
fprintf('取样位数为%d位\n',info.bits_per_sample);
%数据长度,因为这里有一个数据类型转换两个byte才被视为一个数据值
data_length = add_helper(A,75,4);
[info.data_length,info.data_length_type] = calculate_file_len(data_length);
fprintf('数据长为%.2f %s\n',info.data_length,info.data_length_type);
%文件长
[info.file_length,info.file_length_type] = calculate_file_len(length(A));
fprintf('文件长为%.2f %s\n',info.file_length,info.file_length_type);
%因为是将两字节数据视为1个数据,所以要除以2,因为只取一个声道故需要处理声道数
info.real_length = data_length/info.channels_num/2;
%音频长度
info.music_length = roundn(info.real_length/info.fs,-2);
fprintf('音频文件长度为%.2f s\n',info.music_length);
%与采样位数有关,多少Byte合成一位
val = info.bits_per_sample/8;
%左声道数据
left_wav = zeros(info.real_length/2/val,1);
%右声道数据
right_wav = zeros(info.real_length/2/val,1);for i = 0:info.real_length-1left_wav(i+1) = add_helper(A,79+i*4,2);right_wav(i+1) = add_helper(A,79+i*4+val,2);
end[x,fs] = audioread(filepath,'double');% figure;
% subplot(2,1,1)
% plot(left_wav);
% subplot(2,1,2)
% plot(right_wav);Hex_A = dec2hex(A);% A表示wav文件数据
% start表示起始位
% total表示总位数
% return 得到的十进制数据
function tmp = add_helper(A,start,total)tmp = A(start+total-1);for i=total-2:-1:0tmp = tmp*16*16+A(start+i);end
end% A表示wav文件数据
% return file_length表示文件长度
% return len_type表示长度对应类型,有B,KB,MB,GB
function [len,len_type]=calculate_file_len(native_A)len = native_A;len_index = 1;len_list = {'B','KB','MB','GB'};while len >= 1024len = len/1024;len_index = len_index+1;end%保留两位小数len = roundn(len,-2);len_type = len_list{len_index};
end

代码三:
gui格式较为完整。
可以实现的功能如下:
1.数据部分显示音频文件的各项数据。

2.其他选项部分可以选择声道显示波形图异或是李萨如图形。

3.播放选项部分可以跟随动态显示图像。


已上传到我的资源。
有不足之处欢迎指出。

wav音频文件的提取和分析(matlab)相关推荐

  1. 从mp4中提取wav音频文件

    需求: 从mp4文件中提取wav音频文件 运行效果: mp4: 运行后脚本后提取出的wav文件 代码: import os.pathimport moviepy.editor as mpe# 导出格式 ...

  2. C语言解析WAV音频文件

    转载:http://www.cnblogs.com/LexMoon/p/wave-c.html 1.C语言解析WAV音频文件 代码地址: Github : https://github.com/Cas ...

  3. Windows Phone 8初学者开发—第21部分:永久保存Wav音频文件

    第21部分:永久保存Wav音频文件 原文地址:http://channel9.msdn.com/Series/Windows-Phone-8-Development-for-Absolute-Begi ...

  4. python音频频谱_Python 读取WAV音频文件 画频谱的实例

    Python 读取WAV文件 import wave import struct from scipy import * from pylab import * #读取wav文件,我这儿读了个自己用p ...

  5. 将wav音频文件转化为16k Hz 单通道的文件

    一般做语音分析16k Hz 单通道的文件就够了,这里介绍如何查看和转化wav文件的采样频率和通道数. 1. 查看wav文件的采样频率和通道数 这里用python查看 from scipy.io imp ...

  6. android 字节转wav,android开发:把一个byte数组转换成wav音频文件,并且播放

    ============问题描述============ 如题,byte数组转换成wav音频文件,并且播放,下面代码能生成data/data/com.example.playwav/cache/tem ...

  7. python音频频谱_Python读取WAV音频文件 画频谱的方法

    Python 读取WAV文件 import wave import struct from scipy import * from pylab import * #读取wav文件,我这儿读了个自己用p ...

  8. 如何用C语言编写wav读取函数,C++读取WAV音频文件的头部数据的实现方法

    C++读取WAV音频文件的头部数据的实现方法 前言: 在这里分享一下自己的心得,希望和大家一起分享技术,如果有什么不足,还请大家指正.写出这篇目的,就是希望大家一起成长,我也相信技术之间没有高低,只有 ...

  9. c语言 文件 long double 读取,读取*.wav音频文件

    1.wav音频文件的格式 wav文件由文件头和采样数据2部分组成. 文件头又分为RIFF(Resource Interchange File Format).WAVE文件标识段 和 声音数据格式说明段 ...

  10. java 双声道音频_java实现切割wav音频文件的方法详解【附外部jar包下载】

    本文实例讲述了java实现切割wav音频文件的方法.分享给大家供大家参考,具体如下: import it.sauronsoftware.jave.Encoder; import it.sauronso ...

最新文章

  1. 『中级篇』docker容器安装wordpress(37)
  2. linux 挂载网络文件系统,[arm-linux-FL2440挂载网络文件系统共享文件]
  3. mybatis中mysql流式读取_MyBatis读取大量数据(流式读取)
  4. 每次没事情的时候都去学校的活动室或者武术室
  5. java skip函数_【Java必修课】图说Stream中的skip()和limit()方法及组合使用
  6. github优秀前端项目分享(转)
  7. 解析Redis操作五大数据类型常用命令
  8. Android Studio开发学习 - 1. 添加Activity
  9. 战争论 —— 蓝田之战
  10. 解读对象存储九大关键特征
  11. apache不能解析php文件_解析漏洞
  12. matlab实现信号与系统中卷积的计算的两种方法
  13. ssm中小型酒店客房预订系统计算机毕业设计
  14. 政务云存储 备份方案_最佳的在线备份和云存储解决方案
  15. 记仇表情包在线生成源码
  16. access中如何画斜线_在Excel单元格中如何用斜线分割填写?
  17. 3D (Input) Sparse Convolution
  18. 励志短片:献给努力前行的你
  19. java读取qq邮箱_通过java给qq邮箱发送信息
  20. Ubuntu上遇到Failed to construct device ‘usb-ehci‘ instance #0

热门文章

  1. 28个数控编程代码大全,众多程序员呕心沥血的私货
  2. 学校网络认证服务器无响应,校园网常见问题
  3. 指数/对数/WIN10计算器
  4. Linux大棚版redis入门教程(推荐)
  5. 超详细的Redis入门教程
  6. php对接xenserver,XenServer虚拟机管理工具XenCenter安装配置图文教程
  7. vc 6.0下msdev错误
  8. 软件详细设计的几个参考模板
  9. SQL 数据表基本操作
  10. pom中子模块project报红,插件运行Process terminated