- Home /
Question by
A_munim · May 15, 2018 at 04:55 PM ·
networkingmicrophone
Networking Mic
H!!
As always I have tried debugging my code and everything but after so many days still no progress but I remember at some point the audio just produced like no signal TV sound zzzz
I'll post my code and define some things to not waste your time only figuering out what just happened
using System.Collections.Generic;
using System.Collections;
using System.Text;
using System.Linq;
using UnityEngine;
using System;
[RequireComponent(typeof(AudioSource))]
/// <summary>
/// Source : http://forum.unity3d.com/threads/microphone-network-test.123776/
/// </summary>
public class MicInput : MonoBehaviour
{
AudioClip c;
AudioSource audio;
int lastSample;
int FREQUENCY = 44100;
bool _started;
void Start()
{
audio = GetComponent<AudioSource>();
}
void Update()
{
if (_started)
{
int pos = Microphone.GetPosition(null);
int diff = pos - lastSample;
if (diff > 0)
{
float[] samples = new float[diff * c.channels];
c.GetData(samples, lastSample);
SendData(samples);
}
lastSample = pos;
}
}
public void StartGame()
{
if (true)
{
c = Microphone.Start(null, true, 100, FREQUENCY);
while (Microphone.GetPosition(null) < 0) { } // HACK from Riro
FindObjectOfType<Client>().AudioReceivers += ReceiveAudioData;
_started = true;
}
}
public void Receive(byte[] ba, int chan)
{
float[] f = ToFloatArray(ba);
#pragma warning disable CS0618 // Type or member is obsolete
audio.clip = AudioClip.Create("test", f.Length, chan, FREQUENCY, true, true);
#pragma warning restore CS0618 // Type or member is obsolete
audio.clip.SetData(f, 0);
/*if (!audio.isPlaying)*/ audio.Play();
}
public void SendData(float[] data)
{
if (_started)
{
byte[] d = ToByteArray(data);
string strData = Convert(d);
print("data length : " + strData.Length);
FindObjectOfType<Client>().Send("CAUDIO|" + strData);
}
}
private void ReceiveAudioData(string data)
{
byte[] aData = Convert(data);
print("bytes length : " + aData.Length);
Receive(aData, c.channels);
}
public List<int> Factor(int number)
{
List<int> factors = new List<int>();
int max = (int)Math.Sqrt(number); //round down
for (int factor = 1; factor <= max; ++factor)
{ //test from 1 to the square root, or the int below it, inclusive.
if (number % factor == 0)
{
factors.Add(factor);
if (factor != number / factor)
{ // Don't add the square root twice! Thanks Jon
factors.Add(number / factor);
}
}
}
return factors;
}
public byte[] ToByteArray(float[] floatArray)
{
int len = floatArray.Length * 4;
byte[] byteArray = new byte[len];
int pos = 0;
foreach (float f in floatArray)
{
byte[] data = System.BitConverter.GetBytes(f);
System.Array.Copy(data, 0, byteArray, pos, 4);
pos += 4;
}
return byteArray;
}
public float[] ToFloatArray(byte[] byteArray)
{
int magicNumber = Factor(byteArray.Length)[1];
int len = byteArray.Length / magicNumber;
float[] floatArray = new float[len];
for (int i = 0; i < byteArray.Length; i += magicNumber)
{
floatArray[i / magicNumber] = System.BitConverter.ToSingle(byteArray, i);
}
return floatArray;
}
/// <summary>
/// Convert Bytes(byte array) to string
/// </summary>
/// <param name="data"></param>
/// <returns></returns>
string Convert(byte[] data)
{
char[] characters = data.Select(b => (char)b).ToArray();
return new string(characters);
}
/// <summary>
/// Convert string to bytes(byte array)
/// </summary>
/// <param name="data"></param>
/// <returns></returns>
byte[] Convert(string data)
{
return data.ToCharArray().Select(c => (byte)c).ToArray();
}
}
most is self explainatory but the magicNumber helps when you have a string of 3 then you convert it to float array so you get 3 bytes now if you increment i by 4 then it won't work for some reason ok?
Comment