User-free, time-long audio recording using the Microphone class in unity

Source: Internet
Author: User
Tags bool file size save file valid
User-free, time-long audio recording using the microphone class in Unity

Master Recording Script AudioRecord.cs
Maxcliplength: Maximum audio length, do not exceed the length of the actual recording, or set the maxcliplength infinite size can also

Using Unityengine;
Using Unityengine.ui;
Using System.Collections;
Using System;
Using System.IO;

Using System.Collections.Generic;
    public class Audiorecorder:monobehaviour {public enum audiorecordresultstate {Success,nomicrophone,tooshort}
    [serializefield]private int maxcliplength = 300;


    [hideininspector]public bool isrecording = false;
    Private AudioClip Recordedclip;
    private int _samplewindow = 128;

    private float Recordtimer = 0.0f;

        private void Update () {if (isrecording) {recordtimer + = Time.deltatime;
    }}///<summary>///Start recording///</summary> public audiorecordresultstate Startrecord ()


        {if (Microphone.devices.Length <= 0) return audiorecordresultstate.nomicrophone;
        Recordtimer = 0;

        Recordedclip = Microphone.start (null, FALSE, Maxcliplength, 44100);
        IsRecording = true;
Debug.Log ("Start record-------------");        return audiorecordresultstate.success; }///<summary>//Get microphone volume///</summary>//<returns></returns> public FL
        Oat Getlevelmax () {float Levelmax = 0;
        float[] Wavedata = new Float[_samplewindow]; int micposition = microphone.getposition (null)-(_samplewindow + 1);
        Null means the first microphone if (Micposition < 0) return 0;

        Recordedclip.getdata (Wavedata, micposition); Getting a peak on the last samples for (int i = 0; i < _samplewindow; i++) {float W
            Avepeak = wavedata[i] * Wavedata[i];
            if (Levelmax < wavepeak) {Levelmax = Wavepeak;
    }} return Levelmax; }///<summary>///Stop recording///</summary>//<returns> return audio save Path </returns> pub Lic audiorecordresultstate Stoprecord (out string filePath) {DEBUG.LOG ("Stop record---------------");
        Capture the current clip data isrecording = false;
            if (Recordtimer < 0.5f) {filePath = null;
        return audiorecordresultstate.tooshort;
        } int position = microphone.getposition (null);
        var sounddata = new float[recordedclip.samples * Recordedclip.channels];

        Recordedclip.getdata (sounddata, 0); Create shortened array for the data is used for recording var newdata = new Float[position * Recordedclip.


        Channels]; Copy The used samples to a new array for (int i = 0; i < newdata.length; i++) {Newdata[i
        ] = Sounddata[i];
        }//one does not simply shorten an audioclip,//So we do a new one with the appropriate length
                                        Recordedclip = Audioclip.create (recordedclip.name, Position, recordedclip.chAnnels, recordedclip.frequency, false);        Recordedclip.setdata (NewData, 0);

        Give it the data from the old clip//replace the old clip microphone.end (null);
        Save to disk string Recordedaudiopath;
        byte[] data = Wavutility.fromaudioclip (Recordedclip, out Recordedaudiopath, true);

        FilePath = Recordedaudiopath;
    return audiorecordresultstate.success;
 }
}

Tool class Script WavUtility.cs, the user handles the conversion between audio files and AudioClip
(source and how to use: HTTPS://GITHUB.COM/DEADLYFINGERS/UNITYWAV)

Using System.Text;
Using System.IO;
Using System;

Using Unityengine;
<summary>//WAV utility for recording and audio playback functions in Unity.
version:1.0 Alpha 1/////////-use "Toaudioclip" method for loading WAV file/bytes.
Loads. WAV (PCM uncompressed) files at 8,16,24 and all bits and converts data to Unity ' s audioclip.
-Use the "Fromaudioclip" method for saving WAV file/bytes.
Converts an AudioClip ' s float data to wav byte array at + bit. </summary>//<remarks>//For documentation and usage examples:https://github.com/deadlyfingers/ Unitywav//</remarks> public class Wavutility {//force Save as 16-bit. wav const int blocksize_16bit =

    2; <summary>//Load PCM format *.wav audio file (using Unity ' s Application Data path) and convert to AUDIOCLI P.//</summary>//<returns>the audioclip.</returns>//<param name= "FilePath" >loc Al file path to. wav File</param> public static AudioClip Toaudioclip (string filePath) {if (!filepath.startswith (applicat Ion.persistentdatapath) &&!filepath.startswith (Application.datapath)) {debug.logwarning ("Thi s only supports files that is stored using Unity ' s application Data path. \nto load bundled resources use ' resources.load (\ "Filename\") typeof (AudioClip) ' method.
            \nhttps://docs.unity3d.com/scriptreference/resources.load.html ");
        return null;
        } byte[] Filebytes = file.readallbytes (FilePath);
    Return Toaudioclip (filebytes, 0); } public static AudioClip Toaudioclip (byte[] filebytes, int offsetsamples = 0, String name = "wav") {//s
        Tring riff = Encoding.ASCII.GetString (filebytes, 0, 4);
        String wave = Encoding.ASCII.GetString (Filebytes, 8, 4);
        int subchunk1 = Bitconverter.toint32 (filebytes, 16);

        UInt16 Audioformat = bitconverter.touint16 (filebytes, 20); NB: Only uncompressed PCM wav files is supported.
        String formatcode = Formatcode (Audioformat); Debug.assertformat (Audioformat = = 1 | | audioformat = = 65534, "detected format code ' {0} ' {1}, but only PCM and waveformate

        Xtensable uncompressed formats is currently supported. ", Audioformat, Formatcode);
        UInt16 channels = Bitconverter.touint16 (Filebytes, 22);
        int samplerate = Bitconverter.toint32 (filebytes, 24);
        int byterate = Bitconverter.toint32 (filebytes, 28);
        UInt16 blockalign = bitconverter.touint16 (filebytes, 32);

        UInt16 bitDepth = bitconverter.touint16 (filebytes, 34);
        int headeroffset = 4 + Subchunk1 + 4;
        int subchunk2 = Bitconverter.toint32 (filebytes, Headeroffset); Debug.logformat ("riff={0} Wave={1} subchunk1={2} format={3} channels={4} samplerate={5} byterate={6} blockAlign={7} BITDEPTH={8} headeroffset={9} subchunk2={10} filesize={11} ", Riff, Wave, Subchunk1, Formatcode, channels, SamplErate, Byterate, Blockalign, BitDepth, Headeroffset, Subchunk2, filebytes.length);
        float[] data; Switch (bitDepth) {Case 8:data = Convert8bitbytearraytoaudioclipdata (filebytes, head
                Eroffset, SUBCHUNK2);
            Break
                Case 16:data = Convert16bitbytearraytoaudioclipdata (filebytes, Headeroffset, SUBCHUNK2);
            Break
                Case 24:data = Convert24bitbytearraytoaudioclipdata (filebytes, Headeroffset, SUBCHUNK2);
            Break
                Case 32:data = Convert32bitbytearraytoaudioclipdata (filebytes, Headeroffset, SUBCHUNK2);
            Break
        Default:throw New Exception (bitDepth + "bit depth is not supported."); } AudioClip AudioClip = audioclip.create (name, data.
        Length, (int) channels, samplerate, false);
        Audioclip.setdata (data, 0);
    return audioclip; } #region WAV File bytes to Unity audioclip conversion methods private static float[] Convert8bitbytearraytoaudioclipdata (byte[]
        source, int headeroffset, int datasize) {int wavsize = Bitconverter.toint32 (source, headeroffset);
        Headeroffset + = sizeof (int); Debug.assertformat (wavsize > 0 && wavsize = = DataSize, "Failed to get valid 8-bit wav Size: {0} from data bytes

        : {1} at offset: {2} ", Wavsize, DataSize, Headeroffset);

        float[] data = new Float[wavsize]; SByte maxValue = sbyte.

        MaxValue;
        int i = 0;
            while (I < wavsize) {Data[i] = (float) source[i]/maxValue;
        ++i;
    } return data;
        } private static float[] Convert16bitbytearraytoaudioclipdata (byte[] source, int headeroffset, int datasize) {
        int wavsize = Bitconverter.toint32 (source, headeroffset);
        Headeroffset + = sizeof (int); Debug.assertformat (wavsize > 0 && wavsize = = DataSize, "Failed to get valid 16-bit wav Size: {0} from the data bytes: {1} at offset: {2}", Wavsize, DataSize, Headeroffset); int x = sizeof (Int16);

        Block size = 2 int convertedsize = wavsize/x;

        float[] data = new Float[convertedsize];

        Int16 maxValue = Int16.maxvalue;
        int offset = 0;
        int i = 0;
            while (I < convertedsize) {offset = i * x + headeroffset;
            Data[i] = (float) bitconverter.toint16 (source, offset)/maxValue;
        ++i; } debug.assertformat (data. Length = = Convertedsize, "AudioClip. wav data is wrong size: {0} = = {1}", data.

        Length, convertedsize);
    return data;
        } private static float[] Convert24bitbytearraytoaudioclipdata (byte[] source, int headeroffset, int datasize) {
        int wavsize = Bitconverter.toint32 (source, headeroffset);
        Headeroffset + = sizeof (int); Debug.assertformat (wavsize > 0 && wavsize = = DataSize, "Failed to get valid 24-bit wav Size: {0} from the data bytes: {1} at offset: {2}", Wavsize, DataSize, Headeroffset); int x = 3;

        Block size = 3 int convertedsize = wavsize/x;

        int maxValue = Int32.MaxValue;

        float[] data = new Float[convertedsize]; byte[] block = new byte[sizeof (int)];
        Using a 4 byte block for copying 3 bytes, then copy bytes with 1 offset int offset = 0;
        int i = 0;
            while (I < convertedsize) {offset = i * x + headeroffset;
            Buffer.blockcopy (source, offset, block, 1, x);
            Data[i] = (float) bitconverter.toint32 (block, 0)/maxValue;
        ++i; } debug.assertformat (data. Length = = Convertedsize, "AudioClip. wav data is wrong size: {0} = = {1}", data.

        Length, convertedsize);
    return data;
        } private static float[] Convert32bitbytearraytoaudioclipdata (byte[] source, int headeroffset, int datasize) { int Wavsize= Bitconverter.toint32 (source, headeroffset);
        Headeroffset + = sizeof (int); Debug.assertformat (wavsize > 0 && wavsize = = DataSize, "Failed to get valid 32-bit wav Size: {0} from data byte

        S: {1} at offset: {2} ", Wavsize, DataSize, Headeroffset); int x = sizeof (float);

        Block size = 4 int convertedsize = wavsize/x;

        Int32 maxValue = Int32.MaxValue;

        float[] data = new Float[convertedsize];
        int offset = 0;
        int i = 0;
            while (I < convertedsize) {offset = i * x + headeroffset;
            Data[i] = (float) bitconverter.toint32 (source, offset)/maxValue;
        ++i; } debug.assertformat (data. Length = = Convertedsize, "AudioClip. wav data is wrong size: {0} = = {1}", data.

        Length, convertedsize);
    return data;
        } #endregion public static byte[] Fromaudioclip (AudioClip audioclip) {string file; Return Fromaudioclip (AudioClip, out file, false);  } public static byte[] Fromaudioclip (AudioClip audioclip, out string filepath, bool SaveAsFile = True, String dirname

        = "Recordings") {MemoryStream stream = new MemoryStream ();

        const int headersize = 44; Get bit depth UInt16 bitDepth = 16;

        BitDepth (AudioClip); Nb:only supports-bit//debug.assertformat (bitDepth = =, "Only converting-bit is currently supported.

        The audio clip data is {0} bit. ", bitDepth);
        Total File size = bytes of the header format and audioclip.samples * factor due to float to int16/sbyte conversion int fileSize = audioclip.samples * blocksize_16bit + headersize;
        BlockSize (bitDepth)//Chunk Descriptor (RIFF) Writefileheader (ref stream, fileSize);
        File header (FMT) Writefileformat (ref stream, Audioclip.channels, audioclip.frequency, bitDepth); Data chunks (data) Writefiledata (ref stream, AudioClip, bitDepth); byte[] bytes = stream.

        ToArray (); Validate Total Bytes Debug.assertformat (bytes. Length = = FileSize, "Unexpected audioclip to WAV format byte count: {0} = = {1}", bytes.

        Length, fileSize); Save file to persistant storage location if (saveasfile) {filepath = string. Format ("{0}/{1}/{2}.{
            3} ", Application.persistentdatapath, DirName, DateTime.UtcNow.ToString (" Yymmdd-hhmmss-fff ")," wav ");
            Directory.CreateDirectory (Path.getdirectoryname (filepath));
            File.writeallbytes (filepath, bytes);
        Debug.Log ("auto-saved. wav file:" + filepath);
        } else {filepath = null; } stream.

        Dispose ();
    return bytes;
    } #region write. wav file functions private static int Writefileheader (ref MemoryStream stream, int fileSize)
        {int count = 0;

        int total = 12; Riff Chunk ID byte[]Riff = Encoding.ASCII.GetBytes ("riff");

        Count + = Writebytestomemorystream (ref stream, riff, "ID"); Riff chunk size int chunkSize = fileSize-8; Total Size-8-The other-the the header count + = Writebytestomemorystream (ref stream, Bitconverte

        R.getbytes (ChunkSize), "chunk_size");
        byte[] wave = Encoding.ASCII.GetBytes ("wave");

        Count + = Writebytestomemorystream (ref stream, Wave, "FORMAT"); Validate Header Debug.assertformat (count = = Total, "Unexpected WAV descriptor byte count: {0} = = {1}", Count, T

        Otal);
    return count;
        } private static int Writefileformat (ref MemoryStream stream, int channels, int samplerate, UInt16 bitDepth) {
        int count = 0;

        int total = 24;
        byte[] id = Encoding.ASCII.GetBytes ("FMT");

        Count + = Writebytestomemorystream (ref stream, ID, "fmt_id"); int subchunk1size = 16; 24-8 count + = Writebytestomemorystream (Ref stream, Bitconverter.getbytes (subchunk1size), "subchunk_size");
        UInt16 Audioformat = 1;

        Count + = Writebytestomemorystream (ref stream, Bitconverter.getbytes (Audioformat), "Audio_format");
        UInt16 numchannels = convert.touint16 (Channels);

        Count + = Writebytestomemorystream (ref stream, Bitconverter.getbytes (numchannels), "CHANNELS");

        Count + = Writebytestomemorystream (ref stream, Bitconverter.getbytes (samplerate), "sample_rate");
        int byterate = samplerate * Channels * bytespersample (bitDepth);

        Count + = Writebytestomemorystream (ref stream, Bitconverter.getbytes (byterate), "byte_rate");
        UInt16 blockalign = convert.touint16 (Channels * Bytespersample (bitDepth));

        Count + = Writebytestomemorystream (ref stream, Bitconverter.getbytes (blockalign), "block_align"); Count + = Writebytestomemorystream (ref stream, Bitconverter.getbytes (BITD

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.