热门标签 | 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


在主函数怎么用啊?求解

推荐阅读
  • 如何实现织梦DedeCms全站伪静态
    本文介绍了如何通过修改织梦DedeCms源代码来实现全站伪静态,以提高管理和SEO效果。全站伪静态可以避免重复URL的问题,同时通过使用mod_rewrite伪静态模块和.htaccess正则表达式,可以更好地适应搜索引擎的需求。文章还提到了一些相关的技术和工具,如Ubuntu、qt编程、tomcat端口、爬虫、php request根目录等。 ... [详细]
  • VScode格式化文档换行或不换行的设置方法
    本文介绍了在VScode中设置格式化文档换行或不换行的方法,包括使用插件和修改settings.json文件的内容。详细步骤为:找到settings.json文件,将其中的代码替换为指定的代码。 ... [详细]
  • 基于layUI的图片上传前预览功能的2种实现方式
    本文介绍了基于layUI的图片上传前预览功能的两种实现方式:一种是使用blob+FileReader,另一种是使用layUI自带的参数。通过选择文件后点击文件名,在页面中间弹窗内预览图片。其中,layUI自带的参数实现了图片预览功能。该功能依赖于layUI的上传模块,并使用了blob和FileReader来读取本地文件并获取图像的base64编码。点击文件名时会执行See()函数。摘要长度为169字。 ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • 本文介绍了C++中省略号类型和参数个数不确定函数参数的使用方法,并提供了一个范例。通过宏定义的方式,可以方便地处理不定参数的情况。文章中给出了具体的代码实现,并对代码进行了解释和说明。这对于需要处理不定参数的情况的程序员来说,是一个很有用的参考资料。 ... [详细]
  • t-io 2.0.0发布-法网天眼第一版的回顾和更新说明
    本文回顾了t-io 1.x版本的工程结构和性能数据,并介绍了t-io在码云上的成绩和用户反馈。同时,还提到了@openSeLi同学发布的t-io 30W长连接并发压力测试报告。最后,详细介绍了t-io 2.0.0版本的更新内容,包括更简洁的使用方式和内置的httpsession功能。 ... [详细]
  • sklearn数据集库中的常用数据集类型介绍
    本文介绍了sklearn数据集库中常用的数据集类型,包括玩具数据集和样本生成器。其中详细介绍了波士顿房价数据集,包含了波士顿506处房屋的13种不同特征以及房屋价格,适用于回归任务。 ... [详细]
  • 本文介绍了在mac环境下使用nginx配置nodejs代理服务器的步骤,包括安装nginx、创建目录和文件、配置代理的域名和日志记录等。 ... [详细]
  • 在CentOS/RHEL 7/6,Fedora 27/26/25上安装JAVA 9的步骤和方法
    本文介绍了在CentOS/RHEL 7/6,Fedora 27/26/25上安装JAVA 9的详细步骤和方法。首先需要下载最新的Java SE Development Kit 9发行版,然后按照给出的Shell命令行方式进行安装。详细的步骤和方法请参考正文内容。 ... [详细]
  • SpringMVC接收请求参数的方式总结
    本文总结了在SpringMVC开发中处理控制器参数的各种方式,包括处理使用@RequestParam注解的参数、MultipartFile类型参数和Simple类型参数的RequestParamMethodArgumentResolver,处理@RequestBody注解的参数的RequestResponseBodyMethodProcessor,以及PathVariableMapMethodArgumentResol等子类。 ... [详细]
  • Vagrant虚拟化工具的安装和使用教程
    本文介绍了Vagrant虚拟化工具的安装和使用教程。首先介绍了安装virtualBox和Vagrant的步骤。然后详细说明了Vagrant的安装和使用方法,包括如何检查安装是否成功。最后介绍了下载虚拟机镜像的步骤,以及Vagrant镜像网站的相关信息。 ... [详细]
  • 图像因存在错误而无法显示 ... [详细]
  • 本文介绍了一个免费的asp.net控件,该控件具备数据显示、录入、更新、删除等功能。它比datagrid更易用、更实用,同时具备多种功能,例如属性设置、数据排序、字段类型格式化显示、密码字段支持、图像字段上传和生成缩略图等。此外,它还提供了数据验证、日期选择器、数字选择器等功能,以及防止注入攻击、非本页提交和自动分页技术等安全性和性能优化功能。最后,该控件还支持字段值合计和数据导出功能。总之,该控件功能强大且免费,适用于asp.net开发。 ... [详细]
  • 原文地址http://balau82.wordpress.com/2010/02/28/hello-world-for-bare-metal-arm-using-qemu/最开始时 ... [详细]
  • pc电脑如何投屏到电视?DLNA主要步骤通过DLNA连接,使用WindowsMediaPlayer的流媒体播放举例:电脑和电视机都是连接的 ... [详细]
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社区 版权所有