【语音编码】基于matlab ADPCM编解码【含Matlab源码 553期】

一、简介

1 adpcm编码原理
在这里插入图片描述
编码步骤:

求出输入的pcm数据与预测的pcm数据(第一次为上一个pcm数据)的差值diff;
通过差分量化器算出delta(通过index(首次编码index为0)求出step,通过diff和step求出delta)。delta即为编码后的数据;
通过逆量化器求出vpdiff(通过求出的delta和step算出vpdiff);
求出新的预测valpred,即上次预测的valpred+vpdiff;
通过预测器(归一化),求出当前输入pcm input的预测pcm值,为下一次计算用;
量化阶调整(通过delta查表及index,计算出新的index值)。为下次计算用;
2 adpcm解码原理
在这里插入图片描述
解码步骤(其实解码原理就是编码的第三到六步):

通过逆量化器求出vpdiff(通过存储的delta和index,求出step,算出vpdiff);
求出新的预测valpred,即上次预测的valpred+vpdiff;
通过预测器(归一化),求出当前输入pcm input的预测pcm值,为下一次计算用。预测的pcm值即为解码后的数据;
量化阶调整(通过delta查表及index,计算出新的index值)。为下次计算用;
注释说明
通过编码和解码的原理我们可以看出其实第一次编码的时候已经进行了解码,即预测的pcm。
因为编码再解码后输出的数据已经被量化了。根据计算公式delta = diff*4/step;vpdiff = (delta+0.5)*step/4;考虑到都是整数运算,可以推导出:pcm数据经过编码再解码生成的预测pcm数据,如果预测pcm数据再次编码所得的数据与第一次编码所得的数据是相同的。故pcm数据经过一次编码有损后,不论后面经过几次解码再编码都是数据一样,音质不会再次损失。即相对于第一次编码后,以后数据不论多少次编解码,属于无损输出。

3 ADPCM数据存放形式
本部分为adpcm数据存放说明,属于细节部分,很多代码解码出来有噪音就是因为本部分细节不对,所以需要仔细阅读。

3.1 adpcm 数据块介绍
adpcm数据是一个block一个block存放的,block由block header (block头) 和data 两者组成的。其中block header是一个结构,它在单声道下的定义如下:

Typedef struct
{
    
    
short  sample0;    //block中第一个采样值(未压缩)
BYTE  index;     //上一个block最后一个index,第一个block的index=0;
BYTE  reserved;   //尚未使用
}MonoBlockHeader;

对于双声道,它的blockheader应该包含两个MonoBlockHeader其定义如下:

typedaf struct
{
    
    
MonoBlockHeader leftbher;
MonoBlockHeader rightbher;
}StereoBlockHeader;

在解压缩时,左右声道是分开处理的,所以必须有两个MonoBlockHeader;
有了blockheader的信息后,就可以不需要知道这个block前面数据而轻松地解出本block中的压缩数据。故adpcm解码只与本block有关,与其他block无关,可以只单个解任何一个block数据。
block的大小是固定的,可以自定义,每个block含的采样数nsamples计算如下:

//
#define BLKSIZE 1024
block = BLKSIZE * channels;
//block = BLKSIZE;//ffmpeg
nsamples = (block  - 4 * channels) * 8 / (4 * channels) + 1;

例如audition软件就是采用上面的,单通路block为1024bytes,2041个samples,双通路block为2048,也是含有2041个sample。
而ffmpeg采用block =1024bytes,即不论单双通路都为1024bytes,通过公式可以算出单双通路的samples数分别为2041和1017;

3.2 单通路pcm格式:
在这里插入图片描述
3.3 双通路pcm格式:
在这里插入图片描述
3.4 编解码代码实现
需要特别留意双声道的处理和当数据不够1 block时的处理方式
代码包含了编码和解码测试用例,实现先编码再解码。欢迎交流学习
完整代码下载地址(本文只是详细说明了adpcm编解码,如果想wav文件编解码正确需要下载完整代码。
完整代码为0x0011 /* Intel’s DVI ADPCM */的编码解码代码实现。包括单双通路的处理和最后数据不是整块block的处理):

二、源代码

clear all;
clc
close all;
[x,fs,numbits]= wavread('C6_3_y.wav'); 

sign_bit=2;                                     %两位ADPCM算法
ss=adpcm_encoder(x,sign_bit);
yy=adpcm_decoder(ss,sign_bit)';

nq=sum((x-yy).*(x-yy))/length(x);
sq=mean(yy.^2);
snr=(sq/nq);
t=(1:length(x))/fs;
subplot(211)
plot(t,x/max(abs(x)))
axis tight
title('(a)编码前语音')
xlabel('时间/s')
ylabel('幅度')
subplot(212)
plot(t,yy/max(abs(yy)))
axis tight
% APDCM解码函数
function y=adpcm_decoder(code,sign_bit)
len=length(code);
y = zeros(1,len);
ss2 = zeros(1,len); 
ss2(1) = 1; 

currentIndex =1; 
index = [-1 4]; 
startval = 1; 
endval = 127;
base = exp( log(2)/8 ); 
% 近似步长 
const = startval/base; 
numSteps = round( log(endval/const) / log(base) ); 
n = 1:numSteps; 
base = exp( log(endval/startval) / (numSteps-1) ); 
const = startval/base; 
table2 = round( const*base.^n ); 
for n = 2:len 
% 计算量化距离 
    neg = code(n) >= sign_bit; 
    if (neg) 
        temp = code(n) - sign_bit; 
    else 
        temp = code(n); 
    end 
    temp2 = (temp+.5)*ss2(n-1); 
    if (neg) 
        temp2 = -temp2; 
    end 

三、运行结果

在这里插入图片描述

四、备注

完整代码或者代写添加QQ 1564658423
往期回顾>>>>>>
【特征提取】基于matlab小波变换的音频水印嵌入提取【含Matlab源码 053期】
【语音处理】基于matlab GUI语音信号处理【含Matlab源码 290期】
【语音采集】基于matlab GUI语音信号采集【含Matlab源码 291期】
【语音调制】基于matlab GUI语音幅度调制【含Matlab源码 292期】
【语音合成】基于matlab GUI语音合成【含Matlab源码 293期】
【语音加密】基于matlab GUI语音信号加密解密【含Matlab源码 295期】
【语音增强】基于matlab小波变换的语音增强【含Matlab源码 296期】
【语音识别】基于matlab GUI语音基频识别【含Matlab源码 294期】
【语音增强】基于matlab GUI维纳滤波之语音增强【含Matlab源码 298期】
【语音处理】基于matlab GUI语音信号处理【含Matlab源码 299期】
【信号处理】基于matlab的语音信号频谱分析仪【含Matlab源码 325期】
【调制信号】基于matlab GUI数字调制信号仿真【含Matlab源码 336期】
【情感识别】基于matlab BP神经网络的语音情感识别【含Matlab源码 349期】
【语音隐写】基于matlab小波变换的量化音频数字水印【含Matlab源码 351期】
【特征提取】基于matlab音频水印嵌入与提取【含Matlab源码 350期】
【语音去噪】基于matlab低通和自适应滤波去噪【含Matlab源码 352期】
【情感识别】基于matlab GUI语音情感分类识别【含Matlab源码 354期】
【基础处理】基于matlab语音信号的预处理【含Matlab源码 364期】
【语音识别】基于matlab 傅立叶变换0-9的数字语音识别【含Matlab源码 384期】
【语音识别】基于matlab GUI DTW的0-9数字语音识别【含Matlab源码 385期】
【语音播放】基于matlab GUI MP3设计【含Matlab源码 425期】
【语音处理】基于人耳掩蔽效应的语音增强算法信噪比计算【含Matlab源码 428期】
【语音去噪】基于matlab谱减法去噪【含Matlab源码 429期】
【语音识别】基于matlab带动量项的BP神经网络语音识别【含Matlab源码 430期】
【语音隐写】基于matlab LSB语音隐藏【含Matlab源码 431期】
【语音识别】基于matlab男女声识别【含Matlab源码 452期】
【语音处理】基于matlab语音加噪和降噪处理【含Matlab源码 473期】
【语音去噪】基于matlab最小二乘法(LMS)自适应滤波器【含Matlab源码 481期】
【语音增强】基于matlab谱减法、最小均方和维纳滤波语音增强【含Matlab源码 482期】
【通信】基于matlab GUI数字频带(ASK、PSK、QAM)调制仿真 【含Matlab源码 483期】
【信号处理】基于matlab心电信号ECG滤波处理【含Matlab源码 484期】
【语音播报】基于matlab语音播报【含Matlab源码 507期】
【信号处理】基于matlab小波变换脑电信号特征提取【含Matlab源码 511期】
【语音处理】基于matlab GUI双音多频(DTMF)信号检测【含Matlab源码 512期】
【语音隐写】基于matlab LSB实现语音信号的数字水印【含Matlab源码 513期】
【语音增强】基于matlab匹配滤波器的语音识别【含Matlab源码 514期】
【语音处理】基于matlab GUI语音时域频域频谱图分析【含Matlab源码 527期】
【语音去噪】基于matlab LMS、RLS算法语音去噪【含Matlab源码 528期】
【语音去噪】基于matlab LMS谱减法语音去噪【含Matlab源码 529期】
【语音去噪】基于matlab 软阈值、硬阈值、折中阈值语音去噪【含Matlab源码 530期】
【语音识别】基于matlab特定人的语音识别分辨【含Matlab源码 534期】
【语音去噪】基于matlab小波软阈值语音降噪【含Matlab源码 531期】
【语音去噪】基于matlab小波硬阈值语音降噪【含Matlab源码 532期】
【语音识别】基于matlab MFCC和SVM的特定人性别识别【含Matlab源码 533期】
【语音识别】基于MFCC的GMM语音识别【含Matlab源码 535期】
【语音识别】基于matlab VQ特定人孤立词语音识别【含Matlab源码 536期】
【语音识别】基于matlab GUI声纹识别【含Matlab源码 537期】
【采集读写】基于matlab语音采集与读写【含Matlab源码 538期】
【语音编辑】基于matlab语音编辑【含Matlab源码 539期】
【语音模型】基于matlab语音信号数学模型【含Matlab源码 540期】
【语音响度】基于matlab语音声强与响度【含Matlab源码 541期】
【情感识别】基于matlab K近邻分类算法的语音情感识别【含Matlab源码 542期】
【情感识别】基于matlab支持向量机(SVM)的语音情感识别【含Matlab源码 543期】
【情感识别】基于神经网络的语音情感识别【含Matlab源码 544期】
【声源定位】基于matlab不同空间谱估计的声源定位算法比较【含Matlab源码 545期】
【声源定位】基于matlab不同信噪比下的麦克风接收信号【含Matlab源码 546期】
【声源定位】基于matlab单声源双麦克风的房间冲激响应【含Matlab源码 547期】
【声源定位】基于matlab广义互相关的声源定位【含Matlab源码 548期】
【声源定位】基于matlab阵列流形矩阵的信号显示【含Matlab源码 549期】
【特征提取】基于matlab共振峰估计【含Matlab源码 550期】
【特征提取】基于matlab基音周期估计【含Matlab源码 551期】
【特征提取】基于matlab语音端点检测【含Matlab源码 552期】

猜你喜欢

转载自blog.csdn.net/TIQCmatlab/article/details/114977184