Skip to content

Instantly share code, notes, and snippets.

@TakahiroMiyaura
Last active January 23, 2018 03:44
Show Gist options
  • Save TakahiroMiyaura/f4735335099f4d99ff439cc8acf5d2e0 to your computer and use it in GitHub Desktop.
Save TakahiroMiyaura/f4735335099f4d99ff439cc8acf5d2e0 to your computer and use it in GitHub Desktop.
HoloLensで多言語ベースの音声入力システムを作る際のTips - その1:マイクからの音声取得編 ref: https://qiita.com/miyaura/items/3a4a130175d272ea85e6
// Copyright(c) 2018 Takahiro Miyaura
// Released under the MIT license
// http://opensource.org/licenses/mit-license.php
private AudioSource _audioSource;
private string _microphone;
private void Start()
{
_microphone = Microphone.devices[0];
_audioSource = GetComponent<AudioSource>();
_audioSource.clip = Microphone.Start(_microphone, false, 999, AudioSettings.outputSampleRate);
_audioSource.loop = true;
while (!(Microphone.GetPosition(_microphone) > 0)) { }
_audioSource.Play();
_isInitialize = true;
}
// Copyright(c) 2018 Takahiro Miyaura
// Released under the MIT license
// http://opensource.org/licenses/mit-license.php
private bool _isInitialize;
private List<float> _samplingData;
private void OnAudioFilterRead(float[] buffer, int numChannels)
{
if (!_isInitialize) return;
lock (this)
{
_samplingData.AddRange(f);
}
}
// Copyright(c) 2018 Takahiro Miyaura
// Released under the MIT license
// http://opensource.org/licenses/mit-license.php
private void OnDestory()
{
_isInitialize = false;
_audioSource.Stop();
Microphone.End(_microphone);
}
// Copyright(c) 2018 Takahiro Miyaura
// Released under the MIT license
// http://opensource.org/licenses/mit-license.php
using System.Collections.Generic;
using HoloToolkit.Unity;
using HoloToolkit.Unity.InputModule;
using UnityEngine;
using UnityEngine.XR;
using UnityEngine.XR.WSA;
#if ENABLE_WINMD_SUPPORT
using System;
using System.Threading.Tasks;
using Windows.Storage.Streams;
using Windows.Media.Capture;
using Windows.Media.MediaProperties;
using System.Runtime.InteropServices.WindowsRuntime;
#endif
[RequireComponent(typeof(AudioSource))]
public class UWPMediaCapture : MonoBehaviour
{
#if ENABLE_WINMD_SUPPORT
private MediaCapture _capture;
private InMemoryRandomAccessStream _stream;
#endif
#if ENABLE_WINMD_SUPPORT
private async Task Start()
#else
private void Start()
#endif
{
if (!_isInitialize)
{
_isInitialize = true;
#if ENABLE_WINMD_SUPPORT
MediaCaptureInitializationSettings settings = new MediaCaptureInitializationSettings();
settings.StreamingCaptureMode = StreamingCaptureMode.Audio;
settings.MediaCategory = MediaCategory.Speech;
_capture = new MediaCapture();
_stream = new InMemoryRandomAccessStream();
await _capture.InitializeAsync(settings);
await _capture.StartRecordToStreamAsync(MediaEncodingProfile.CreateWav(AudioEncodingQuality.Medium),_stream);
#endif
}
}
// Copyright(c) 2018 Takahiro Miyaura
// Released under the MIT license
// http://opensource.org/licenses/mit-license.php
#if ENABLE_WINMD_SUPPORT
private async Task OnDestory()
#else
private void OnDestory()
#endif
{
_isInitialize = false;
#if ENABLE_WINMD_SUPPORT
await _capture.StopRecordAsync();
byte[] bytes=new byte[(uint)_stream.Size];
//バッファに読み込む
await _stream.ReadAsync(bytes.AsBuffer(),(uint)_stream.Size,InputStreamOptions.None);
#endif
}
// Copyright(c) 2018 Takahiro Miyaura
// Released under the MIT license
// http://opensource.org/licenses/mit-license.php
public MicStream.StreamCategory StreamType = MicStream.StreamCategory.HIGH_QUALITY_VOICE;
public int InputGain = 1;
private void Start()
{
MicStream.CheckForErrorOnCall(MicStream.MicInitializeCustomRate((int) StreamType, AudioSettings.outputSampleRate));
MicStream.CheckForErrorOnCall(MicStream.MicStartStream(KeepAllData, false));
MicStream.CheckForErrorOnCall(MicStream.MicSetGain(InputGain));
_isInitialize = true;
}
// Copyright(c) 2018 Takahiro Miyaura
// Released under the MIT license
// http://opensource.org/licenses/mit-license.php
private bool _isInitialize;
private List<float> _samplingData;
private void OnAudioFilterRead(float[] buffer, int numChannels)
{
if (!_isInitialize) return;
lock (this)
{
MicStream.CheckForErrorOnCall(MicStream.MicGetFrame(buffer, buffer.Length, numChannels));
_samplingData.AddRange(f);
}
}
// Copyright(c) 2018 Takahiro Miyaura
// Released under the MIT license
// http://opensource.org/licenses/mit-license.php
private void OnDestory()
{
_isInitialize = false;
MicStream.CheckForErrorOnCall(MicStream.MicStopStream());
}
private short FloatToInt16(float value)
{
var f = value * short.MaxValue;
if (f > short.MaxValue) f = short.MaxValue;
if (f < short.MinValue) f = short.MinValue;
}
// Copyright(c) 2018 Takahiro Miyaura
// Released under the MIT license
// http://opensource.org/licenses/mit-license.php
/// <summary>
/// Create a RIFF Wave Header
/// </summary>
/// <returns></returns>
public byte[] GetWaveHeader(short bitsPerSample, short channels, int sampleRate,
int sampingDataByteSize)
{
var extraSize = 0;
var headerSize = 46;
var blockAlign = (short) (channels * (bitsPerSample / 8));
var averageBytesPerSecond = sampleRate * blockAlign;
using (var stream = new MemoryStream())
{
var writer = new BinaryWriter(stream, Encoding.UTF8);
writer.Write(Encoding.UTF8.GetBytes("RIFF"));
writer.Write(headerSize + sampingDataByteSize - 8);
writer.Write(Encoding.UTF8.GetBytes("WAVE"));
writer.Write(Encoding.UTF8.GetBytes("fmt "));
writer.Write(18 + extraSize);
writer.Write((short) 1);
writer.Write(channels);
writer.Write(sampleRate);
writer.Write(averageBytesPerSecond);
writer.Write(blockAlign);
writer.Write(bitsPerSample);
writer.Write((short) extraSize);
writer.Write(Encoding.UTF8.GetBytes("data"));
writer.Write(sampingDataByteSize);
stream.Position = 0;
var buffer = new byte[stream.Length];
stream.Read(buffer, 0, buffer.Length);
return buffer;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment