用Audio Precision 2722来检测音频系统的频响曲线,其中有一种方法是利用被检测设备中声音文件发出的频率作为扫频信号源,检测系统的实际频响效果。其中对这个扫频信号是有较为严格的要求。具体要求(参考外部扫描规则设置External Sweep Rules)如下:
1. 在扫描的源1中,选择模拟信号分析仪的读数值A通道的频率作为信号源。 起始频率为20Hz,终止频率为22kHz,中间频率采用是对数方式增长。但是这些具体的频率是多少呢,需要通过外部规则来设定。因此,需要打开"External Rules..."按钮,做详细设定。
在 External Sweep Setting窗口,包括起始条件(Start),中间读数(Data)和终止条件(End)三个部分。分别包括了具体设定的数值,允许的读数误差。 在以下几种情况下,才可能开始扫描(AP 2700系列产品用户手册第423页)。
起始值设置:
1. 信号源的输出在起始值+/-误差范围内;信号强度要超过设定的阈值;设定的读数1-6都稳定;信号源1的读数稳定超过1s。这几个条件中,所有条件均必须满足,才能开始扫描。
2. 信号源的输出在起始值+/-误差范围或以上:信号强度要超过设定的阈值;设定的读数1-6都稳定;信号源1的读数稳定在误差范围内或超出误差范围的时间超过1s。
3. 任意设定的读数点:源1的信号是不相关信号;信号强度要超过设定的阈值;设定的读数1-6都稳定。在此情况下收集的数据可能超出设定的起始值和终止值的范围。
数据间隔问题:
1. 源1的读数稳定在前一读数加数据间隔上;
2. 要采集的信号读数必须大于或等于设定的读数阈值;
3. 设定的读数1-6都稳定;
4. 信号源1的读数稳定在误差范围内或超出误差范围的时间超过1s。
读数阈值设定:此数值的设定主要是用来排除误差干扰信号。对于低于设定值的信号不做处理。
终止条件设定:
终止值及误差范围:当源1的测量读数在此范围时,会自动停止扫描。
从以上信息中得知,对于用作扫描信号的信号波形,并不是连续光滑的扫频曲线,而是基本上以1秒为单位的步长阶梯,并且这些频点是以对数频率步进。如果要扫描的范围是22Hz-22000Hz,则起始范围比1000,常用对数值为3。如果划分为30个频点,每个频点步长为常用对数0.1。如果划分为120个频点,则步长为0.025。如果更进一步,划分到150个频点,则步长为0.02。每个频点的最短时间为1s。假设其为1.1s,则需要扫描165s,外加10s的1kHz标准信号,则整个扫描过程最少需要175s才能完成。
在matlab上,可以用以下代码实现。
%以下程序中生成正弦波并播放。
Fs = 192000; % 采样频率
%写10s 1kHz数据
T = 10; % 时间长度
n = Fs*T; % 采样点数f = 1000; % 声音频率
nBitSize = 24; %量化精度(位深度)
y = sin(2*pi*f*T*linspace(0,1,n+1));
%sound(y,Fs); %播放音频数据
nStartFreq =20; %起始频率
nEndFreq=22000; %终止频率
nSteps=160; %共扫描160个数据点
nLastT=1.1; %每个频点延时1.1秒
nCount = Fs*nLastT;
nStepLog = log10(nEndFreq/nStartFreq)/nSteps; %频率增加的对数步距
for (nFreqLog =0:nSteps-1)
fFreq = nStartFreq*10^(nFreqLog*nStepLog) %实际扫描频点
y1=sin(2*pi*fFreq*nLastT*linspace(0,1,nCount+1)); %生成对应频率的正弦波数据,频率为计算的频点,时间1.1s y=[y,y1]; %生成的数据与前面的波形数据合并end
filename = 'd:\testfiles\Sweep_192K_24bit.wav';
audiowrite(filename, y, Fs, 'BitsPerSample',nBitSize,'Comment','Sweep_192K_24bit'); %保存声音文件。
info = audioinfo(filename);
info %显示音频文件的主要信息
msgbox('程序运行结束。');
程序运行后的显示结果如下(matlab 8.01 64位版本,运行时间7s):
info =
Filename: 'D:\TestFiles\Sweep_192K_24bit.wav'
CompressionMethod: 'Uncompressed'
NumChannels: 1
SampleRate: 192000
TotalSamples: 35712161
Duration: 186.0008
Title: []
Comment: 'Sweep_192K_24bit'
Artist: []
BitsPerSample: 24
使用matlab的最大好处在于读取和保存声音文件非常方便。目前使用audioread, audiowrite 和 audioinfo函数替代了早期的wavread和wavwrite等函数,把支持的音频文件的格式扩展到 WAV, OGG, FLAC,M4A,ALC等格式,全面支持24bit,32位,64位量化,以及各种采样率的归一化数据,为音频文件的处理提供了极大的灵活性。
使用 Audition 对该文件的频谱做分析如下:
整体频谱范围在20-22kHz,前面一段10s 1KHz。
局部放大后,可以看到每个频段的持续时间1S。在两个不同频点的连接处,可以看出频谱很广。
对波形数据做局部放大,可以看出,因为波形数据不连续,导致其频谱非常负载。
通过 matlab的强大运算能力,可以对音频数据的质量做分析。以下的程序段用于将音频数据文件读到系统中,然后进行FFT,获取信号的频谱。
%用fft方法分析 Wave波形文件的频谱
%y 为音频数据的存储数组,Fs为音频数据的采样率
%Pyy 用于保存音频的归一化幅度,Pyy_DB是转换为dBV以后的数值。
%info用来获取音频文件的详细信息,nBitSize是音频文件的采样率。
%nNormal 用于做归一化使用的常数,等于2^nBitSize。
%sigLength是音频文件的总采样个数,halfLength是总采样数的一半值。
%f是用于显示频率时的具体频点值。
%##########################################################clear; %清理当前内存变量clc; %清理命令窗口filename='D:\testfiles\1kHz_Sine_192kHz_24bit_2ch.wav';
[y,Fs]=audioread(filename);%读数据文件info = audioinfo(filename); %获取音乐文件信息nBitSize = info.BitsPerSample;%获取文件中采样深度
nNormal = 2^nBitSize; %做幅度归一化时的最大值
y=y(:,1); %仅使用双声道数据中的第一列(左声道数据)sigLength = length(y); %获取数组长度
%Y1 = y.*hanning(sigLength); %使用Hanning窗变换?操作失败,暂时去掉。
%完成FFT及获取幅度值,以及幅度值的对数表示法(dBV)Y=fft(y,sigLength); %做标准FFT变换Pyy = abs(Y)*2/sigLength/nNormal; %求取变换结果的幅值部分,并做归一化处理Pyy_DB = 10*log10(Pyy); %取常用对数,变成dBV单位。
%以下处理画图部分
halflength = floor(sigLength/2); %仅使用半长度做显示
f=Fs*(0:halflength)/sigLength; %生成索要用的频点
semilogx(f,Pyy_DB(1:halflength+1)); %画x轴对数曲线
title('1K-192kHz-24bit-2CH正弦波频谱'); %标题
xlabel('频率(Hz)'); %x轴标记
ylabel('dBV');
grid on; %打开网格
msgbox('Done'); %提示结束
实际运行的结果如下:
直接用Audition 生成的192KHz,24bit采样的正弦波,其频谱如下:
对比 44.1kHz采样率,16bit的1KHz Sine的MP3 频谱如下,可以看出增加了很多高次谐波分量。
直接用Audition 生成的44.1kHz 16bit, 1KHz Sine 的频谱,相对来说高频分量较MP3好很多。
目前这个算法还有一点问题,就是计算出来的幅度值严重偏离正常的设定值,还需要做进一步的修订。