Kummy's Blog

o(︶︿︶)o { name : 'Kummy' , job : 'Feser' }

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

 /// <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();
                }
            }
        }

 

posted @ 2014-04-25 10:38  李 维  阅读(757)  评论(0编辑  收藏  举报