amr编码

音频编码:AMR 7:压缩码率:6.60/8.85/12.65/14.25/15.85/18.25/19.85/23.05/23.85,最高码率达到。7:压缩码率:4.75/5.15/5.90/6.70/7.40/7.95/10.2/12.2,最高码率达到。6:原始码率:16kHz×16bit=256kbit/s。1:AMR-NB:Narrow Band,窄带AMR。2:AMR_WB:Wide Band,宽带AMR。3:量化:采用均匀量化,65 536个量化电平。3:量化:采用均匀量化,65 536个量化电平。 阅读详情

目录
1. 概述
2. AMR编码
3. AMR解码
4. AMR帧读取算法
5. 参考资料

1. 概述
现在很多智能手机都支持多媒体功能,特别是音频和视频播放功能,而AMR文件格式是手机端普遍支持的音频文件格式。

AMR,全称是:Adaptive Multi-Rate,自适应多速率,是一种音频编码文件格式,专用于有效地压缩语音频率。

AMR音频主要用于移动设备的音频压缩,压缩比非常高,但是音质比较差,主要用于语音类的音频压缩,不适合对音质要求较高的音乐类音频的压缩。

AMR的编解码是基于“3GPP AMR Floating-point Speech Codec”来做的,3GPP还专门开放了基于ANSI-C实现的编解码代码,便于我们在各种平台上进行移植。

#ifndef amrFileCodec_h
#define amrFileCodec_h

#define AMR_MAGIC_NUMBER "#!AMRn"

#define PCM_FRAME_SIZE 160 // 8khz 8000*0.02=160
#define MAX_AMR_FRAME_SIZE 32
#define AMR_FRAME_COUNT_PER_SECOND 50
//int amrEncodeMode[] = {4750, 5150, 5900, 6700, 7400, 7950, 10200, 12200}; // amr 编码方式

typedef struct
{
char chChunkID[4];
int nChunkSize;
}XCHUNKHEADER;

typedef struct
{
short nFormatTag;
short nChannels;
int nSamplesPerSec;
int nAvgBytesPerSec;
short nBlockAlign;
short nBitsPerSample;
}WAVEFORMAT;

typedef struct
{
short nFormatTag;
short nChannels;
int nSamplesPerSec;
int nAvgBytesPerSec;
short nBlockAlign;
short nBitsPerSample;
short nExSize;
}WAVEFORMATX;

typedef struct
{
char chRiffID[4];
int nRiffSize;
char chRiffFormat[4];
}RIFFHEADER;

typedef struct
{
char chFmtID[4];
int nFmtSize;
WAVEFORMAT wf;
}FMTBLOCK;

// WAVE音频采样频率是8khz
// 音频样本单元数 = 8000*0.02 = 160 (由采样频率决定)
// 声道数 1 : 160
// 2 : 160*2 = 320
// bps决定样本(sample)大小
// bps = 8 --> 8位 unsigned char
// 16 --> 16位 unsigned short
int EncodeWAVEFileToAMRFile(const char* pchWAVEFilename, const char* pchAMRFileName, int nChannels, int nBitsPerSample);

// 将AMR文件解码成WAVE文件
int DecodeAMRFileToWAVEFile(const char* pchAMRFileName, const char* pchWAVEFilename);

#endif




2. AMR编码
3GPP提供了编码代码,并提供了一个encoder.c程序,该程序示范了如何对一个16位的单声道PCM数据进行压缩的。(采样频率必须是8khz)

我对该程序进行一定的拓展,数据位支持8位和16位,可以是单声道和双声道。

l 对于8位PCM只需要将每个采样的sample数据位扩展成16位,并左移7位。
l 对于双声道,可以只对左声道数据进行处理,也可以只对右声道数据进行处理,或者将左右声道数据求平均值就可。

这样两个小处理,就可以将PCM规范成3PGG的编码器需要的数据格式。

代码在 amrFileEncoder.c 中。


#include "amrFileCodec.h"

// 从WAVE文件中跳过WAVE文件头,直接到PCM音频数据
void SkipToPCMAudioData(FILE* fpwave)
{
RIFFHEADER riff;
FMTBLOCK fmt;
XCHUNKHEADER chunk;
WAVEFORMATX wfx;
int bDataBlock = 0;

// 1. 读RIFF头
fread(&riff, 1, sizeof(RIFFHEADER), fpwave);

// 2. 读FMT块 - 如果 fmt.nFmtSize>16 说明需要还有一个附属大小没有读
fread(&chunk, 1, sizeof(XCHUNKHEADER), fpwave);
if ( chunk.nChunkSize>16 )
{
fread(&wfx, 1, sizeof(WAVEFORMATX), fpwave);
}
else
{
memcpy(fmt.chFmtID, chunk.chChunkID, 4);
fmt.nFmtSize = chunk.nChunkSize;
fread(&fmt.wf, 1, sizeof(WAVEFORMAT), fpwave);
}

// 3.转到data块 - 有些还有fact块等。
while(!bDataBlock)
{
fread(&chunk, 1, sizeof(XCHUNKHEADER), fpwave);
if ( !memcmp(chunk.chChunkID, "data", 4) )
{
bDataBlock = 1;
break;
}
// 因为这个不是data块,就跳过块数据
fseek(fpwave, chunk.nChunkSize, SEEK_CUR);
}
}

// 从WAVE文件读一个完整的PCM音频帧
// 返回值: 0-错误 >0: 完整帧大小
int ReadPCMFrame(short speech[], FILE* fpwave, int nChannels, int nBitsPerSample)
{
int nRead = 0;
int x = 0, y=0;
unsigned short ush1=0, ush2=0, ush=0;

// 原始PCM音频帧数据
unsigned char pcmFrame_8b1[PCM_FRAME_SIZE];
unsigned char pcmFrame_8b2[PCM_FRAME_SIZE<<1];
unsigned short pcmFrame_16b1[PCM_FRAME_SIZE];
unsigned short pcmFrame_16b2[PCM_FRAME_SIZE<<1];

if (nBitsPerSample==8 && nChannels==1)
{
nRead = fread(pcmFrame_8b1, (nBitsPerSample/8), PCM_FRAME_SIZE*nChannels, fpwave);
for(x=0; x<PCM_FRAME_SIZE; x++)
{
speech[x] =(short)((short)pcmFrame_8b1[x] << 7);
}
}
else
if (nBitsPerSample==8 && nChannels==2)
{
nRead = fread(pcmFrame_8b2, (nBitsPerSample/8), PCM_FRAME_SIZE*nChannels, fpwave);
for( x=0, y=0; y<PCM_FRAME_SIZE; y++,x+=2 )
{
// 1 - 取两个声道之左声道
speech[y] =(short)((short)pcmFrame_8b2[x+0] << 7);
// 2 - 取两个声道之右声道
//speech[y] =(short)((short)pcmFrame_8b2[x+1] << 7);
// 3 - 取两个声道的平均值
//ush1 = (short)pcmFrame_8b2[x+0];
//ush2 = (short)pcmFrame_8b2[x+1];
//ush = (ush1 + ush2) >> 1;
//speech[y] = (short)((short)ush << 7);
}
}
else
if (nBitsPerSample==16 && nChannels==1)
{
nRead = fread(pcmFrame_16b1, (nBitsPerSample/8), PCM_FRAME_SIZE*nChannels, fpwave);
for(x=0; x<PCM_FRAME_SIZE; x++)
{
speech[x] = (short)pcmFrame_16b1[x+0];
}
}
else
if (nBitsPerSample==16 && nChannels==2)
{
nRead = fread(pcmFrame_16b2, (nBitsPerSample/8), PCM_FRAME_SIZE*nChannels, fpwave);
for( x=0, y=0; y<PCM_FRAME_SIZE; y++,x+=2 )
{
//speech[y] = (short)pcmFrame_16b2[x+0];
speech[y] = (short)((int)((int)pcmFrame_16b2[x+0] + (int)pcmFrame_16b2[x+1])) >> 1;
}
}

// 如果读到的数据不是一个完整的PCM帧, 就返回0
if (nRead<PCM_FRAME_SIZE*nChannels) return 0;

return nRead;
}

// WAVE音频采样频率是8khz
// 音频样本单元数 = 8000*0.02 = 160 (由采样频率决定)
// 声道数 1 : 160
// 2 : 160*2 = 320
// bps决定样本(sample)大小
// bps = 8 --> 8位 unsigned char
// 16 --> 16位 unsigned short
int EncodeWAVEFileToAMRFile(const char* pchWAVEFilename, const char* pchAMRFileName, int nChannels, int nBitsPerSample)
{
FILE* fpwave;
FILE* fpamr;


short speech[160];


int byte_counter, frames = 0, bytes = 0;


int *enstate;


enum Mode req_mode = MR122;
int dtx = 0;


unsigned char amrFrame[MAX_AMR_FRAME_SIZE];

fpwave = fopen(pchWAVEFilename, "rb");
if (fpwave == NULL)
{
return 0;
}

// 创建并初始化amr文件
fpamr = fopen(pchAMRFileName, "wb");
if (fpamr == NULL)
{
fclose(fpwave);
return 0;
}

bytes = fwrite(AMR_MAGIC_NUMBER, sizeof(char), strlen(AMR_MAGIC_NUMBER), fpamr);


SkipToPCMAudioData(fpwave);

enstate = Encoder_Interface_init(dtx);

while(1)
{
// read one pcm frame
if (!ReadPCMFrame(speech, fpwave, nChannels, nBitsPerSample)) break;

frames++;


byte_counter = Encoder_Interface_Encode(enstate, req_mode, speech, amrFrame, 0);

bytes += byte_counter;
fwrite(amrFrame, sizeof (unsigned char), byte_counter, fpamr );
}

Encoder_Interface_exit(enstate);

fclose(fpamr);
fclose(fpwave);

return frames;
}


3. AMR解码
3GPP提供了解码代码,并提供了一个decoder.c程序,该程序示范了如何对amr音频进行解码。解码成一个wave文件(8khz 16位单声道)。

解码是需要注意AMR坏帧的处理。在AMR读帧算法中有说明。

文件解码器代码在 amrFileDecoder.c 中。

#include "amrFileCodec.h"

void WriteWAVEFileHeader(FILE* fpwave, int nFrame)
{
char tag[10] = "";

// 1. 写RIFF头
strcpy(tag, "RIFF");
memcpy(riff.chRiffID, tag, 4);
riff.nRiffSize = 4 // WAVE
+ sizeof(XCHUNKHEADER) // fmt
+ sizeof(WAVEFORMATX) // WAVEFORMATX
+ sizeof(XCHUNKHEADER) // DATA
+ nFrame*160*sizeof(short); //
strcpy(tag, "WAVE");
memcpy(riff.chRiffFormat, tag, 4);
fwrite(&riff, 1, sizeof(RIFFHEADER), fpwave);

// 2. 写FMT块
strcpy(tag, "fmt ");
memcpy(chunk.chChunkID, tag, 4);
chunk.nChunkSize = sizeof(WAVEFORMATX);
fwrite(&chunk, 1, sizeof(XCHUNKHEADER), fpwave);
memset(&wfx, 0, sizeof(WAVEFORMATX));
wfx.nFormatTag = 1;
wfx.nChannels = 1; // 单声道
wfx.nSamplesPerSec = 8000; // 8khz
wfx.nAvgBytesPerSec = 16000;
wfx.nBlockAlign = 2;
wfx.nBitsPerSample = 16; // 16位
fwrite(&wfx, 1, sizeof(WAVEFORMATX), fpwave);

// 3. 写data块头
strcpy(tag, "data");
memcpy(chunk.chChunkID, tag, 4);
chunk.nChunkSize = nFrame*160*sizeof(short);
fwrite(&chunk, 1, sizeof(XCHUNKHEADER), fpwave);
}

const int round(const double x)
{
return((int)(x+0.5));
}

// 根据帧头计算当前帧大小
int caclAMRFrameSize(unsigned char frameHeader)
{
int mode;
int temp1 = 0;
int temp2 = 0;
int frameSize;

temp1 = frameHeader;

// 编码方式编号 = 帧头的3-6位
temp1 &= 0x78; // 0111-1000
temp1 >>= 3;

mode = amrEncodeMode[temp1];

// 计算amr音频数据帧大小
// 原理: amr 一帧对应20ms,那么一秒有50帧的音频数据
temp2 = round((double)(((double)mode / (double)AMR_FRAME_COUNT_PER_SECOND) / (double)8));

frameSize = round((double)temp2 + 0.5);
return frameSize;
}

// 读第一个帧 - (参考帧)
// 返回值: 0-出错; 1-正确
int ReadAMRFrameFirst(FILE* fpamr, unsigned char frameBuffer[], int* stdFrameSize, unsigned char* stdFrameHeader)
{
memset(frameBuffer, 0, sizeof(frameBuffer));

// 先读帧头
fread(stdFrameHeader, 1, sizeof(unsigned char), fpamr);
if (feof(fpamr)) return 0;

// 根据帧头计算帧大小
*stdFrameSize = caclAMRFrameSize(*stdFrameHeader);

// 读首帧
frameBuffer[0] = *stdFrameHeader;
fread(&(frameBuffer[1]), 1, (*stdFrameSize-1)*sizeof(unsigned char), fpamr);
if (feof(fpamr)) return 0;

return 1;
}

// 返回值: 0-出错; 1-正确
int ReadAMRFrame(FILE* fpamr, unsigned char frameBuffer[], int stdFrameSize, unsigned char stdFrameHeader)
{
int bytes = 0;
unsigned char frameHeader; // 帧头

memset(frameBuffer, 0, sizeof(frameBuffer));

// 读帧头
// 如果是坏帧(不是标准帧头),则继续读下一个字节,直到读到标准帧头
while(1)
{
bytes = fread(&frameHeader, 1, sizeof(unsigned char), fpamr);
if (feof(fpamr)) return 0;
if (frameHeader == stdFrameHeader) break;
}

// 读该帧的语音数据(帧头已经读过)
frameBuffer[0] = frameHeader;
bytes = fread(&(frameBuffer[1]), 1, (stdFrameSize-1)*sizeof(unsigned char), fpamr);
if (feof(fpamr)) return 0;

return 1;
}

// 将AMR文件解码成WAVE文件
int DecodeAMRFileToWAVEFile(const char* pchAMRFileName, const char* pchWAVEFilename)
{
FILE* fpamr = NULL;
FILE* fpwave = NULL;
char magic[8];
int * destate;
int nFrameCount = 0;
int stdFrameSize;
unsigned char stdFrameHeader;

unsigned char amrFrame[MAX_AMR_FRAME_SIZE];
short pcmFrame[PCM_FRAME_SIZE];

fpamr = fopen(pchAMRFileName, "rb");
if ( fpamr==NULL ) return 0;

// 检查amr文件头
fread(magic, sizeof(char), strlen(AMR_MAGIC_NUMBER), fpamr);
if (strncmp(magic, AMR_MAGIC_NUMBER, strlen(AMR_MAGIC_NUMBER)))
{
fclose(fpamr);
return 0;
}

// 创建并初始化WAVE文件
fpwave = fopen(pchWAVEFilename, "wb");
WriteWAVEFileHeader(fpwave, nFrameCount);


destate = Decoder_Interface_init();

// 读第一帧 - 作为参考帧
memset(amrFrame, 0, sizeof(amrFrame));
memset(pcmFrame, 0, sizeof(pcmFrame));
ReadAMRFrameFirst(fpamr, amrFrame, &stdFrameSize, &stdFrameHeader);

// 解码一个AMR音频帧成PCM数据
Decoder_Interface_Decode(destate, amrFrame, pcmFrame, 0);
nFrameCount++;
fwrite(pcmFrame, sizeof(short), PCM_FRAME_SIZE, fpwave);

// 逐帧解码AMR并写到WAVE文件里
while(1)
{
memset(amrFrame, 0, sizeof(amrFrame));
memset(pcmFrame, 0, sizeof(pcmFrame));
if (!ReadAMRFrame(fpamr, amrFrame, stdFrameSize, stdFrameHeader)) break;

// 解码一个AMR音频帧成PCM数据 (8k-16b-单声道)
Decoder_Interface_Decode(destate, amrFrame, pcmFrame, 0);
nFrameCount++;
fwrite(pcmFrame, sizeof(short), PCM_FRAME_SIZE, fpwave);
}

Decoder_Interface_exit(destate);

fclose(fpwave);

// 重写WAVE文件头
fpwave = fopen(pchWAVEFilename, "r+");
WriteWAVEFileHeader(fpwave, nFrameCount);
fclose(fpwave);

return nFrameCount;
}





4. AMR帧读取算法
因为可能存在异常帧,所以不一定所有的语音帧大小一致,对于跟正常帧大小不一致的,或者帧头跟正常帧头不一致的,就不交给解码器,直接抛弃该坏帧。

读取帧的算法,用C语言来编写,readAMRFrame.c,JAVA可以用类似的方法。
下面是算法描述流程图。
读首帧(标准帧)
ReadFirstAMRFrame
根据帧头计算标准帧的大小
caclAMRFrameSize
AMR音频文件流
读帧头(字节)
frameHeader
判断是否为坏帧?
Y
N
读本帧音频数据
帧头 + 音频数据 = 当前帧数据
AMR音频编解码  目录1.    概述2.    AMR编码3.    AMR解码4.    AMR帧读取算法5.    参考资料 1.      概述现在很多智能手机都支持多媒体功能,特别是音频和视频播放功能,而AMR文件格式是手机端普遍支持的音频文件格式。 AMR,全称是:Adaptive Multi-Rate,自适应多速率,是一种音频编码文件格式,专用于有效地 阅读详情

相关推荐

12、江科大stm32视频学习笔记——TIM编码器接口

江科大stm32视频学习笔记——TIM编码器接口

weixin_45981798的博客 2955

AMR编码

背景音频编码技术 音频信号 音频信号是指人耳可以听到的频率在 20Hz 到 20KHz 之间的声波信号。人的话音信号的频率在 300~3000Hz 之间,该频段的信号也被称为语音信号。我们广义上的音频信号包括了音乐、语音、风声、雨声、鸟叫声、机器声等[4]。 音频编码技术应用背景 音频信号是模拟信号,在数字...

测试0901-1 2435

AMR编码文件解析

一、AMR简介 基于新的网络和新的要求,无论是从节省传输频带资源,还是保持线路通信的高效率等方面来看,研究采用各种可变速率语音编码技术的系统都有重要意义。目前为了适应此需要提出了AMR(Adaptive Multi-rate) 的概念,即自适应多速率语音编码器,主要用于移动设备的音频,压缩比比较大,但相对其他的压缩格式质量比较差,由于多用于人声通话。AMR又分为两种,一种是...

hanzhen7541的博客 2634

语音编码技术,AMR、AMR-NB、AMR-WB、EVS总结

最近对实时语音编码技术有点兴趣,于是了解了一下。 一开始听说AMR-NB窄带编码,搜索才发现更多的编码技术,这里总结一下,便于日后查看。 一、什么是AMR、AMR-WB 全称Adaptive Multi-Rate和Adaptive Multi-Rate Wideband,主要用于移动设备的音频,压缩比比较大,但相对其他的压缩格式质量比较差,由于多用于人声,通话,效果还是很不错的。 AMR: 又称为AMR-NB,相对于下面的WB而言 语音带宽范围:300-3400Hz 8KHz采样率 AMR-WB:AMR W

1万+

音频基础与音频编码(AMR和PCM)

音频基础与音频编码(AMR和PCM) 1、音频基础 1.1 声音是什么 引用百度百科中对声音的一段描述: 声音其实是一种能量波,因此也有频率和振幅的特征,频率对应于时间轴线,振幅对应于电平轴线。波是无限光滑的,弦线可以看成由无数点组成,由于存储空间是相对有限的,数字编码过程中,必须对弦线的点进行采样。采样的过程就是抽取某点的频率值,很显然,在一秒中内抽取的点越多,获取得频率信息更丰富,为了复原波...

qq_15585751的博客 4471

AMR 编码 PCM & WAV (opencore-amr-0.1.5)

AMR编码基于第三方opencore-amr-0.1.5库 支持PCM2AMR,WAV2AMR test目录下:pcm2amr.c pcm2amr.c,linux环境下 调试通过,准备移植到安卓手机 资源下载链接:http://download.youkuaiyun.com/detail/yuanchunsi/9917689

yuanchunsi的博客 2076

amr-nb amr-wb 编码

amr-nb: 自适应多速率窄带语音编码,主要应用于2G时代语音通讯,其以更加智能的方式解决信源和信道编码的速率分配问题,根据无线信道和传输状况来自适应地选择一种编码模式进行传输,使得无线资源的配置与利用更加灵活有效。 支持8种速率(比特率)编码模式: 编码模式 编码名称 比特率 帧大小 帧头 Mode 0 AMR 4.75 4.75 kbi..

liuxunfei15的博客 3627

C++实现的AMR音频编码与解码技术全解

自适应多速率(AMR)技术是一种广泛应用于移动通信领域的语音压缩编码技术。它的核心目标是在不同的网络条件下自适应地选择最合适的语音比特率,以保证通信质量的同时减少带宽占用。AMR技术特别适合在带宽受限的移动环境中使用,比如GSM、3G和4G网络等,可以有效地提升语音通信的清晰度和可靠性。开源库在AMR编解码中的应用极大地简化了开发过程,提供了高效且稳定的实现。例如,开源库如FFmpeg提供了AMR编解码的功能,极大地减少了开发工作量。

weixin_42587866的博客 819

详解AMR音频编码器

AMR音频编码器概述及文件格式分析 全称Adaptive Multi-Rate,自适应多速率编码,主要用于移动设备的音频,压缩比比较大,但相对其他的压缩格式质量比较差,由于多用于人声,通话,效果还是很不错的。 一、分类 1. AMR: 又称为AMR-NB,相对于下面的WB而言, 语音带宽范围:300-3400Hz, 8KHz抽样 2. AMR-WB:AMR WideBand,

weixiaowenrou的专栏 903

Java农产品质量溯源大数据管理系统源码

产品追溯基于“一物一码”从工厂生产环节至销售阶段,赋予产品唯一的数码,并关联产品名称、批号、生产时间等信息,建立包装关联关系,为后期产品的追溯、营销搭建信息基础。 农产品溯源,从原材料收购、生产、加工质检到包装运输、终端门店销售等环节追溯,可以保证产品质量,监管部门和消费者都可以查询产品信息。对生产进行层层把关、一旦发现问题、立即进行处理、提升产品质量。

xingchen优快云的博客 1803

electron windows设置镜像地址环境变量报错npm error `ELECTRON_MIRROR` is not a valid npm option

如果你是在使用某个特定的脚本或配置文件,请检查该文件中是否有不正确的配置项,并进行相应的修正。确保你遵循electron的官方安装指南,并且没有包含不必要的或错误的配置选项。如果问题依然存在,可以查看npm的官方文档或者相关社区获取更多帮助。

qq_36158551的博客 3322

AMR2与AMR编码区别

1. 为什么有AMR、AMR2两种编解码方式?两者的区别在哪里呢? UMTS_AMR2的引入是为了3G与2G互通时端到端免编解码,UMTS_AMR2与UMTS_AMR的区别在于uplink上速率控制。www.mscbsc.com6[&c!D9v*R-h!b&n7U GSM的FR_AMR速率控制只能每隔一帧发生(40ms间隔),而UMTS_AMR速率控制可以在任何一帧发生(20ms间隔),这样,

专栏 7115

无人机中继传输数据链技术,(无人机+自组网)远距离传输技术实现详解

无人机中继传输数据链技术是指利用无人机作为空中移动中继节点,在需要通信的区域上空悬停或移动,以建立和维护通信链路,从而扩展通信范围、提高通信质量和灵活性。1. 通信链路:是无人机中继通信的重要组成部分,包括源节点到中继节点的链路和中继节点到目标节点的链路。同时,它还支持空中到地面的通信,距离大于100km。总的来说,无人机中继传输数据链技术和(无人机+自组网)远距离传输技术都是现代无人机通信领域的重要技术,它们的应用极大地扩展了无人机的通信范围和灵活性,为各种应用场景提供了强有力的支持。

专注多旋翼、复合翼无人机技术研究,从事低空经济行业。 2079

AMR-NB 与 AMR-WB 语音编码标准技术的对比研究

AMR-NB 与 AMR-WB 语音编码标准技术的对比研究 2013年07月15日 15:58:49随心飘散阅读数 8550 自适应多速率窄带语音编码AMR-NB(Adaptive Multi Rate-Narrow Band Speech Codec)算法是由第三代伙伴计划(3rdGeneration Partnership Project,简称 3GPP)于 1999年8月制...

weixin_42082222的博客 1294

python-snap7 报错:can‘t find snap7 library. If installed, try running ldconfig

1、使用场景: Python 读取西门子 S7 系列 PLC 信息,会用到 snap7 库,网上也有很多案例。但是,运行时会报错:can't find snap7 library. If installed, try running ldconfig 2、解决方案: A、下载项目需要依赖的 dll、lib 文件: i、Sourceforge下载:https://sourceforge.net/projects/snap7/files/ ii、优快云下载(免费):https://dow.

蜡笔小新历险记的博客 3646

Quartus Prime 软件 USB-blaster 驱动安装失败【已解决】

一、安装步骤 1、将FPGA 开发板插入电脑时,未安装驱动的电脑会提示安装usb-Blaster驱动。Windows搜索框打开设备管理器,在“其他设备”下会发现黄色感叹号的“USB-Blaster”的设备驱动。 2、Quartus系列软件的安装目录下自带USB-blaster的驱动程序,右键更新驱动,选择驱动目录:(D:\intelFPGA\18.1\quartus\drivers\usb-blaster,文件位置和版本请按照自己安装的路径选择),点击Next开始安装。 3、安装成功,重启电脑即可使

adolphwang_909086的博客 6万+

AMR音频编码器概述及文件格式分析

全称Adaptive Multi-Rate,自适应多速率编码,主要用于移动设备的音频,压缩比比较大,但相对其他的压缩格式质量比较差,由于多用于人声,通话,效果还是很不错的。 一、分类 1. AMR: 又称为AMR-NB,相对于下面的WB而言, 语音带宽范围:300-3400Hz, 8KHz抽样 2. AMR-WB:AMR WideBand, 语音带宽范围: 50

技术无捷径,一步一脚印 1442

杰理AC695N系列芯片 LED7数码管使用教程

杰理AC695N数码管使用摘要 本教程介绍了杰理AC695N芯片驱动LED7数码管的实现方法: 硬件配置:支持7/12/13脚三种数码管类型,详细说明了7脚数码管的标准段码定义和GPIO接线方式。 软件设置: 通过修改配置文件启用LED7功能 配置GPIO引脚映射(PORTC/PORTA组) 选择与硬件匹配的真值表 层次架构:包含硬件层、驱动层、UI层和应用层的完整设计,支持数字、字符和图标显示功能。 实现要点包括正确配置引脚类型、选择真值表,并通过UI风格设置为LED7模式。

qq_42014563的博客 1344

语音编码算法AMR NB , AMR WB 和AMR WB+的区别

网上有些分析AMR NB 和AMR WB区别的资料,为节省篇幅,就不一一转过来了,可以参考如下 http://www.rosoo.net/a/201101/10759.html 还有科技论文在线的:AMR-NB 与AMR-WB 语音编码标准技术的对比研究 不过我感觉这些对比都是对比的表面现象,没有对比AMR NB和AMR WB的本质不同,AMR NB和AMR WB语音编解码都

老衲不出家 2844

注意力机制篇 | YOLOv8改进之在C2f模块添加EMA注意力机制(附2种改进方法)

EMA(Exponential Moving Average)注意力机制是一种用于增强模型性能的注意力机制,它通过对模型的特征图进行加权平均来提取更有用的特征信息。具体来说,EMA注意力机制通过引入一个权重因子来调整特征图中每个位置的重要性,从而使模型能够更好地关注重要的特征。🌈

小哥谈 4180

三菱FX5U气缸控制功能块(完整ST源代码+示例程序)

如果机器包含100个气缸,我们只需要修改数组的元素数量就可以了,效率非常的高。待续....博途PLC 面向对象系列之“双通气缸功能块“(SCL代码)_plc面向对象-优快云博客文章浏览阅读667次。本文介绍了博途PLC中面向对象编程的应用,重点讲解了双通气缸的功能块设计,包括双通电磁阀功能块、双通气缸的UDT数据类型以及SCL代码实现。同时,对比了双通与单通电磁阀的差异,并讨论了将单通气缸改造为双通气缸的方法,强调了双通气缸在安全性上的优势。

RXXW_Dor的博客 1026

AMR音频编码器

AMR音频编码器概述及文件格式分析 全称Adaptive Multi-Rate,自适应多速率编码,主要用于移动设备的音频,压缩比比较大,但相对其他的压缩格式质量比较差,由于多用于人声,通话,效果还是很不错的。 一、分类 1. AMR: 又称为AMR-NB,相对于下面的WB而言, 语音带宽范围:300-3400Hz, 8KHz抽样 2. A

thinker 1915

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

上一篇: ios程序发布后,收集Crash崩溃信息
下一篇: 一步一步教你做ios推送
JackHu
博客等级 码龄17年 4粉丝 5原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值