Save audio to a file [Solved]

Question
Hi, I need to record sound from micro
and save it to a file. for now I have
this:

void OnGUI()
{
    if (GUI.Button(new Rect(10,10,60,50),"Record"))
    { 
        audio.clip = Microphone.Start ( null, false, 3, 44100 ); 
    }
    if (GUI.Button(new Rect(10,70,60,50),"Play"))
    { 
        audio.Play();
    }
}

but it only save in buffer.

Unity documents have this:
EditorUtility.ExtractOggFileUnity - Scripting API: EditorUtility.ExtractOggFile
But I don’t understand how it works.

Could someone help me, please?

Answer

Add this C# script to your project: Unity3D: script to save an AudioClip as a .wav file. · GitHub (credits to Dark Table)

on other C# script call SavWav.Save("myfile", myAudioClip);

For example:

public class audioRec : MonoBehaviour
{
    AudioClip myAudioClip; 	
   void OnGUI()
   {
        if (GUI.Button(new Rect(10,10,60,50),"Record"))
	{ 
	    myAudioClip = Microphone.Start ( null, false, 10, 44100 );
	}
	if (GUI.Button(new Rect(10,70,60,50),"Save"))
	{
	    SavWav.Save("myfile", myAudioClip);
//	    audio.Play();
        }
   }
}

It saves the .Wav file to some strange folder. to change that, open SavWav.cs file and change line 41 (var filepath = Path.Combine(Application.persistentDataPath, filename);) to:

var filepath = Path.Combine(Application.dataPath, filename);

Hope it helps. Credits to people on this post: http://forum.unity3d.com/threads/119295-Writing-AudioListener.GetOutputData-to-wav-problem

Hi everyone,
I came from the future :slight_smile: I have an issue with save audio file. I can record and play audio, yet I cannot save the file. I get this error. Hope you help me.
NullReferenceException: Object reference not set to an instance of an object
Recorder.OnGUI () (at Assets/Recorder.cs:20)

// Following code recorder code.
using UnityEngine;
using System.Collections;

[RequireComponent(typeof(AudioSource))]
public class Recorder : MonoBehaviour
{
    public AudioClip myAudioClip;
    private SavWav savwav;

    void Start() { }
    void Update() { }

    void OnGUI()
    {
        if (GUI.Button(new Rect(10, 10, 60, 50), "Record")) {
            myAudioClip = Microphone.Start(null, false, 10, 44100);
        }

        if (GUI.Button(new Rect(10, 70, 60, 50), "Save")) {
20)       -----------     savwav.Save("myfile", myAudioClip); // error
        }

        if (GUI.Button(new Rect(10, 130, 60, 50), "Play")) {
            AudioSource audio = GetComponent<AudioSource>();
            audio.clip = myAudioClip;
            audio.Play();
        }
    }
}

solved the problem. I created gameobject and dragged recorder script into gameobject. But I forgot dragging SavWav script into game object. Thanks for interest.

i have done like you. But i cant dragging a SavWav script because there is no monobehaviour class involved. So i dont know how to save the file.

Could you briefly explain how did you done this?

@Alexander21 : since SavWav is a class and the save function is static, you can just call it as you do for unity native class, like that :

public void SaveMyFile()
{
    SavWav.Save("myfile", myAudioClip);
}

@danishsshaikh : you need a class to encode to mp3, like this one, but i’ve not tested it.

using System;
//using System.IO;
using UnityEngine;
  
public static class Statics
{
    public static byte[] ClipToWav(AudioClip clip)
    {
        float[] floats = new float[clip.samples * clip.channels];
        clip.GetData(floats, 0);
  
        byte[] bytes = new byte[floats.Length * 2];
  
        for (int ii = 0; ii < floats.Length; ii++)
        {
            short uint16 = (short)(floats[ii] * short.MaxValue);
            byte[] vs = BitConverter.GetBytes(uint16);
            bytes[ii * 2] = vs[0];
            bytes[ii * 2 + 1] = vs[1];
        }
  
        byte[] wav = new byte[44 + bytes.Length];
  
        byte[] header = {0x52, 0x49, 0x46, 0x46, 0x00, 0x00, 0x00, 0x00,
                         0x57, 0x41, 0x56, 0x45, 0x66, 0x6D, 0x74, 0x20,
                         0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
                         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                         0x04, 0x00, 0x10, 0x00, 0x64, 0x61, 0x74, 0x61 };
  
        Buffer.BlockCopy(header, 0, wav, 0, header.Length);
        Buffer.BlockCopy(BitConverter.GetBytes(36 + bytes.Length), 0, wav, 4, 4);
        Buffer.BlockCopy(BitConverter.GetBytes(clip.channels), 0, wav, 22, 2);
        Buffer.BlockCopy(BitConverter.GetBytes(clip.frequency), 0, wav, 24, 4);
        Buffer.BlockCopy(BitConverter.GetBytes(clip.frequency * clip.channels * 2), 0, wav, 28, 4);
        Buffer.BlockCopy(BitConverter.GetBytes(clip.channels * 2), 0, wav, 32, 2);
        Buffer.BlockCopy(BitConverter.GetBytes(bytes.Length), 0, wav, 40, 4);
        Buffer.BlockCopy(bytes, 0, wav, 44, bytes.Length);
  
        //File.WriteAllBytes(Application.dataPath + "/my.wav", wav);
        return wav;
    }
}

See on GitHub gist: Statics.cs · GitHub

You can save (and load) as compressed ogg file using this wrapper: GitHub - gindemit/unity-wrapper-vorbis: Unity3d Vorbis Ogg integration. Saving and loading AudioClip in Vorbis Ogg file format