Microphone input's maximum float number is 1. How to make it bigger and change it from 1? Unity C#
up vote
-1
down vote
favorite
I have a code that takes a microphone input(when pressing "T)" and returns it as a float number (one final float number). However, when I yell or blow into microphone the maximum float it prints is 1 and no matter how I yell or say quietly after it printed 1, it keeps printing 1 only. How to change it to a bigger number. Let's say if I yell it would return a bigger number than if I just say quietly.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Linq;
public class MicInputs : MonoBehaviour
{
public enum micActivation
{
HoldToSpeak,
}
public micActivation micControl;
private float sample_max = 0.0f;
public static float MicLoudFloat;
public List<float> recorded_values = new List<float>();
private string theMicroDevice;
AudioClip recordOfClips;
//microphone initialization
void MicroInitialization()
{
if (theMicroDevice == null) theMicroDevice = Microphone.devices[0];
recordOfClips = Microphone.Start(theMicroDevice, true, 999, 44100);
}
void StopMicrophone()
{
Microphone.End(theMicroDevice);
Maximum_Level(); // Collect the final sample
MicLoudFloat = sample_max;
print(MicLoudFloat);
}
void Awake()
{
recordOfClips = AudioClip.Create("nameOfClip", 128, 2, 1000, true);
}
//AudioClip clip = myRecordedOrOwnClip;
//reate(string name, int lengthSamples, int channels, int frequency,
bool stream,
//_sampleWindow = clip.samples;
//AudioClip _clipRecord = new AudioClip();
//AudioClip _clipRecord = AudioClip.Create("nameOfClip", 128, 2, 1,
true);
int samplesWindows = 128;
//=========THIS IS THE START OF THE METHOD========
// get data from microphone into audioclip
float Maximum_Level()
{
float waveData = new float[samplesWindows];
int micPosition = Microphone.GetPosition(null) - (samplesWindows
+1); // null means the first microphone
if (micPosition < 0) return 0;
recordOfClips.GetData(waveData, micPosition);
// Getting a peak on the last 128 samples
for (int i = 0; i < samplesWindows; i++)
{
float wavePeak = waveData[i] * waveData[i];
if (wavePeak > sample_max)
{
sample_max = wavePeak;
}
}
return sample_max;
//float maximum_level = 0;
//float waveData = new float[samplesWindows];
//int micPosition = Microphone.GetPosition(null) - (samplesWindows
+ 1); // null means the first microphone
//if (micPosition < 0) return 0;
//recordOfClips.GetData(waveData, micPosition);
//// Getting a peak on the last 128 samples
//for (int i = 0; i < samplesWindows; i++)
//{
// float wavePeak = waveData[i] * waveData[i];
// if (maximum_level < wavePeak)
// {
// maximum_level = wavePeak;
// recorded_values.Add(maximum_level);
// }
//}
//float max = recorded_values.Max();
////print(max);
//return max;
//print(maximum_level);
//return maximum_level;
}
//=========THIS IS THE END OF THE METHOD========
void Update()
{
if (micControl == micActivation.HoldToSpeak)
{
//if (Microphone.IsRecording(theMicroDevice) &&
Input.GetKey(KeyCode.T) == false)
//StopMicrophone();
//
if (Input.GetKeyDown(KeyCode.T)){ //Push to talk
MicroInitialization();
}
//
if (Input.GetKeyUp(KeyCode.T)){
StopMicrophone();
}
}
Maximum_Level();
// levelMax equals to the highest normalized value power 2, a small
number because < 1
// pass the value to a static var so we can access it from anywhere
//print(MicLoudFloat);
}
//bool isItInitialized;
//// start mic when scene starts
//void OnEnable()
//{
// MicroInitialization();
// isItInitialized = true;
//}
////stop mic when loading a new level or quit application
//void OnDisable()
//{
// StopMicrophone();
//}
//void OnDestroy()
//{
// StopMicrophone();
//}
// detects if the mic gets started & stopped when application gets
focused
//void OnApplicationFocus(bool focus)
//{
// if (focus)
// {
// //Debug.Log("Focus");
// if (!isItInitialized)
// {
// //Debug.Log("Init Mic");
// MicroInitialization();
// isItInitialized = true;
// }
// }
// if (!focus)
// {
// //Debug.Log("Pause");
// StopMicrophone();
// //Debug.Log("Stop Mic");
// isItInitialized = false;
// }
//}
}
c# unity3d
|
show 3 more comments
up vote
-1
down vote
favorite
I have a code that takes a microphone input(when pressing "T)" and returns it as a float number (one final float number). However, when I yell or blow into microphone the maximum float it prints is 1 and no matter how I yell or say quietly after it printed 1, it keeps printing 1 only. How to change it to a bigger number. Let's say if I yell it would return a bigger number than if I just say quietly.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Linq;
public class MicInputs : MonoBehaviour
{
public enum micActivation
{
HoldToSpeak,
}
public micActivation micControl;
private float sample_max = 0.0f;
public static float MicLoudFloat;
public List<float> recorded_values = new List<float>();
private string theMicroDevice;
AudioClip recordOfClips;
//microphone initialization
void MicroInitialization()
{
if (theMicroDevice == null) theMicroDevice = Microphone.devices[0];
recordOfClips = Microphone.Start(theMicroDevice, true, 999, 44100);
}
void StopMicrophone()
{
Microphone.End(theMicroDevice);
Maximum_Level(); // Collect the final sample
MicLoudFloat = sample_max;
print(MicLoudFloat);
}
void Awake()
{
recordOfClips = AudioClip.Create("nameOfClip", 128, 2, 1000, true);
}
//AudioClip clip = myRecordedOrOwnClip;
//reate(string name, int lengthSamples, int channels, int frequency,
bool stream,
//_sampleWindow = clip.samples;
//AudioClip _clipRecord = new AudioClip();
//AudioClip _clipRecord = AudioClip.Create("nameOfClip", 128, 2, 1,
true);
int samplesWindows = 128;
//=========THIS IS THE START OF THE METHOD========
// get data from microphone into audioclip
float Maximum_Level()
{
float waveData = new float[samplesWindows];
int micPosition = Microphone.GetPosition(null) - (samplesWindows
+1); // null means the first microphone
if (micPosition < 0) return 0;
recordOfClips.GetData(waveData, micPosition);
// Getting a peak on the last 128 samples
for (int i = 0; i < samplesWindows; i++)
{
float wavePeak = waveData[i] * waveData[i];
if (wavePeak > sample_max)
{
sample_max = wavePeak;
}
}
return sample_max;
//float maximum_level = 0;
//float waveData = new float[samplesWindows];
//int micPosition = Microphone.GetPosition(null) - (samplesWindows
+ 1); // null means the first microphone
//if (micPosition < 0) return 0;
//recordOfClips.GetData(waveData, micPosition);
//// Getting a peak on the last 128 samples
//for (int i = 0; i < samplesWindows; i++)
//{
// float wavePeak = waveData[i] * waveData[i];
// if (maximum_level < wavePeak)
// {
// maximum_level = wavePeak;
// recorded_values.Add(maximum_level);
// }
//}
//float max = recorded_values.Max();
////print(max);
//return max;
//print(maximum_level);
//return maximum_level;
}
//=========THIS IS THE END OF THE METHOD========
void Update()
{
if (micControl == micActivation.HoldToSpeak)
{
//if (Microphone.IsRecording(theMicroDevice) &&
Input.GetKey(KeyCode.T) == false)
//StopMicrophone();
//
if (Input.GetKeyDown(KeyCode.T)){ //Push to talk
MicroInitialization();
}
//
if (Input.GetKeyUp(KeyCode.T)){
StopMicrophone();
}
}
Maximum_Level();
// levelMax equals to the highest normalized value power 2, a small
number because < 1
// pass the value to a static var so we can access it from anywhere
//print(MicLoudFloat);
}
//bool isItInitialized;
//// start mic when scene starts
//void OnEnable()
//{
// MicroInitialization();
// isItInitialized = true;
//}
////stop mic when loading a new level or quit application
//void OnDisable()
//{
// StopMicrophone();
//}
//void OnDestroy()
//{
// StopMicrophone();
//}
// detects if the mic gets started & stopped when application gets
focused
//void OnApplicationFocus(bool focus)
//{
// if (focus)
// {
// //Debug.Log("Focus");
// if (!isItInitialized)
// {
// //Debug.Log("Init Mic");
// MicroInitialization();
// isItInitialized = true;
// }
// }
// if (!focus)
// {
// //Debug.Log("Pause");
// StopMicrophone();
// //Debug.Log("Stop Mic");
// isItInitialized = false;
// }
//}
}
c# unity3d
4
The actuall sensor only returns values from 0 to 1. Either make the checks at partial numbers. Or just multiply the input by a number. Something like 100.
– Christopher
Nov 10 at 21:50
In StopMicrophone() I multiplied sample_max by 100. It simply give me the number just multiplied by 100. Which means instead of 1 it gives 100.
– optimus
Nov 10 at 22:16
If the sensor returns 0 to 1 as float, and you want "half of full volume", jsut compare it to be >= 0.5 You got float values. Use them.
– Christopher
Nov 10 at 22:34
Since you say that it does return a bigger number when you yell than when you talk quietly, it's not clear what you're asking.
– Eric Lippert
Nov 11 at 0:29
If the problem is that your microphone has a small dynamic range, that's not a problem you can solve in software. Buy a better microphone.
– Eric Lippert
Nov 11 at 0:30
|
show 3 more comments
up vote
-1
down vote
favorite
up vote
-1
down vote
favorite
I have a code that takes a microphone input(when pressing "T)" and returns it as a float number (one final float number). However, when I yell or blow into microphone the maximum float it prints is 1 and no matter how I yell or say quietly after it printed 1, it keeps printing 1 only. How to change it to a bigger number. Let's say if I yell it would return a bigger number than if I just say quietly.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Linq;
public class MicInputs : MonoBehaviour
{
public enum micActivation
{
HoldToSpeak,
}
public micActivation micControl;
private float sample_max = 0.0f;
public static float MicLoudFloat;
public List<float> recorded_values = new List<float>();
private string theMicroDevice;
AudioClip recordOfClips;
//microphone initialization
void MicroInitialization()
{
if (theMicroDevice == null) theMicroDevice = Microphone.devices[0];
recordOfClips = Microphone.Start(theMicroDevice, true, 999, 44100);
}
void StopMicrophone()
{
Microphone.End(theMicroDevice);
Maximum_Level(); // Collect the final sample
MicLoudFloat = sample_max;
print(MicLoudFloat);
}
void Awake()
{
recordOfClips = AudioClip.Create("nameOfClip", 128, 2, 1000, true);
}
//AudioClip clip = myRecordedOrOwnClip;
//reate(string name, int lengthSamples, int channels, int frequency,
bool stream,
//_sampleWindow = clip.samples;
//AudioClip _clipRecord = new AudioClip();
//AudioClip _clipRecord = AudioClip.Create("nameOfClip", 128, 2, 1,
true);
int samplesWindows = 128;
//=========THIS IS THE START OF THE METHOD========
// get data from microphone into audioclip
float Maximum_Level()
{
float waveData = new float[samplesWindows];
int micPosition = Microphone.GetPosition(null) - (samplesWindows
+1); // null means the first microphone
if (micPosition < 0) return 0;
recordOfClips.GetData(waveData, micPosition);
// Getting a peak on the last 128 samples
for (int i = 0; i < samplesWindows; i++)
{
float wavePeak = waveData[i] * waveData[i];
if (wavePeak > sample_max)
{
sample_max = wavePeak;
}
}
return sample_max;
//float maximum_level = 0;
//float waveData = new float[samplesWindows];
//int micPosition = Microphone.GetPosition(null) - (samplesWindows
+ 1); // null means the first microphone
//if (micPosition < 0) return 0;
//recordOfClips.GetData(waveData, micPosition);
//// Getting a peak on the last 128 samples
//for (int i = 0; i < samplesWindows; i++)
//{
// float wavePeak = waveData[i] * waveData[i];
// if (maximum_level < wavePeak)
// {
// maximum_level = wavePeak;
// recorded_values.Add(maximum_level);
// }
//}
//float max = recorded_values.Max();
////print(max);
//return max;
//print(maximum_level);
//return maximum_level;
}
//=========THIS IS THE END OF THE METHOD========
void Update()
{
if (micControl == micActivation.HoldToSpeak)
{
//if (Microphone.IsRecording(theMicroDevice) &&
Input.GetKey(KeyCode.T) == false)
//StopMicrophone();
//
if (Input.GetKeyDown(KeyCode.T)){ //Push to talk
MicroInitialization();
}
//
if (Input.GetKeyUp(KeyCode.T)){
StopMicrophone();
}
}
Maximum_Level();
// levelMax equals to the highest normalized value power 2, a small
number because < 1
// pass the value to a static var so we can access it from anywhere
//print(MicLoudFloat);
}
//bool isItInitialized;
//// start mic when scene starts
//void OnEnable()
//{
// MicroInitialization();
// isItInitialized = true;
//}
////stop mic when loading a new level or quit application
//void OnDisable()
//{
// StopMicrophone();
//}
//void OnDestroy()
//{
// StopMicrophone();
//}
// detects if the mic gets started & stopped when application gets
focused
//void OnApplicationFocus(bool focus)
//{
// if (focus)
// {
// //Debug.Log("Focus");
// if (!isItInitialized)
// {
// //Debug.Log("Init Mic");
// MicroInitialization();
// isItInitialized = true;
// }
// }
// if (!focus)
// {
// //Debug.Log("Pause");
// StopMicrophone();
// //Debug.Log("Stop Mic");
// isItInitialized = false;
// }
//}
}
c# unity3d
I have a code that takes a microphone input(when pressing "T)" and returns it as a float number (one final float number). However, when I yell or blow into microphone the maximum float it prints is 1 and no matter how I yell or say quietly after it printed 1, it keeps printing 1 only. How to change it to a bigger number. Let's say if I yell it would return a bigger number than if I just say quietly.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Linq;
public class MicInputs : MonoBehaviour
{
public enum micActivation
{
HoldToSpeak,
}
public micActivation micControl;
private float sample_max = 0.0f;
public static float MicLoudFloat;
public List<float> recorded_values = new List<float>();
private string theMicroDevice;
AudioClip recordOfClips;
//microphone initialization
void MicroInitialization()
{
if (theMicroDevice == null) theMicroDevice = Microphone.devices[0];
recordOfClips = Microphone.Start(theMicroDevice, true, 999, 44100);
}
void StopMicrophone()
{
Microphone.End(theMicroDevice);
Maximum_Level(); // Collect the final sample
MicLoudFloat = sample_max;
print(MicLoudFloat);
}
void Awake()
{
recordOfClips = AudioClip.Create("nameOfClip", 128, 2, 1000, true);
}
//AudioClip clip = myRecordedOrOwnClip;
//reate(string name, int lengthSamples, int channels, int frequency,
bool stream,
//_sampleWindow = clip.samples;
//AudioClip _clipRecord = new AudioClip();
//AudioClip _clipRecord = AudioClip.Create("nameOfClip", 128, 2, 1,
true);
int samplesWindows = 128;
//=========THIS IS THE START OF THE METHOD========
// get data from microphone into audioclip
float Maximum_Level()
{
float waveData = new float[samplesWindows];
int micPosition = Microphone.GetPosition(null) - (samplesWindows
+1); // null means the first microphone
if (micPosition < 0) return 0;
recordOfClips.GetData(waveData, micPosition);
// Getting a peak on the last 128 samples
for (int i = 0; i < samplesWindows; i++)
{
float wavePeak = waveData[i] * waveData[i];
if (wavePeak > sample_max)
{
sample_max = wavePeak;
}
}
return sample_max;
//float maximum_level = 0;
//float waveData = new float[samplesWindows];
//int micPosition = Microphone.GetPosition(null) - (samplesWindows
+ 1); // null means the first microphone
//if (micPosition < 0) return 0;
//recordOfClips.GetData(waveData, micPosition);
//// Getting a peak on the last 128 samples
//for (int i = 0; i < samplesWindows; i++)
//{
// float wavePeak = waveData[i] * waveData[i];
// if (maximum_level < wavePeak)
// {
// maximum_level = wavePeak;
// recorded_values.Add(maximum_level);
// }
//}
//float max = recorded_values.Max();
////print(max);
//return max;
//print(maximum_level);
//return maximum_level;
}
//=========THIS IS THE END OF THE METHOD========
void Update()
{
if (micControl == micActivation.HoldToSpeak)
{
//if (Microphone.IsRecording(theMicroDevice) &&
Input.GetKey(KeyCode.T) == false)
//StopMicrophone();
//
if (Input.GetKeyDown(KeyCode.T)){ //Push to talk
MicroInitialization();
}
//
if (Input.GetKeyUp(KeyCode.T)){
StopMicrophone();
}
}
Maximum_Level();
// levelMax equals to the highest normalized value power 2, a small
number because < 1
// pass the value to a static var so we can access it from anywhere
//print(MicLoudFloat);
}
//bool isItInitialized;
//// start mic when scene starts
//void OnEnable()
//{
// MicroInitialization();
// isItInitialized = true;
//}
////stop mic when loading a new level or quit application
//void OnDisable()
//{
// StopMicrophone();
//}
//void OnDestroy()
//{
// StopMicrophone();
//}
// detects if the mic gets started & stopped when application gets
focused
//void OnApplicationFocus(bool focus)
//{
// if (focus)
// {
// //Debug.Log("Focus");
// if (!isItInitialized)
// {
// //Debug.Log("Init Mic");
// MicroInitialization();
// isItInitialized = true;
// }
// }
// if (!focus)
// {
// //Debug.Log("Pause");
// StopMicrophone();
// //Debug.Log("Stop Mic");
// isItInitialized = false;
// }
//}
}
c# unity3d
c# unity3d
edited Nov 11 at 18:46
asked Nov 10 at 21:45
optimus
15
15
4
The actuall sensor only returns values from 0 to 1. Either make the checks at partial numbers. Or just multiply the input by a number. Something like 100.
– Christopher
Nov 10 at 21:50
In StopMicrophone() I multiplied sample_max by 100. It simply give me the number just multiplied by 100. Which means instead of 1 it gives 100.
– optimus
Nov 10 at 22:16
If the sensor returns 0 to 1 as float, and you want "half of full volume", jsut compare it to be >= 0.5 You got float values. Use them.
– Christopher
Nov 10 at 22:34
Since you say that it does return a bigger number when you yell than when you talk quietly, it's not clear what you're asking.
– Eric Lippert
Nov 11 at 0:29
If the problem is that your microphone has a small dynamic range, that's not a problem you can solve in software. Buy a better microphone.
– Eric Lippert
Nov 11 at 0:30
|
show 3 more comments
4
The actuall sensor only returns values from 0 to 1. Either make the checks at partial numbers. Or just multiply the input by a number. Something like 100.
– Christopher
Nov 10 at 21:50
In StopMicrophone() I multiplied sample_max by 100. It simply give me the number just multiplied by 100. Which means instead of 1 it gives 100.
– optimus
Nov 10 at 22:16
If the sensor returns 0 to 1 as float, and you want "half of full volume", jsut compare it to be >= 0.5 You got float values. Use them.
– Christopher
Nov 10 at 22:34
Since you say that it does return a bigger number when you yell than when you talk quietly, it's not clear what you're asking.
– Eric Lippert
Nov 11 at 0:29
If the problem is that your microphone has a small dynamic range, that's not a problem you can solve in software. Buy a better microphone.
– Eric Lippert
Nov 11 at 0:30
4
4
The actuall sensor only returns values from 0 to 1. Either make the checks at partial numbers. Or just multiply the input by a number. Something like 100.
– Christopher
Nov 10 at 21:50
The actuall sensor only returns values from 0 to 1. Either make the checks at partial numbers. Or just multiply the input by a number. Something like 100.
– Christopher
Nov 10 at 21:50
In StopMicrophone() I multiplied sample_max by 100. It simply give me the number just multiplied by 100. Which means instead of 1 it gives 100.
– optimus
Nov 10 at 22:16
In StopMicrophone() I multiplied sample_max by 100. It simply give me the number just multiplied by 100. Which means instead of 1 it gives 100.
– optimus
Nov 10 at 22:16
If the sensor returns 0 to 1 as float, and you want "half of full volume", jsut compare it to be >= 0.5 You got float values. Use them.
– Christopher
Nov 10 at 22:34
If the sensor returns 0 to 1 as float, and you want "half of full volume", jsut compare it to be >= 0.5 You got float values. Use them.
– Christopher
Nov 10 at 22:34
Since you say that it does return a bigger number when you yell than when you talk quietly, it's not clear what you're asking.
– Eric Lippert
Nov 11 at 0:29
Since you say that it does return a bigger number when you yell than when you talk quietly, it's not clear what you're asking.
– Eric Lippert
Nov 11 at 0:29
If the problem is that your microphone has a small dynamic range, that's not a problem you can solve in software. Buy a better microphone.
– Eric Lippert
Nov 11 at 0:30
If the problem is that your microphone has a small dynamic range, that's not a problem you can solve in software. Buy a better microphone.
– Eric Lippert
Nov 11 at 0:30
|
show 3 more comments
1 Answer
1
active
oldest
votes
up vote
-1
down vote
accepted
The sensor returns only a 0 or a 1, it's not 0->inf, if you want to something else, like checking how load is the voice from 0 to 100, you could record it and check the audio file highest bump and return that.
add a comment |
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
-1
down vote
accepted
The sensor returns only a 0 or a 1, it's not 0->inf, if you want to something else, like checking how load is the voice from 0 to 100, you could record it and check the audio file highest bump and return that.
add a comment |
up vote
-1
down vote
accepted
The sensor returns only a 0 or a 1, it's not 0->inf, if you want to something else, like checking how load is the voice from 0 to 100, you could record it and check the audio file highest bump and return that.
add a comment |
up vote
-1
down vote
accepted
up vote
-1
down vote
accepted
The sensor returns only a 0 or a 1, it's not 0->inf, if you want to something else, like checking how load is the voice from 0 to 100, you could record it and check the audio file highest bump and return that.
The sensor returns only a 0 or a 1, it's not 0->inf, if you want to something else, like checking how load is the voice from 0 to 100, you could record it and check the audio file highest bump and return that.
answered Nov 11 at 18:57
Ido H Levi
847
847
add a comment |
add a comment |
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53243719%2fmicrophone-inputs-maximum-float-number-is-1-how-to-make-it-bigger-and-change-i%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
4
The actuall sensor only returns values from 0 to 1. Either make the checks at partial numbers. Or just multiply the input by a number. Something like 100.
– Christopher
Nov 10 at 21:50
In StopMicrophone() I multiplied sample_max by 100. It simply give me the number just multiplied by 100. Which means instead of 1 it gives 100.
– optimus
Nov 10 at 22:16
If the sensor returns 0 to 1 as float, and you want "half of full volume", jsut compare it to be >= 0.5 You got float values. Use them.
– Christopher
Nov 10 at 22:34
Since you say that it does return a bigger number when you yell than when you talk quietly, it's not clear what you're asking.
– Eric Lippert
Nov 11 at 0:29
If the problem is that your microphone has a small dynamic range, that's not a problem you can solve in software. Buy a better microphone.
– Eric Lippert
Nov 11 at 0:30