• 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();
                    }
                }
            }
    在寂寞的日子里沉淀自己,在程序的日子里找到自己,我为梦想而坚持!

    如果对你有重要帮助,可以打赏一下!


  • 相关阅读:
    [学习笔记] Symfony2学习笔记之数据库操作 [转]
    [学习笔记] Twig 的 tags学习 [转]
    [学习笔记] 设计模式之状态机模式 [转]
    【转】Lombok介绍、使用方法和总结
    RabbitMQ
    百度云下载不限速方法+软件
    json数据的key的读取和替换
    spring boot配置mybatis和事务管理
    windows强大的快捷键
    rtsp向rtmp推流
  • 原文地址:https://www.cnblogs.com/Kummy/p/3688170.html
Copyright © 2020-2023  润新知