Save audio to a file [Solved]
Asked Answered
G

6

0

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?

Gmt answered 17/10, 2023 at 8:13 Comment(5)

It's me again :P I found a solution on this post: http://forum.unity3d.com/threads/119295-Writing-AudioListener.GetOutputData-to-wav-problem?p=859871&viewfull=1#post859871 I'm using the C# example and it's working very good.

Gmt

Please post your own answer as a proper answer and mark it as correct, so other can see it that it is solved. Welcome to Unity Answers.

Rochellerochemont

and how i do that? i've written the answer on the question and put [solved] in title

Gmt

Instead of pressing "add new comment" fill the text box bellow and press "Post your answer". Once your answer is posted you can mark it as correct. Then this question becomes "green" and gets removed from "Unanswered" list.

Rochellerochemont

This is awesome! Does it work for mobile as well? I assume it has a different folder structure for saving files.

Toodleoo
G
0

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

Gmt answered 17/10, 2023 at 8:17 Comment(5)

this is brilliant! this works perfect! is there away to save the files incrementally? ie myfile001, myfile002... I can get through javascript, but I have only a slight idea about c#

Puddle

add a variable and increment it every time you record and save the file with "filename" + variable

Gmt

I got it by changing the original SavWav.cs file in line 40 to: filename += System.DateTime.Now.ToString("MM-dd-yy_hh-mm-ss") +".wav";

Puddle

The output from that script is, strangely, lossy. To fix that I replaced the int rescaleFactor = 32767; //to convert float to Int16 with float rescaleFactor = 32767; And now it sounds lossless!

Entrenchment

How does one load in the saved audio clip back into unity? Thanks

Yeah
A
0

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();
        }
    }
}
Aeriela answered 6/6, 2023 at 2:12 Comment(2)

Hi I came from the past. You declared private SavWav savwav; and do nothing to it and call that of course it is currently null. The class is static, and all of the methods are static. You are not supposed to instantiate an instance of that class. Use the class name to call into the method directly. Also I thought your code would not compile because .Save is static you probably can't call from an instance.

Entrenchment

make the class of "SaveLoadWav" and all its functions static.

Hamil
S
0

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?

Summitry answered 7/2, 2020 at 11:20 Comment(0)
G
0

@Summitry : 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);
}

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

Gober answered 17/10, 2023 at 8:14 Comment(0)
S
0
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

Salesperson answered 17/10, 2023 at 8:15 Comment(0)
B
0

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

Bargain answered 6/5, 2023 at 12:18 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.