当前课程知识点:计算机音乐 > 第二章 时域音频处理 > 2.2 分窗处理1:OLA叠放 > 分窗处理1: OLA叠放
我们首先要介绍的是一种称之为分窗处理
或者说时窗分析的时域信号处理技术
音频信号是一种分布在时间轴上的信号
音乐作为音频信号的一种
也称之为构筑在时间上的建筑
只有随着时间的移动
音乐才能体现它原有的意义
因此我们不能单独的对音频信号中的
逐个采样点进行分析
同时由于不同的时间片段
又会包含不同的内容
因此我们也不太可能将音频信号
当作一个整体从头到尾的来处理
因此我们会把一个音频进行切割
通过这样的一种方式对音频进行窗口的切割
这样的一种处理
我们也把它叫做时窗处理
那么这些窗口之间可以有重叠
也可以没有重叠
如果我们做完这样的处理之后
我们就可以对每个窗口进行单独的分析
其中的一种分析方法就是
对这些窗口进行重新的一个排列
比如说首尾相接拼接起来
这样处理之后
这样的音频就会从原来的比较短的时间
变成比较长的时间
从而完成一个音频放慢一倍的一个效果
那么我们把这种处理就叫做OLA
Overlap and Add叠放的技术
我们可以在不改变音频信号的频率之下
去放慢或者加快音频
下面就让我们来看一下如何在程序中
来实现OLA叠放
那么在一开始我们像以前一样
还是先录制一段测试音频
I love music
那么接下来还是去掉首尾的静音的部分
那么然后我们给导出成一个音频wav文件
test wav文件
接下来我们首先来完成分窗的函数
比如说我们的名字叫做frame
那么它的功能是对于输入的信号X
以freamsize作为窗口的宽度
interva作为这个窗口的间隔
然后我们实现一个分窗函数
使得通过这个函数之后
可以输出一个窗口的列表
那么我们先记录一下输入信号的长度lenX
然后我们计算一下一共能够分多少个窗口
因为从第一个窗口到最后一个窗口的距离
应该是N减去freamsize
因为第一个窗口的大小是freamsize
那么他到最后一个窗口距离
应该是n减去freamsize
然后我们看一下这个距离
一共能够放得下多少个窗口
我们给它做一个整除这样的话
frameNUM能保证它是一个整数
这样的话我们就计算出一共有多少个窗口
接下来我们要输出的窗口frames
那么我们用np.zeros来进行一个初始化
当然它一共有那么多个窗口
每个窗口的长度是freamsize
所以我们先用np.zeros
来做一个这样的初始化
接下来我们就需要用一个for循环
把每一个窗口的取值给确定下来
那么第I个窗口我们去哪里截取
我们去X这样的输入信号里面去截取
它的起始坐标是i乘以interval
那么它结束坐标是起始坐标
再加上窗口的宽度
这样我们就完成了分窗的过程
最后我们只要把这个窗口
以及每个窗口的数据
那么我们用frames
每个窗口数据给进行一个return就可以了
那么接下来我们首先
读取一下刚才我们录制的这段
录制的这段音频
那么用Rx等于read
读取test wav
读取一下这段音频
读取之后我们要设定一下
要进行分窗的窗口的大小
比如说用512个点
然后interval是窗口的间隔
我们用半个窗口的间隔
然后我们就可以调用
fram函数进行分窗处理
等于说调用frames frameNUM调用frame函数
这样的话我们就进行了分窗的处理
那么接下来我们就需要
对这些窗口进行重新的一个排列
比如说我们让重新排列之后的
窗口间隔是原来的两倍
这样话就实现了我们刚才所说的
把窗口的间隔拉开
使得原来的数据拉长到原来的两倍
这样话它按理说应该是会把原来的
时间拉长
但是窗口内容并没有变化
这样的话我们希望通过这样的方式来实现
变速而不变调
那么新的间隔我们把定义成intervalc
然后根据新的窗口间隔
我们计算出新的数据的长度
应该是framesize再加上intervalc
乘以窗口的个数减1这样的这么多的采样点
然后我们去创建
去初始化这个要输出的数据
输出了信号Y
那么用NC个采样点来初始化这个输出的
输出的信号y
那么接下来就是去
按照新的间隔去放置这些窗口了
就是说对frameNUM窗口
我进行一个重新的放置
比如说第i个窗口应该放在intervalc
到起始位置是i乘intervalc
然后终止的位置应该是
起始位置再加上窗口的长度
那么在原来数据基础上
再加上从frames里面拿到的窗口的数据
那么最后我们需要做一个类型的转换
转换成标准的
NP下面的int16的形式
然后通过inport这个write
写到文件里面
比如说我们写到output.wav
然后写到RY里面
好 我们运行一下
运行完之后
我们就可以去听一下这个结果了
那么这是原始的输入的音频
以及这输出的音频
我们会听到它确实时间被拉长了一倍
也就是慢了一倍
但是这个声音过程中是有一点噪音的
这主要是我们在窗口拼接的过程中
没有进行任何处理
那么窗口与窗口之间的信号
不一定能够接起来
等于说他们在窗户与窗户之间
是断开的这样一个信号
那么断开的信号将会产生一个噪音
那么当窗口比较多的时候
这些噪音就会不间断的出现
那么产生我们刚才听到的效果
那么一种比较简单的处理方法
就是为每个窗口
增加一个我们叫做窗口包络
这样的一个曲线
那么也就是说
我们对每个窗口进行一个
淡入跟淡出的一个处理
保证窗口的两个边缘的信号的强度都是零
这样话窗口与窗口之间就能够
比较完美的拼接起来
让信号处于一个连续的状态
要做到这件事情
我们只需要去修改我们的分窗函数
在原来的基础之上
我们让他去乘上一个
叫做汉宁窗口的一个曲线
那么这汉宁窗口的函数
我们可以从np.hanning里面去获得
窗口大小是framesize
这样的一个汉宁窗口
然后我们去截取窗口同时
再去乘上这根首尾都是零的一个光滑的曲线
就可以了
我们在进行分窗的时候
我就使用了是新的分窗函数
就是by hanning窗口的分窗函数
但这里han是用负值
然后我们运行一下
听一下新的结果
OK
我们来听一下新的结果
他的边缘就变得更光滑一点
不会像第一个版本一样
有这样的噪音
好 新的版本
去除了这样的不间断的噪音
这就是我们使用分窗函数进行OLA叠加
所产生的变速而不变调的效果
在刚才的演示当中
我们将窗口的间隔加大一倍
进行重新的叠放
以达到时间拉长一倍的效果
同理我们也可以对窗口进行分割之后
进行重新的叠放
同时把窗口间隔缩短一倍
来达到缩短音频时间的效果
大家可以尝试一下
在刚才的程序的基础之上
把整个程序写成一个参数可调的变速器
在完成这一节的有关OLA叠放的学习之后
大家可以尝试一下
把刚才的程序写成一个参数可调的变速器
-欢迎辞
-1.1 计算机音乐导言
--计算机音乐导言
-1.2 计算机音乐课程主要内容
-1.3计算机音乐课程资源
-1.4 音乐的基本表达
--音乐的基本表达
-第一章作业
-2.1时域音频处理概述
--时域音频处理概述
-2.2 分窗处理1:OLA叠放
-2.3 分窗处理2:音量计算
-2.4 端点检测
--端点检测
-2.5 振幅包络
--振幅包络
-2.6 音频信号相乘
--音频信号相乘
-2.7 环形调制
--环形调制
-2.8 频率调制
--频率调制
-2.9 频率调制在音乐上的应用
-第二章作业
-3.1 频谱概述
--频谱概述
-3.2 傅里叶变换
--傅里叶变换
-3.3 短时傅里叶变换
--短时傅里叶变换
-3.4 加法合成
--加法合成
-3.5 线性滤波器
--线性滤波器
-3.6 京剧锣鼓经分析
--京剧锣鼓经分析
-第三章作业
-4.1 音色合成概述
--音色合成概述
-4.2 质点弹簧阻尼模型
--质点弹簧阻尼模型
-4.3 双线性滤波器
--双线性滤波器
-4.4 Modal合成
--Modal合成
-第四章测试
-5.1 一维振动模型概述
--一维振动模型概述
-5.2 弦振动模型
--弦振动模型
-5.3 达朗贝尔的行波解
--达朗贝尔的行波解
-5.4 梳状滤波器
--梳状滤波器
-5.5 Karplus Strong算法
-5.6 管状气鸣乐器模型
--管状气鸣乐器模型
-第五章作业
-6.1 音高跟踪概述
--音高跟踪
-6.2 时域音高跟踪
--时域音高跟踪
-6.3 频域音高跟踪
--频域音高跟踪
-6.4 K歌评分
--K歌评分
-第六章作业
-7.1 音频同步概述
--音频同步概述
-7.2 音乐特征提取 CQT
-7.3 音乐特征提取 Chroma
-7.4 动态时间规划概述
--动态时间规划概述
-7.5 动态时间规划实现
--动态时间规划实现
-第七章作业