您的位置:首页 > 其它

Web Api 中使用 PCM TO WAV 的语音操作

2014-04-25 10:38 218 查看
/// <summary>
/// 语音【文件、上传、解码、保存(WAV)】
/// </summary>
[DeveloperEx("Liwei:秘书语音需求单")]
public class AudioController : ClubBaseController
{
#region Android和IOS的一些音频参数
/****************
//格式
#define NAOMI_SPEEX_FORMAT kAudioFormatLinearPCM
//采样
#define NAOMI_SPEEX_RATE 8000
//声道
#define NAOMI_SPEEX_NUMBER_CHANNEL 1
//采样位数
#define NAOMI_SPEEX_BITDEPTH 16

private static final int FREQUENCY = 8000;
private static final int audioEncoding = AudioFormat.ENCODING_PCM_16BIT;
private static final int CHANNEL = AudioFormat.CHANNEL_IN_MONO;//0x10
***************/
#endregion
private ILogProvider log = LogFactory.Create();
private FileStream fileStream = null;
private BinaryWriter binaryWriter = null;

/// <summary>
/// PCM To WAV
/// 添加Wav头文件
/// </summary>
[NonAction]
private void CreateSoundFile(string path)
{
fileStream = new FileStream(path, FileMode.Create);
binaryWriter = new BinaryWriter(fileStream);

//Set up file with RIFF chunk info. 每个WAVE文件的头四个字节便是“RIFF”。
char[] ChunkRiff = { 'R', 'I', 'F', 'F' };
char[] ChunkType = { 'W', 'A', 'V', 'E' };
char[] ChunkFmt = { 'f', 'm', 't', ' ' };
char[] ChunkData = { 'd', 'a', 't', 'a' };

short shPad = 1;                 // File padding
int nFormatChunkLength = 0x10;   // Format chunk length.
int nLength = 0;                 // File length, minus first 8 bytes of RIFF description. This will be filled in later.

short bitsPerSample = 16;     //每个采样需要的bit数
//short khCaiYang = 8000;       //16KHz 采样频率
//short bitSecondRate = 16000;  //-每秒所需字节数
short channels = 1;           //声道数目,1-- 单声道;2-- 双声道
short shBytesPerSample = 2;   //一个样本点的字节数目

//------- RIFF 块 -------
binaryWriter.Write(ChunkRiff);
binaryWriter.Write(nLength);
binaryWriter.Write(ChunkType);

//------- WAVE块 ---------
binaryWriter.Write(ChunkFmt);
binaryWriter.Write(nFormatChunkLength);
binaryWriter.Write(shPad);

binaryWriter.Write(channels);         //Mono,声道数目,1-- 单声道;2-- 双声道
binaryWriter.Write(8000);             //16KHz 采样频率
binaryWriter.Write(16000);            //每秒所需字节数
binaryWriter.Write(shBytesPerSample); //数据块对齐单位(每个采样需要的字节数)
binaryWriter.Write(bitsPerSample);    //16Bit,每个采样需要的bit数

//------- 数据块 ---------
binaryWriter.Write(ChunkData);
binaryWriter.Write((int)0);   // The sample length will be written in later.
}

/// <summary>
///【上传、保存、PCM源数据文件】
/// </summary>
[AllowAnonymous]
public ResponseModel UploadAudio()
{
try
{
//-------上传文件---------
var hash = CommonUpload("/UploadAudio/", (string i) =>
{
i = Guid.NewGuid().ToString("n");
return i;
}, isFile: true);

if (hash["retInt"].Equals("1"))
{
string uploadPcmFile = hash["retSrc"].ToString();
//--------获取pcm的文件名------------
string pcmFileName = uploadPcmFile.Substring(0, uploadPcmFile.IndexOf(Path.GetExtension(uploadPcmFile)));

string wavFile = pcmFileName + ".wav";
string physicPCMPath = hash["retSrcDirPath"].ToString();
string tempWavPath = Path.Combine(HttpContext.Current.Server.MapPath(physicPCMPath), wavFile);

//--------添加wav文件头-----
CreateSoundFile(tempWavPath);

#region 读取上传的PCM源文件
string fileName = Path.Combine(HttpContext.Current.Server.MapPath(physicPCMPath), uploadPcmFile);
FileInfo fileinfo = new FileInfo(fileName);
FileStream fs = fileinfo.OpenRead();
int length = (int)fs.Length;
byte[] bytes = new byte[length];
fs.Read(bytes, 0, length);
fs.Close();
fs.Dispose();
#endregion

#region  向WAV音频中写入数据
binaryWriter.Write(bytes, 0, bytes.Length);
binaryWriter.Seek(4, SeekOrigin.Begin);
binaryWriter.Write((int)(bytes.Length + 36)); // 写文件长度
binaryWriter.Seek(40, SeekOrigin.Begin);
binaryWriter.Write(bytes.Length);
fileStream.Close();
#endregion

//----------删除用户PCM的源文件---------------
if (System.IO.File.Exists(fileName))
{
FileInfo fi = new FileInfo(fileName);
if (fi.Attributes.ToString().IndexOf("ReadOnly") != -1)
fi.Attributes = FileAttributes.Normal;
System.IO.File.Delete(fileName);
}
return SetOfMessage(data: new { filename = base.domainSite + physicPCMPath + wavFile });
}
else
{
return SetOfMessage(status: 0, message: hash["retMsg"].ToString());
}
}
catch (Exception ex)
{
log.Log(LogLevel.Info, "上传语音出错误了!", ex.Message);
//--------记录日志-------------
return SetOfMessage(data: null, message: "语音上传出现错误了!", status: 0); ;
}
finally
{
if (fileStream != null)
{
fileStream.Close();
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: