soundtouch 变速算法matlab实现
soundtouch变速主要采用WSOLA算法来进行变速。
http://www.surina.net/soundtouch/
https://blog.csdn.net/suhetao/article/details/5863477
The principle of WSOLA refer to following figure:
There are three important parameter: SequenceMs, overlapMs, seekWindowMs.
These parameters affect to the time-stretch algorithm as follows:
- DEFAULT_SEQUENCE_MS: This is the default length of a single processing sequence in milliseconds which determines the how the original sound is chopped in the time-stretch algorithm. Larger values mean fewer sequences are used in processing. In principle a larger value sounds better when slowing down the tempo, but worse when increasing the tempo and vice versa.
By default, this setting value is calculated automatically according to tempo value.
- DEFAULT_SEEKWINDOW_MS: The seeking window default length in milliseconds is for the algorithm that seeks the best possible overlapping location. This determines from how wide a sample "window" the algorithm can use to find an optimal mixing location when the sound sequences are to be linked back together.
The bigger this window setting is, the higher the possibility to find a better mixing position becomes, but at the same time large values may cause a "drifting" sound artifact because neighboring sequences can be chosen at more uneven intervals. If there's a disturbing artifact that sounds as if a constant frequency was drifting around, try reducing this setting.
By default, this setting value is calculated automatically according to tempo value.
- DEFAULT_OVERLAP_MS: Overlap length in milliseconds. When the sound sequences are mixed back together to form again a continuous sound stream, this parameter defines how much the ends of the consecutive sequences will overlap with each other.
This shouldn't be that critical parameter. If you reduce the DEFAULT_SEQUENCE_MS setting by a large amount, you might wish to try a smaller value on this.
function out = check_limits(in, min, max)
if in < min
out = min;
else if in > max
out = max;
else
out = in;
end
end
function [seekWindowLength, seekLength, overlapLength] = calcSeqParams(fs, tempo)
overlapMs = 8;
autoseq_tempo_low = 0.5;
autoseq_tempo_top = 2.0;
autoseq_at_min = 90;
autoseq_at_max = 40;
autoseq_k =(autoseq_at_max - autoseq_at_min) / (autoseq_temp_top - auto_temp_low);
autoseq_c = autoseq_at_min -autoseq_k * autoseq_temp_low;
autoseek_at_min = 20;
autoseek_at_max = 15;
autoseek_k =(autoseek_at_max - autoseek_at_min) / (autoseq_temp_top - auto_temp_low);
autoseek_c = autoseek_at_min -autoseek_k * autoseq_temp_low;
%calc sequenceMs
seq = autoseq_c + autoseq_k * tempo;
seq = check_limits(seq, autoseq_at_max, autoseq_at_min);
sequenceMs = round(seq);
seek= autoseek_c + autoseek_k * tempo;
seek= check_limits(seek, autoseek_at_max, autoseek_at_min);
seekMs = round(seek)
seekWindowLength = sequenceMs * fs / 1000;
seekLength = seekMs * fs /1000;
overlapLength = overlapMs * fs / 1000;
overlapLength = overlapLength - mod(overlapLength, 8);
end
function corr = calcCrossCorr(mixingSeg, compareSeg)
len = length(compareSeg(:,1));
corr = 0;
norm = 0;
for i = 1: 1 : len
corr = corr + mixingSeg(i) * compareSeg(i);
norm = norm + mixingSeg(i) * mixingSeg(i);
end
corr = corr / sqrt(norm);
end
function offset = seekBestOverlapPosition(seekWindow, compareSeg, overlapLength, seekLength)
bestCorr = calcCrossCorr(seekWindow(1:overlapLength, 1), compareSeg);
offset = 1;
for i = 2 : 1 : seekLength
corr = calcCrossCorr(seekWindow(i:i + overlapLength, 1), compareSeg);
if corr > bestCorr
bestCorr = corr;
offset = i;
end
end
end
function output = overlap(rampUp, rampDown)
len=length(rampDown);
for i = 1:1:len
output(i,1) = rampUp(i) * i / len + rampDown(i) * (len - i) / len;
end
end
function [output, outpos, lastCompare, inpos] = processSamples(input, inputLen, expectOutputLen, compareSeg, overlapLength, seekLength, seekWindowLength, tempo, isBeginning)
nominalSkip = tempo * (seekWindowLength - overlapLength);
sampleReq = max(round(nominalSkip) + overlapLength, seekWindow);
inpos = 1;
outpos = 1;
offset = 0;
skipFract = 0;
while inputLen - inpos >= sampleReq
if isBeginning == 0
offset = seekBestOverlapPosition(input(inpos : inpos + overlapLength + seekLength - 1, 1), compareSeg, overlapLength, seekLength);
output(outpos:outpos + overlapLength - 1, 1) = overlap(input(inpos + offset : inpos + offset + overlapLength - 1, 1), compareseg);
ouputpos = outpos + overlapLength;
offset = offset + overlapLength;
else
isBeginning = 0;
skip = round(tempo * overlapLength);
skipFract = skipFract - skip;
end
temp = (seekWindowLength - 2 * overlapLength);
if outpos + tmep < expectOutputLen
output(outpos : outpos + temp - 1, 1) = input (inpos + offset : inpos + offset + temp - 1, 1);
outpos = outpos + temp;
else
output(outpos : expectOutputLen, 1) = input (inpos + offset : inpos + offset + expectOutputLen- outpos, 1);
outpos = expectOutputLen;
beak;
end
compareSeg = input (inpos + offset + temp: inpos + offset + temp +overlapLength - 1, 1);
skipFract = skipFract + nominalSkip;
ovlSkip = floor(skipFract);
skipFract = skipFract - ovlSkip;
inpos = inpos + ovlSkip;
end
lastCompare = compareSeg;
end
function output = changeTempo(input, fs, tempo)
inputLen = length(input(:,1));
outputLen = round(inputLen / tempo);
output = zeros(outputLen, 1);
[seekWindowLength, seekLength, overlapLength] = calcSeqParams(fs, tempo);
isBeginning = 1;
compareBuf = zeros(overlapLength, 1);
expectOutLen = outputLen;
[output, outpos, compareBuf, inpos] = processSamples(input, inputLen, expectOutLen, compareBuf, overlapLength, seekLength, seekWindowLength, tempo, isBeginning);
remainningSamples = inputLen - inpos;
%append zeros to the remainning data
remainningLen = remainningSamples + 200 * 128;
remainningInput = zeros(remainningLen, 1);
remainningInput(1:remainningSamples, 1) = input(inpos:inpos + remainningSamples - 1, 1);
if outputLen > outpos
expectOutLen = outputLen - outpos + 1;
isBeginning = 0;
[tempOutput, tempOutpos, compareBuf, inpos] = processSamples(remainingInput, remainingInputLen, expectOutLen, compareBuf, overlapLength, seekLength, seekWindowLength, tempo, isBeginning);
output(outpos:outputLen, 1) = tempOutput(1: tempOutpos);
end
end
main.m:
clc;
clear all;
[input fs] = wavread('test.wav');
tempo = 2;
output = changeTempo(input, fs, tempo);
wavwrite(output, fs, 'output.wav');
soundtouch 变速算法matlab实现的更多相关文章
- soundtouch变速wsola算法之改进
soundtouch变速算法很类似sola算法,细看才知道是wsola算法. 上个星期有个需求,将该变速应用到直播的包处理,有点类似于webrtc的netEQ处理机制. 直接使用soundtouch, ...
- OLA音频变速算法的仿真与剖析
前段时间,在尝试音乐节拍数的提取时,终于有了突破性的进展,效果基本上比市面上的许多商业软件还要好,在作节拍数检测时,高频信息作用不大, 通过重采样减小运算量.重采样让我想起了在学校里面做的变速变调算法 ...
- 标准差分进化算法matlab程序实现(转载)
标准差分进化算法matlab程序实现 自适应差分演化算法方面的Matlab和C++代码及论文 差分进化算法 DE-Differential Evolution matlab练习程序(差异演化DE) [ ...
- 密度峰值聚类算法MATLAB程序
密度峰值聚类算法MATLAB程序 凯鲁嘎吉 - 博客园 http://www.cnblogs.com/kailugaji/ 密度峰值聚类算法简介见:[转] 密度峰值聚类算法(DPC) 数据见:MATL ...
- GWO(灰狼优化)算法MATLAB源码逐行中文注解(转载)
以优化SVM算法的参数c和g为例,对GWO算法MATLAB源码进行了逐行中文注解. tic % 计时器 %% 清空环境变量 close all clear clc format compact %% ...
- 每天进步一点点------Alpha半透明图形叠加算法Matlab+Verilog实现
Alpha图形叠加算法Matlab+Verilog实现 1.1. Alpha算法的研究 Alpha通道是一个8位的灰度通道,该通道用256级灰度来记录图像中的透明度信息,定义透明.不透明和半透明区域, ...
- 医学CT图像特征提取算法(matlab实现)
本科毕设做的是医学CT图像特征提取方法研究,主要是肺部CT图像的特征提取.由于医学图像基本为灰度图像,因此我将特征主要分为三类:纹理特征,形态特征以及代数特征,每种特征都有对应的算法进行特征提取. 如 ...
- 蚁群算法matlab实现
大家好,我是小鸭酱,博客地址为:http://www.cnblogs.com/xiaoyajiang 以下用matlab实现蚁群算法: %蚂蚁算法test %用产生的一个圆上的十个点来检验蚂蚁 ...
- 多源最短路Floyd 算法————matlab实现
弗洛伊德(Floyd)算法是一种用于寻找给定的加权图中顶点间最短路径的算法.该算法名称以创始人之一.1978年图灵奖获得者.斯坦福大学计算机科学系教授罗伯特·弗洛伊德命名. 基本思想 通过Floyd计 ...
随机推荐
- 秋水逸冰实用Linux脚本收藏
秋水逸冰的脚本非常受欢迎,奈何其本人博客已经不能访问(目前是这样,不知道别的地区是否能访问),实际上GitHub上他本人一直在维护,因为某些原因不放出他本人的GitHub地址.截止到2019年12月1 ...
- Java中顺序、并行与并发
顺序(sequential)用于表示多个操作依次处理.例如把十个操作交给一个人处理 并行(parallel)用于表示多个操作同时处理.比如是个操作分给两个人操作,两个人会并行处理 并发(concurr ...
- [SDOI2012] 任务安排 题解
有感而发,遂书. 其实和sze聊了很久,但他还是退役了.恐怕他是本届里学oi时间最长的一个人吧,从小学五年级开始.我也是因为他,才开始学oi的.他因为学校的压力,不得不放弃.或许是没什么天赋.学了4年 ...
- phpcms抛出的二维数组转移到js,js中for....in遍历数组,用“.”连接来读出一维数组值
直切正题: 1.phpcms在模版中读出数组有很多中方法,如,{pc:content action="lists"}或{pc:get sql=""},经过{lo ...
- 使用VS中自带的一键打包功能将我们的ASP.NET Core类库打包并将程序包(类库)发布到NuGet平台上进行管理
本章将和大家简单分享下如何使用VS中自带的一键打包功能将我们的ASP.NET Core类库打包并将程序包(类库)发布到NuGet平台上进行管理. 一.注册并登录NuGet平台 NuGet官网:http ...
- HDU1408 - 盐水的故事
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1408 解题思路:主要考虑最后一滴可能不满足D毫升,但仍算1秒.另外还要注意浮点数的比较. #inclu ...
- shelll高级编程【实战】(1)
shell优势在于处理操作系统底层业务,2000多个命令都是shell的支持. 一键安装,报警脚本,常规业务操作,shell开发更简单快速. 1- 常用操作系统默认shell linux: Bourn ...
- 【学习笔记】BP神经网络
转自 huaweizte123的CSDN博客 链接 https://blog.csdn.net/huaweizte123/article/details/78803045 第一步.向前传播得到预测数 ...
- 查看appium参数
首先打开appium server并运行,然后将手机与电脑相连,然后在python中写代码,但是代码需要出入appium参数,这些参数怎么查询呢? 1.创建appium参数 { "platf ...
- Building a Space Station POJ - 2031 三维最小生成树,其实就是板子题
#include<iostream> #include<cmath> #include<algorithm> #include<cstdio> usin ...