1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【Unity×C#】マイクからオーディオを取得しファイルに保存する

Posted at

概要

Unity×C#の環境でマイクからオーディオを取得しWAVファイルとして保存するデモです。

開発環境

Windows 10
Unity 2019.4.31f1
Api Compatibility Level .NET Standard 2.0

実装

詳細はスクリプト中にコメントで記載しています。

DemoAudioRecorder.cs

using System.Collections;
using System.Linq;
using UnityEngine;

public class DemoAudioRecorder : MonoBehaviour
{
    // Start is called before the first frame update
    private string microphone;
    private AudioClip microphoneInput;
    private const int RECORD_LENGTH_SEC = 10;
    private const int SAMPLE_RATE = 41100;

    void Start()
    {
        // 利用可能なマイクを検出
        microphone = Microphone.devices.FirstOrDefault();
        Debug.Log("microphone: " + microphone);
        if (microphone == null)
        {
            Debug.LogError("No microphone found");
            return;
        }

        // 第二引数をtrueにすると循環バッファとしてループ保存
        microphoneInput = Microphone.Start(microphone, false, RECORD_LENGTH_SEC, SAMPLE_RATE);
        Debug.Log("録音を開始します。何か話してください。");

        // Coroutine(非同期処理)でWaitAndExecuteメソッドを実行
        StartCoroutine(WaitAndExecute());
    }

    // Update is called once per frame
    void Update() { }

    /// <summary>
    /// 10秒間待機して、録音結果をWAVファイルに保存
    /// Unity自体の処理を止めないようにコルーチンを利用して非同期処理にしています。
    /// </summary>
    IEnumerator WaitAndExecute()
    {
        // 10秒間待機
        yield return new WaitForSeconds(10);
        Debug.Log("録音を終了し、WAVファイルに保存します。");

        // 保存先ファイルの設定
        var filePath = string.Format("{0}/{1}/{2}", Application.persistentDataPath, "recordings", "recordedAudio.wav");
        Debug.Log("filePath: " + filePath);

        // AudioClipからWAVファイルを作成
        SaveWavFile(filePath, microphoneInput);
    }

    /// <summary>
    /// AudioClipからWAVファイルを作成
    /// WavUtilityには以下のコードを利用。ただし、FromAudioClipメソッドの一部を修正
    /// https://github.com/deadlyfingers/UnityWav/tree/master
    /// </summary>
    private void SaveWavFile(string filepath, AudioClip clip)
    {
        // AudioClipからWAVファイルを作成
        byte[] wavBytes = WavUtility.FromAudioClip(clip, filepath, true);
    }
}

WavUtility.cs(微修正したFromAudioClipメソッド部分のみ)

WAVファイルとして保存するスクリプトにはWavUtilityを一部書き換えて利用しました。

注意:以下のスクリプトは一部分のみです。これだけでは機能しません。

    // すべてコメントアウト
    // public static byte[] FromAudioClip(AudioClip audioClip)
    // {
    // 	string file;
    // 	return FromAudioClip(audioClip, out file, false);
    // }

    // filepathがoutである必要はないので、outを削除
    public static byte[] FromAudioClip(AudioClip audioClip, 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 16 bit
        //Debug.AssertFormat (bitDepth == 16, "Only converting 16 bit is currently supported. The audio clip data is {0} bit.", bitDepth);

        // total file size = 44 bytes for 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は引数として読み込むので、コメントアウト
            // 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;
    }

利用方法

  • Unityを起動します。
  • Cube等のGameObjectを用意します。
  • 用意したGameObjectにDemoAudioRecorder.csをアタッチします。
  • Console画面を開き、Playモードに入ります。
  • Consoleに表示される指示に従って、マイクに話しかけます。
  • 録音が完了したら、filePathに表示されるフォルダを開き、recordedAudio.wavを確認します。
  • きちんと録音できていたら、成功です。

参考資料

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?