AR Design
UBC EML collab with UBC SALA - visualizing IoT data in AR
MicStreamDemo.cs
Go to the documentation of this file.
1 // Copyright (c) Microsoft Corporation. All rights reserved.
2 // Licensed under the MIT License. See LICENSE in the project root for license information.
3 
4 using UnityEngine;
5 
6 namespace HoloToolkit.Unity.InputModule.Tests
7 {
8  [RequireComponent(typeof(AudioSource))]
9  public class MicStreamDemo : MonoBehaviour
10  {
14  public MicStream.StreamCategory StreamType = MicStream.StreamCategory.HIGH_QUALITY_VOICE;
15 
20  public float InputGain = 1;
21 
27  public bool KeepAllData;
28 
32  public bool AutomaticallyStartStream = true;
33 
37  public bool PlaybackMicrophoneAudioSource = true;
38 
42  public string SaveFileName = "MicrophoneTest.wav";
43 
47  private float averageAmplitude;
48 
52  [SerializeField]
53  private float minObjectScale = .3f;
54 
55  private bool isRunning;
56 
57  public bool IsRunning
58  {
59  get { return isRunning; }
60  private set
61  {
62  isRunning = value;
63  CheckForErrorOnCall(isRunning ? MicStream.MicPause() : MicStream.MicResume());
64  }
65  }
66 
67  #region Unity Methods
68 
69  private void OnAudioFilterRead(float[] buffer, int numChannels)
70  {
71  // this is where we call into the DLL and let it fill our audio buffer for us
72  CheckForErrorOnCall(MicStream.MicGetFrame(buffer, buffer.Length, numChannels));
73 
74  float sumOfValues = 0;
75 
76  // figure out the average amplitude from this new data
77  for (int i = 0; i < buffer.Length; i++)
78  {
79  if (float.IsNaN(buffer[i]))
80  {
81  buffer[i] = 0;
82  }
83 
84  buffer[i] = Mathf.Clamp(buffer[i], -1f, 1f);
85  sumOfValues += Mathf.Clamp01(Mathf.Abs(buffer[i]));
86  }
87  averageAmplitude = sumOfValues / buffer.Length;
88  }
89 
90  private void OnEnable()
91  {
92  IsRunning = true;
93  }
94 
95  private void Awake()
96  {
97  CheckForErrorOnCall(MicStream.MicInitializeCustomRate((int)StreamType, AudioSettings.outputSampleRate));
98  CheckForErrorOnCall(MicStream.MicSetGain(InputGain));
99 
100  if (!PlaybackMicrophoneAudioSource)
101  {
102  gameObject.GetComponent<AudioSource>().volume = 0; // can set to zero to mute mic monitoring
103  }
104 
105  if (AutomaticallyStartStream)
106  {
107  CheckForErrorOnCall(MicStream.MicStartStream(KeepAllData, false));
108  }
109 
110  print("MicStream selector demo");
111  print("press Q to start stream to audio source, W will stop that stream");
112  print("press A to start a recording and S to stop that recording and save it to a wav file.");
113  print("Since this all goes through the AudioSource, you can mute the mic while using it there, or do anything else you would do with an AudioSource");
114  print("In this demo, we start the stream automatically, and then change the size of the GameObject based on microphone signal amplitude");
115  isRunning = true;
116  }
117 
118  private void Update()
119  {
120  CheckForErrorOnCall(MicStream.MicSetGain(InputGain));
121 
122  if (Input.GetKeyDown(KeyCode.Q))
123  {
124  CheckForErrorOnCall(MicStream.MicStartStream(KeepAllData, false));
125  }
126  else if (Input.GetKeyDown(KeyCode.W))
127  {
128  CheckForErrorOnCall(MicStream.MicStopStream());
129  }
130  else if (Input.GetKeyDown(KeyCode.A))
131  {
132  CheckForErrorOnCall(MicStream.MicStartRecording(SaveFileName, false));
133  }
134  else if (Input.GetKeyDown(KeyCode.S))
135  {
136  string outputPath = MicStream.MicStopRecording();
137  Debug.Log("Saved microphone audio to " + outputPath);
138  CheckForErrorOnCall(MicStream.MicStopStream());
139  }
140 
141  gameObject.transform.localScale = new Vector3(minObjectScale + averageAmplitude, minObjectScale + averageAmplitude, minObjectScale + averageAmplitude);
142  }
143 
144  private void OnApplicationPause(bool pause)
145  {
146  IsRunning = !pause;
147  }
148 
149  private void OnDisable()
150  {
151  IsRunning = false;
152  }
153 
154  private void OnDestroy()
155  {
156  CheckForErrorOnCall(MicStream.MicDestroy());
157  }
158 
159 #if !UNITY_EDITOR
160  private void OnApplicationFocus(bool focused)
161  {
162  IsRunning = focused;
163  }
164 #endif
165  #endregion
166 
167  private static void CheckForErrorOnCall(int returnCode)
168  {
169  MicStream.CheckForErrorOnCall(returnCode);
170  }
171 
172  public void Enable()
173  {
174  IsRunning = true;
175  }
176 
177  public void Disable()
178  {
179  IsRunning = false;
180  }
181  }
182 }
static int MicStopStream()
Shuts down the connection to the microphone. Data will not longer be received from the microphone...
static int MicResume()
Unpauses streaming of microphone data to MicGetFrame (and/or file specified with MicStartRecording) ...
static void MicStopRecording(StringBuilder sb)
Finishes writing the file recording started with MicStartRecording.
static int MicSetGain(float g)
Sets amplification factor for microphone samples returned by MicGetFrame (and/or file specified with ...
static int MicPause()
Pauses streaming of microphone data to MicGetFrame (and/or file specified with MicStartRecording) ...
static int MicGetFrame(float[] buffer, int length, int numchannels)
Read from the microphone buffer. Usually called once per frame.
static bool CheckForErrorOnCall(int returnCode)
Prints useful error/warning messages based on error codes returned from the functions in this class ...
Definition: MicStream.cs:161
static int MicStartStream(bool keepData, bool previewOnDevice, LiveMicCallback micsignal)
Call this to start receiving data from a microphone. Then, each frame, call MicGetFrame.
static int MicInitializeCustomRate(int category, int samplerate)
Called before calling MicStartStream or MicstartRecording to initialize microphone ...
bool KeepAllData
if keepAllData==false, you&#39;ll always get the newest data no matter how long the program hangs for any...
static int MicStartRecording(string filename, bool previewOnDevice)
Begins recording microphone data to the specified file.
static int MicDestroy()
Cleans up data associated with microphone recording. Counterpart to MicInitialize* ...