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


在主函数怎么用啊?求解

推荐阅读
  • Python处理Word文档的高效技巧
    本文详细介绍了如何使用Python处理Word文档,涵盖从基础操作到高级功能的各种技巧。我们将探讨如何生成文档、定义样式、提取表格数据以及处理超链接和图片等内容。 ... [详细]
  • 本文介绍如何通过Windows批处理脚本定期检查并重启Java应用程序,确保其持续稳定运行。脚本每30分钟检查一次,并在需要时重启Java程序。同时,它会将任务结果发送到Redis。 ... [详细]
  • 本文探讨了在使用Azure Active Directory进行用户身份验证时,结合AddAuthentication和RequireAuthenticatedUser的必要性及其潜在冗余问题。 ... [详细]
  • 本文探讨了使用C#在SQL Server和Access数据库中批量插入多条数据的性能差异。通过具体代码示例,详细分析了两种数据库的执行效率,并提供了优化建议。 ... [详细]
  • 本文介绍如何在 Android 中通过代码模拟用户的点击和滑动操作,包括参数说明、事件生成及处理逻辑。详细解析了视图(View)对象、坐标偏移量以及不同类型的滑动方式。 ... [详细]
  • 优化联通光猫DNS服务器设置
    本文详细介绍了如何为联通光猫配置DNS服务器地址,以提高网络解析效率和访问体验。通过智能线路解析功能,域名解析可以根据访问者的IP来源和类型进行差异化处理,从而实现更优的网络性能。 ... [详细]
  • 高效解决应用崩溃问题!友盟新版错误分析工具全面升级
    友盟推出的最新版错误分析工具,专为移动开发者设计,提供强大的Crash收集与分析功能。该工具能够实时监控App运行状态,快速发现并修复错误,显著提升应用的稳定性和用户体验。 ... [详细]
  • 以下实例展示了locals( ... [详细]
  • andr ... [详细]
  • 本题涉及一棵由N个节点组成的树(共有N-1条边),初始时所有节点均为白色。题目要求处理两种操作:一是改变某个节点的颜色(从白变黑或从黑变白);二是查询从根节点到指定节点路径上的第一个黑色节点,若无则输出-1。 ... [详细]
  • 深入解析TCP/IP五层协议
    本文详细介绍了TCP/IP五层协议模型,包括物理层、数据链路层、网络层、传输层和应用层。每层的功能及其相互关系将被逐一解释,帮助读者理解互联网通信的原理。此外,还特别讨论了UDP和TCP协议的特点以及三次握手、四次挥手的过程。 ... [详细]
  • 本文介绍了一种适用于小型创业公司的小规模每日数据备份及健康检查的自动化解决方案。通过简单的Shell脚本实现本地数据库的每日全量备份,并将备份文件上传至中心备份服务器。同时,编写了自动检测脚本来确保备份的完整性和及时性,一旦发现异常,会通过邮件和短信通知相关人员。 ... [详细]
  • 如何将本地Docker镜像推送到阿里云容器镜像服务
    本文详细介绍将本地Docker镜像上传至阿里云容器镜像服务的步骤,包括登录、查看镜像列表、推送镜像以及确认上传结果。通过本文,您将掌握如何高效地管理Docker镜像并将其存储在阿里云的镜像仓库中。 ... [详细]
  • C#设计模式学习笔记:观察者模式解析
    本文将探讨观察者模式的基本概念、应用场景及其在C#中的实现方法。通过借鉴《Head First Design Patterns》和维基百科等资源,详细介绍该模式的工作原理,并提供具体代码示例。 ... [详细]
  • 本文详细介绍了在不同操作系统中查找和设置网卡的方法,涵盖了Windows系统的具体步骤,并提供了关于网卡位置、无线网络设置及常见问题的解答。 ... [详细]
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社区 版权所有