原文:http://www.cnblogs.com/saucerman/p/5555793.html

因为项目要加语音。语音数据都非常大。所以顺带就把之前写的网络模块一起测试了。

然后发现了一些bug,逐修。本来想在原文上面直接修改掉。但是恐怕已经看到的人拿去用了之后,再回头看也不一定能看明白,索性再写一文,将新文件直接放上来。

错误修改:

  1. 网络接收数据后,有一种情况没有处理完整,导致接收数据之后数据池的计数器没有向后偏移
  2. 网络数据处理后,当当前包仅剩1字节,下一个次数据进来的时候,需要2字节才能确认当前消息长度。增加了消息补齐机制。
  3. 增加了当网络数据拥堵的时候,直接断开当前链接。
  4. MsgUnPack的GetHead函数获取消息id的时候使用了错误的函数,导致数据偏移不正确
  5. MsgUnPack的UnPack(byte[] mBuff, ushort offset, ushort len),由于总buff扩大,导致offset参数超过上限,改为int
  6. 消息事件增加了错误消息ID过滤

由于语音的需求,将原本的服务器段接受buff容量扩大一倍。增加了语音模块。

特别说下语音模块。

http://blog.csdn.net/huutu/article/details/20216613

这是原文。

稍做修改。特别说一下这个语音模块在使用中容易遇到的问题。

  1. 如果声音太小,可能是你录音设备的侦听开得不够。
  2. 本地测试还好,放到网络上之后,因为代码里有处理,如果没有对象会创建对象并且添加必要组件。原文在创建的时候比特率是手动填写的。导致我客户端一个比特率,服务器一个比特率。然后客户端听着一切正常,传给服务器就错了。后来查了一天,排查各个代码段之后才找到这个原因。

以下是代码:

新增语音模块:

  1 using System;
  2 using System.Collections.Generic;
  3 using System.IO;
  4 using System.Linq;
  5 using System.Text;
  6 using UnityEngine;
  7 using System.Collections;
  8 
  9 [RequireComponent(typeof(AudioSource))]
 10 public class MicroPhoneInput : MonoBehaviour
 11 {
 12 
 13     private static MicroPhoneInput m_instance;
 14 
 15     public float sensitivity = 100;
 16     public float loudness = 0;
 17 
 18     private static string[] micArray = null;
 19 
 20     const int HEADER_SIZE = 44;
 21 
 22     const int RECORD_TIME = 5;
 23     const int RECORD_frequency = 8000;
 24 
 25     // Use this for initialization  
 26     void Start()
 27     {
 28     }
 29 
 30     public static MicroPhoneInput getInstance()
 31     {
 32         if (m_instance == null)
 33         {
 34             micArray = Microphone.devices;
 35             if (micArray.Length == 0)
 36             {
 37                 Debug.LogError("Microphone.devices is null");
 38             }
 39             foreach (string deviceStr in Microphone.devices)
 40             {
 41                 Debug.Log("device name = " + deviceStr);
 42             }
 43             if (micArray.Length == 0)
 44             {
 45                 Debug.LogError("no mic device");
 46             }
 47 
 48             GameObject MicObj = new GameObject("MicObj");
 49             m_instance = MicObj.AddComponent<MicroPhoneInput>();
 50         }
 51         return m_instance;
 52     }
 53 
 54     public void StartRecord()
 55     {
 56         audio.Stop();
 57         if (micArray.Length == 0)
 58         {
 59             Debug.Log("No Record Device!");
 60             return;
 61         }
 62         audio.loop = false;
 63         audio.mute = true;
 64         audio.clip = Microphone.Start(null, false, RECORD_TIME, RECORD_frequency); //22050   
 65         while (!(Microphone.GetPosition(null) > 0))
 66         {
 67         }
 68         audio.Play();
 69         Debug.Log("StartRecord");
 70         //倒计时  
 71         StartCoroutine(TimeDown());
 72 
 73     }
 74 
 75     public void StopRecord()
 76     {
 77         if (micArray.Length == 0)
 78         {
 79             Debug.Log("No Record Device!");
 80             return;
 81         }
 82         if (!Microphone.IsRecording(null))
 83         {
 84             return;
 85         }
 86         Microphone.End(null);
 87         audio.Stop();
 88 
 89         Debug.Log("StopRecord");
 90 
 91     }
 92 
 93     public Byte[] GetClipData()
 94     {
 95         if (audio.clip == null)
 96         {
 97             Debug.Log("GetClipData audio.clip is null");
 98             return null;
 99         }
100 
101         float[] samples = new float[audio.clip.samples];
102 
103         audio.clip.GetData(samples, 0);
104 
105 
106         Byte[] outData = new byte[samples.Length * 2];
107         //Int16[] intData = new Int16[samples.Length];  
108         //converting in 2 float[] steps to Int16[], //then Int16[] to Byte[]  
109 
110         int rescaleFactor = 32767; //to convert float to Int16  
111 
112         for (int i = 0; i < samples.Length; i++)
113         {
114             short temshort = (short)(samples[i] * rescaleFactor);
115 
116             Byte[] temdata = System.BitConverter.GetBytes(temshort);
117 
118             outData[i * 2] = temdata[0];
119             outData[i * 2 + 1] = temdata[1];
120 
121 
122         }
123         if (outData == null || outData.Length <= 0)
124         {
125             Debug.Log("GetClipData intData is null");
126             return null;
127         }
128         //return intData;  
129         return outData;
130     }
131     public void PlayClipData(Int16[] intArr)
132     {
133         if (intArr.Length == 0)
134         {
135             Debug.Log("get intarr clipdata is null");
136             return;
137         }
138         //从Int16[]到float[]  
139         float[] samples = new float[intArr.Length];
140         int rescaleFactor = 32767;
141         for (int i = 0; i < intArr.Length; i++)
142         {
143             samples[i] = (float)intArr[i] / rescaleFactor;
144         }
145 
146         //从float[]到Clip  
147         AudioSource audioSource = this.GetComponent<AudioSource>();
148         if (audioSource.clip == null)
149         {
150             audioSource.clip = AudioClip.Create("playRecordClip", intArr.Length, 1, RECORD_frequency, false, false);
151         }
152         audioSource.clip.SetData(samples, 0);
153         audioSource.mute = false;
154         audioSource.Play();
155     }
156     public void PlayRecord()
157     {
158         if (audio.clip == null)
159         {
160             Debug.Log("audio.clip=null");
161             return;
162         }
163         audio.mute = false;
164         audio.loop = false;
165         audio.Play();
166         Debug.Log("PlayRecord");
167 
168     }
169 
170 
171 
172     public float GetAveragedVolume()
173     {
174         float[] data = new float[256];
175         float a = 0;
176         audio.GetOutputData(data, 0);
177         foreach (float s in data)
178         {
179             a += Mathf.Abs(s);
180         }
181         return a / 256;
182     }
183 
184     // Update is called once per frame  
185     void Update()
186     {
187 //         loudness = GetAveragedVolume() * sensitivity;
188 //         if (loudness > 1)
189 //         {
190 //             Debug.Log("loudness = " + loudness);
191 //         }
192     }
193 
194     private IEnumerator TimeDown()
195     {
196         Debug.Log(" IEnumerator TimeDown()");
197 
198         int time = 0;
199         while (time < RECORD_TIME)
200         {
201             if (!Microphone.IsRecording(null))
202             { //如果没有录制  
203                 Debug.Log("IsRecording false");
204                 yield break;
205             }
206             Debug.Log("yield return new WaitForSeconds " + time);
207             yield return new WaitForSeconds(1);
208             time++;
209         }
210         if (time >= 10)
211         {
212             Debug.Log("RECORD_TIME is out! stop record!");
213             StopRecord();
214         }
215         yield return 0;
216     }
217 }
MicroPhoneInput.cs

相关文章:

  • 2021-08-31
  • 2022-12-23
  • 2021-11-19
  • 2021-09-08
  • 2022-12-23
  • 2022-12-23
  • 2021-09-19
  • 2021-10-30
猜你喜欢
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2021-12-04
  • 2021-10-08
  • 2021-07-17
  • 2021-07-05
相关资源
相似解决方案