【Unity】Unity Microphone录音 保存wav 功能

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using UnityEngine;
using System.Collections;


[RequireComponent (typeof(AudioSource))]
public class MicroPhoneInput : MonoBehaviour 
{

	private static MicroPhoneInput m_instance;
	private AudioClip clip;

	private string path_1; 

	public float sensitivity=100;
	public float loudness=0;

    private static string[] micArray=null;

    const int HEADER_SIZE = 44;

    const int RECORD_TIME = 10;

	// Use this for initialization
	void Start () {
	}
	//--------------------------------

	public static MicroPhoneInput getInstance()
	{
		if (m_instance == null) 
		{
            micArray = Microphone.devices;
            if (micArray.Length == 0)
            {
                Debug.LogError ("Microphone.devices is null");
            }
            foreach (string deviceStr in Microphone.devices)
            {
                Debug.Log("device name = " + deviceStr);
            }
			if(micArray.Length==0)
			{
				Debug.LogError("no mic device");
			}

			GameObject MicObj=new GameObject("MicObj");
			m_instance= MicObj.AddComponent<MicroPhoneInput>();
		}
		return m_instance;
	}

	public void StartRecord()
	{
        GetComponent<AudioSource>().Stop();
        if (micArray.Length == 0)
        {
            Debug.Log("No Record Device!");
            return;
        }
		GetComponent<AudioSource>().loop = false;
		GetComponent<AudioSource>().mute = true;
        GetComponent<AudioSource>().clip = Microphone.Start(null, false, RECORD_TIME, 44100); //22050 
		clip = GetComponent<AudioSource>().clip;
		while (!(Microphone.GetPosition(null)>0)) {
		}
		GetComponent<AudioSource>().Play ();
        Debug.Log("StartRecord");
        //倒计时
        StartCoroutine(TimeDown());
       
	}

	public  void StopRecord()
	{
	        if (micArray.Length == 0)
        {
            Debug.Log("No Record Device!");
            return;
        }
        if (!Microphone.IsRecording(null))
        {
            return;
        }
		Microphone.End (null);
        GetComponent<AudioSource>().Stop();

        Debug.Log("StopRecord");

	}

	public Byte[] GetClipData()
    {
        if (GetComponent<AudioSource>().clip == null)
        {
            Debug.Log("GetClipData audio.clip is null");
            return null; 
        }

        float[] samples = new float[GetComponent<AudioSource>().clip.samples];

        GetComponent<AudioSource>().clip.GetData(samples, 0);


		Byte[] outData = new byte[samples.Length * 2];
        //Int16[] intData = new Int16[samples.Length];
        //converting in 2 float[] steps to Int16[], //then Int16[] to Byte[]

        int rescaleFactor = 32767; //to convert float to Int16

        for (int i = 0; i < samples.Length; i++)
        {
            short temshort = (short)(samples[i] * rescaleFactor);

			Byte[] temdata=System.BitConverter.GetBytes(temshort);

			outData[i*2]=temdata[0];
			outData[i*2+1]=temdata[1];


        }
		if (outData == null || outData.Length <= 0)
        {
            Debug.Log("GetClipData intData is null");
            return null; 
        }
        //return intData;

		return outData;
    }
    public void PlayClipData(Int16[] intArr)
    {

        string aaastr = intArr.ToString();
        long  aaalength=aaastr.Length;
        Debug.LogError("aaalength=" + aaalength);

		string aaastr1 = Convert.ToString (intArr);
		aaalength = aaastr1.Length;
		Debug.LogError("aaalength=" + aaalength);

        if (intArr.Length == 0)
        {
            Debug.Log("get intarr clipdata is null");
            return;
        }
        //从Int16[]到float[]
        float[] samples = new float[intArr.Length];
        int rescaleFactor = 32767;
        for (int i = 0; i < intArr.Length; i++)
        {
            samples[i] = (float)intArr[i] / rescaleFactor;
        }
        
        //从float[]到Clip
        AudioSource audioSource = this.GetComponent<AudioSource>();
        if (audioSource.clip == null)
        {
            audioSource.clip = AudioClip.Create("playRecordClip", intArr.Length, 1, 44100, false, false);
        }
        audioSource.clip.SetData(samples, 0);
        audioSource.mute = false;
        audioSource.Play();
    }
    public void PlayRecord()
	{
        if (GetComponent<AudioSource>().clip == null)
        {
            Debug.Log("audio.clip=null");
            return;
        }
		GetComponent<AudioSource>().mute = false;
		GetComponent<AudioSource>().loop = false;
		GetComponent<AudioSource>().Play ();
        Debug.Log("PlayRecord");

	}



	public  float GetAveragedVolume()
	{
		float[] data=new float[256];
		float a=0;
		GetComponent<AudioSource>().GetOutputData(data,0);
		foreach(float s in data)
		{
			a+=Mathf.Abs(s);
		}
		return a/256;
	}
	
	// Update is called once per frame
	void Update ()
    {
		loudness = GetAveragedVolume () * sensitivity;
		if (loudness > 1) 
		{
			Debug.Log("loudness = "+loudness);
		}
	}

    private IEnumerator TimeDown()
    {
        Debug.Log(" IEnumerator TimeDown()");

        int time = 0;
        while (time < RECORD_TIME)
        {
			if (!Microphone.IsRecording (null)) 
			{ //如果没有录制
				Debug.Log ("IsRecording false");
				yield break;
			}
            Debug.Log("yield return new WaitForSeconds "+time);
            yield return new WaitForSeconds(1);
            time++;
        }
        if (time >= 10)
        {
            Debug.Log("RECORD_TIME is out! stop record!");
            StopRecord();
        }
        yield return 0;
    }





	public void SaveMusic()
	{
		Save ("123",clip);
	}
//	public void UnSaveMusic()
//	{
//		clip = null;
//	}
	//保存wav 模式
	public static bool Save(string filename, AudioClip clip) {

		Debug.Log(Application.persistentDataPath);
		if (!filename.ToLower().EndsWith(".wav")) {
			filename += ".wav";
		}

		#if UNITY_IPHONE
//		path_1 = Application.persistentDataPath;
		string filepath = Path.Combine(Application.persistentDataPath, filename);
		#endif

		#if UNITY_STANDALONE_WIN
		string filepath =  filename;
		#endif
		#if UNITY_ANDROID

		string filepath = Path.Combine(Application.persistentDataPath, filename);
		#endif

//		string filepath = Path.Combine(Application.persistentDataPath, filename);
		Debug.Log(filepath);

		// Make sure directory exists if user is saving to sub dir.
		Directory.CreateDirectory(Path.GetDirectoryName(filepath));

		using (FileStream fileStream = CreateEmpty(filepath)) {

			ConvertAndWrite(fileStream, clip);

			WriteHeader(fileStream, clip);
		}

		return true; // TODO: return false if there's a failure saving the file
	}
	static FileStream CreateEmpty(string filepath) {
		FileStream fileStream = new FileStream(filepath, FileMode.Create);
		byte emptyByte = new byte();

		for(int i = 0; i < HEADER_SIZE; i++) //preparing the header
		{
			fileStream.WriteByte(emptyByte);
		}

		return fileStream;
	}
	static void ConvertAndWrite(FileStream fileStream, AudioClip clip) {

		float[] samples = new float[clip.samples];

		clip.GetData(samples, 0);

		Int16[] intData = new Int16[samples.Length];
		//converting in 2 float[] steps to Int16[], //then Int16[] to Byte[]

		Byte[] bytesData = new Byte[samples.Length * 2];
		//bytesData array is twice the size of
		//dataSource array because a float converted in Int16 is 2 bytes.

		int rescaleFactor = 32767; //to convert float to Int16

		for (int i = 0; i<samples.Length; i++) {
			intData[i] = (short) (samples[i] * rescaleFactor);
			Byte[] byteArr = new Byte[2];
			byteArr = BitConverter.GetBytes(intData[i]);
			byteArr.CopyTo(bytesData, i * 2);
		}

		fileStream.Write(bytesData, 0, bytesData.Length);
	}
	static void WriteHeader(FileStream fileStream, AudioClip clip) {

		int hz = clip.frequency;
		int channels = clip.channels;
		int samples = clip.samples;

		fileStream.Seek(0, SeekOrigin.Begin);

		Byte[] riff = System.Text.Encoding.UTF8.GetBytes("RIFF");
		fileStream.Write(riff, 0, 4);

		Byte[] chunkSize = BitConverter.GetBytes(fileStream.Length - 8);
		fileStream.Write(chunkSize, 0, 4);

		Byte[] wave = System.Text.Encoding.UTF8.GetBytes("WAVE");
		fileStream.Write(wave, 0, 4);

		Byte[] fmt = System.Text.Encoding.UTF8.GetBytes("fmt ");
		fileStream.Write(fmt, 0, 4);

		Byte[] subChunk1 = BitConverter.GetBytes(16);
		fileStream.Write(subChunk1, 0, 4);

		UInt16 two = 2;
		UInt16 one = 1;

		Byte[] audioFormat = BitConverter.GetBytes(one);
		fileStream.Write(audioFormat, 0, 2);

		Byte[] numChannels = BitConverter.GetBytes(channels);
		fileStream.Write(numChannels, 0, 2);

		Byte[] sampleRate = BitConverter.GetBytes(hz);
		fileStream.Write(sampleRate, 0, 4);

		Byte[] byteRate = BitConverter.GetBytes(hz * channels * 2); // sampleRate * bytesPerSample*number of channels, here 44100*2*2
		fileStream.Write(byteRate, 0, 4);

		UInt16 blockAlign = (ushort) (channels * 2);
		fileStream.Write(BitConverter.GetBytes(blockAlign), 0, 2);

		UInt16 bps = 16;
		Byte[] bitsPerSample = BitConverter.GetBytes(bps);
		fileStream.Write(bitsPerSample, 0, 2);

		Byte[] datastring = System.Text.Encoding.UTF8.GetBytes("data");
		fileStream.Write(datastring, 0, 4);

		Byte[] subChunk2 = BitConverter.GetBytes(samples * channels * 2);
		fileStream.Write(subChunk2, 0, 4);

		//		fileStream.Close();
	}
}

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Unity_阿黄

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值