热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

求一个asp.net下面的AMR转换WAV音频的DLL控件或源代码

现在需要将别人上传来的AMR音频转换成WAV格式,求这方面的可引用动态库dll或com组件注:不是音频转换器,是要代码或者dll库我有一个是c++写的可以将amr转换成wav,我本想将c++
现在需要将别人上传来的AMR音频转换成WAV格式,求这方面的可引用动态库dll或com组件
注:不是音频转换器,是要代码或者dll库

我有一个是c++写的  可以将amr转换成wav,我本想将c++翻译给c#用,发现c++东西很多都忘了,有些又过于复杂,翻译不到,现将该c++代码贴出来,若可以帮我翻译成c#也可以,或者生成能给c#使用的dll控件

谢谢各位大神

12 个解决方案

#1


c++代码
amrFileEncoder.cpp
#include "stdafx.h"
#include "amrFileCoderc.h"
#include "interf_enc.h"
#include "interf_dec.h"
#include "alaw.h"
#include 


int amrEncodeMode[] = {4750, 5150, 5900, 6700, 7400, 7950, 10200, 12200}; // amr 编码方式

void WriteWAVEFileHeader(FILE* fpwave, int nFrame)
{
char tag[10] = "";
RIFFHEADER riff;
XCHUNKHEADER chunk;
WAVEFORMATX wfx;

// 1. 写RIFF头
strcpy(tag, "RIFF");
memcpy(riff.chRiffID, tag, 4);
riff.nRiffSize = 4                                     // WAVE
+ sizeof(XCHUNKHEADER)               // fmt 
+ 18  // 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 = 18;
fwrite(&chunk, 1, sizeof(XCHUNKHEADER), fpwave);
memset(&wfx, 0, sizeof(WAVEFORMATX));
wfx.nFormatTag = 6;
wfx.nChannels = 1; // 单声道
wfx.nSamplesPerSec = 8000; // 8khz
wfx.nAvgBytesPerSec = 8000; //
wfx.nBlockAlign = 2;
wfx.nBitsPerSample = 8; // 8位

fwrite(&wfx, 1, 18, fpwave);

// 3. 写data块头
strcpy(tag, "data");
memcpy(chunk.chChunkID, tag, 4);
chunk.nChunkSize = nFrame*160*sizeof(unsigned char);
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 alawBuffer[PCM_FRAME_SIZE] = {0};
unsigned char stdFrameHeader;

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

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

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

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

/* init decoder */
destate = (int *)Decoder_Interface_init();

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

for (int iIndex = 0; iIndex < PCM_FRAME_SIZE; iIndex++)
{
alawBuffer[iIndex] = Snack_Lin2Alaw(pcmFrame[iIndex]);
}
// 解码一个AMR音频帧成PCM数据
Decoder_Interface_Decode(destate, amrFrame, pcmFrame, 0);
nFrameCount++;
fwrite(alawBuffer, sizeof(unsigned char), PCM_FRAME_SIZE, fpwave);

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

// 解码一个AMR音频帧成PCM数据 (8k-16b-单声道)
Decoder_Interface_Decode(destate, amrFrame, pcmFrame, 0);

for (int iIndex = 0; iIndex < PCM_FRAME_SIZE; iIndex++)
{
alawBuffer[iIndex] = Snack_Lin2Alaw(pcmFrame[iIndex]);
}

nFrameCount++;
fwrite(alawBuffer, sizeof(unsigned char), PCM_FRAME_SIZE, fpwave);
}

Decoder_Interface_exit(destate);

fclose(fpwave);

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

return nFrameCount;
}

#2


这个我刚弄过啊 。。。
这是我上次发表过的帖子不过没啥人回复。http://bbs.csdn.net/topics/390293178
使用ffmpeg可以解决。

#3


如果只是将amr转wav可以使用
http://www.ffmpeg-csharp.com/

反转就不行了。

#4


引用 2 楼 gaoming918 的回复:
这个我刚弄过啊 。。。
这是我上次发表过的帖子不过没啥人回复。http://bbs.csdn.net/topics/390293178
使用ffmpeg可以解决。

谢谢大神指点,能否将使用方法具体说一下

#5


请到 http://www.ffmpeg-csharp.com/下载

#6


说明一下:
http://www.ffmpeg-csharp.com
1 这个组件是付费的,如果是试用会转换时会弹出一个提示框来。这个可恶。
2 试用前需要对组件进行注册注册方法如下:
   下载后找到 CAVEditLib.dll,右键打开方式,找到C:\WINDOWS\system32\regsvr32.exe文件进行注册(或试用cmd命令注册),注册完成后在项目中引用即可使用。

有问题可继续追问。。。。
     

#7


该回复于2012-12-18 14:35:43被管理员删除

#8


引用 5 楼 gaoming918 的回复:
请到http://www.ffmpeg-csharp.com/下载


嗯 我按你说的做了   也用起了  就是弹个框出来   就算我用regsvr32注册了  单身还是谈框   这个是放到服务器里执行  不可能每次都去点   有什么办法去掉这个提示框吗

#9


楼主贴出来的C++代码可以运行吗?图中的那个初始化函数在哪里呢?用了什么库吗?求指点。

#10


引用 8 楼 yzt7805882 的回复:
引用 5 楼 gaoming918 的回复:请到http://www.ffmpeg-csharp.com/下载

嗯 我按你说的做了   也用起了  就是弹个框出来   就算我用regsvr32注册了  单身还是谈框   这个是放到服务器里执行  不可能每次都去点   有什么办法去掉这个提示框吗

 http://ffmpeg.org/中下载,里面有详细的接收。最终使用exe去转换的。

#11


用另一种方法解决了  直接开进程调用exe文件转码,但还是谢谢你了

#12


c++代码
amrFileEncoder.cpp


在主函数怎么用啊?求解

推荐阅读
  • [转]doc,ppt,xls文件格式转PDF格式http:blog.csdn.netlee353086articledetails7920355确实好用。需要注意的是#import ... [详细]
  • 基于Net Core 3.0与Web API的前后端分离开发:Vue.js在前端的应用
    本文介绍了如何使用Net Core 3.0和Web API进行前后端分离开发,并重点探讨了Vue.js在前端的应用。后端采用MySQL数据库和EF Core框架进行数据操作,开发环境为Windows 10和Visual Studio 2019,MySQL服务器版本为8.0.16。文章详细描述了API项目的创建过程、启动步骤以及必要的插件安装,为开发者提供了一套完整的开发指南。 ... [详细]
  • 2018年9月21日,Destoon官方发布了安全更新,修复了一个由用户“索马里的海贼”报告的前端GETShell漏洞。该漏洞存在于20180827版本的某CMS中,攻击者可以通过构造特定的HTTP请求,利用该漏洞在服务器上执行任意代码,从而获得对系统的控制权。此次更新建议所有用户尽快升级至最新版本,以确保系统的安全性。 ... [详细]
  • 开机自启动的几种方式
    0x01快速自启动目录快速启动目录自启动方式源于Windows中的一个目录,这个目录一般叫启动或者Startup。位于该目录下的PE文件会在开机后进行自启动 ... [详细]
  • 深入解析:Synchronized 关键字在 Java 中对 int 和 Integer 对象的作用与影响
    深入探讨了 `Synchronized` 关键字在 Java 中对 `int` 和 `Integer` 对象的影响。尽管初看此题似乎简单,但其实质在于理解对象的概念。根据《Java编程思想》第二章的观点,一切皆为对象。本文详细分析了 `Synchronized` 关键字在不同数据类型上的作用机制,特别是对基本数据类型 `int` 和包装类 `Integer` 的区别处理,帮助读者深入理解 Java 中的同步机制及其在多线程环境中的应用。 ... [详细]
  • 本文详细解析了使用C++实现的键盘输入记录程序的源代码,该程序在Windows应用程序开发中具有很高的实用价值。键盘记录功能不仅在远程控制软件中广泛应用,还为开发者提供了强大的调试和监控工具。通过具体实例,本文深入探讨了C++键盘记录程序的设计与实现,适合需要相关技术的开发者参考。 ... [详细]
  • 使用Maven JAR插件将单个或多个文件及其依赖项合并为一个可引用的JAR包
    本文介绍了如何利用Maven中的maven-assembly-plugin插件将单个或多个Java文件及其依赖项打包成一个可引用的JAR文件。首先,需要创建一个新的Maven项目,并将待打包的Java文件复制到该项目中。通过配置maven-assembly-plugin,可以实现将所有文件及其依赖项合并为一个独立的JAR包,方便在其他项目中引用和使用。此外,该方法还支持自定义装配描述符,以满足不同场景下的需求。 ... [详细]
  • Java能否直接通过HTTP将字节流绕过HEAP写入SD卡? ... [详细]
  • CSS3 @font-face 字体应用技术解析与实践
    在Web前端开发中,HTML教程和CSS3的结合使得网页设计更加多样化。长期以来,Web设计师受限于“web-safe”字体的选择。然而,CSS3中的`@font-face`规则允许从服务器端加载自定义字体,极大地丰富了网页的视觉效果。通过这一技术,设计师可以自由选择和使用各种字体,提升用户体验和页面美观度。本文将深入解析`@font-face`的实现原理,并提供实际应用案例,帮助开发者更好地掌握这一强大工具。 ... [详细]
  • 在Android应用开发中,实现与MySQL数据库的连接是一项重要的技术任务。本文详细介绍了Android连接MySQL数据库的操作流程和技术要点。首先,Android平台提供了SQLiteOpenHelper类作为数据库辅助工具,用于创建或打开数据库。开发者可以通过继承并扩展该类,实现对数据库的初始化和版本管理。此外,文章还探讨了使用第三方库如Retrofit或Volley进行网络请求,以及如何通过JSON格式交换数据,确保与MySQL服务器的高效通信。 ... [详细]
  • 基于Dubbo与Zipkin的微服务调用链路监控解决方案
    本文提出了一种基于Dubbo与Zipkin的微服务调用链路监控解决方案。通过抽象配置层,支持HTTP和Kafka两种数据上报方式,实现了灵活且高效的调用链路追踪。该方案不仅提升了系统的可维护性和扩展性,还为故障排查提供了强大的支持。 ... [详细]
  • CTF竞赛中文件上传技巧与安全绕过方法深入解析
    CTF竞赛中文件上传技巧与安全绕过方法深入解析 ... [详细]
  • 本文介绍了如何在iOS平台上使用GLSL着色器将YV12格式的视频帧数据转换为RGB格式,并展示了转换后的图像效果。通过详细的技术实现步骤和代码示例,读者可以轻松掌握这一过程,适用于需要进行视频处理的应用开发。 ... [详细]
  • 本文介绍了UUID(通用唯一标识符)的概念及其在JavaScript中生成Java兼容UUID的代码实现与优化技巧。UUID是一个128位的唯一标识符,广泛应用于分布式系统中以确保唯一性。文章详细探讨了如何利用JavaScript生成符合Java标准的UUID,并提供了多种优化方法,以提高生成效率和兼容性。 ... [详细]
  • Netty框架中运用Protobuf实现高效通信协议
    在Netty框架中,通过引入Protobuf来实现高效的通信协议。为了使用Protobuf,需要先准备好环境,包括下载并安装Protobuf的代码生成器`protoc`以及相应的源码包。具体资源可从官方下载页面获取,确保版本兼容性以充分发挥其性能优势。此外,配置好开发环境后,可以通过定义`.proto`文件来自动生成Java类,从而简化数据序列化和反序列化的操作,提高通信效率。 ... [详细]
author-avatar
我就唔分_753
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有