- Home /
Generating an Echo effect in Unity
Hi there, I am quite new to playing with Microphone audio on Unity. For a project I require to create an Echo Effect to the Microphone audio on Unity. First of all I want to create a Push to Talk kind of Option, so when I press "S" I start getting audio input and as soon as I leave that button it stops.
While this audio is being input, I want to process it with an Echo algorithm and generate a real time effect.
I understand that for this I should use the Microphone.Start and get my data, but somehow I am unable to even understand how the recording process works in unity.
As given, Start(deviceName: string, loop: bool, lengthSec: int, frequency: int): What is the Loop parameter here for?
In the example given,
// Start recording with built-in Microphone and play the recorded audio right away
function Start() {
audio.clip = Microphone.Start("Built-in Microphone", true, 10, 44100);
audio.Play();
}
It does not play the audio right away! Isnt this being called just once on start, then how will it play all the data right away?
My major task is to get the real time data samples, and play them immediately, and then apply some kind of delay and fade multiplier to get the ECHO effect.
Please help me out! Thanks!
EDIT : So I have made some progress or a hack more to say, If I add a delay before I call the AudioSource.Play(), such as by counting down a timer for about 0.5s I am getting the output. Also I call this Play from my Update(). But in the last 4 seconds of the sound, I get a really bad stutter! Can anyone explain that? using UnityEngine; using System.Collections;
public class EchoTest : MonoBehaviour {
public AudioSource tempSource;
AudioClip tempClip;
// Use this for initialization
void Start () {
string deviceName = "";
foreach (string device in Microphone.devices)
deviceName = device;
tempClip = Microphone.Start(deviceName, false,15, 44100);
tempSource = this.GetComponent<AudioSource>();
tempSource.clip = tempClip;
}
bool a = true;
float timer = 0.1f;
// Update is called once per frame
void Update () {
if (timer > 0)
timer = timer - Time.deltaTime;
else if (timer <= 0&&a)
{
tempSource.playOnAwake = false;
tempSource.loop = false;
tempSource.Play();
a = false;
}
}
AudioClip createdelay(AudioClip temp)
{
if (timer > 0)
timer = timer - Time.deltaTime;
if (timer <= 0)
return temp;
return null;
}
}
Hi Starwalker, ty for your response. Yes, I did but for my project I need some further processing on the sounds, hence I need further control. $$anonymous$$y real problem is to get this audio co$$anonymous$$g back to me real time. I have made some progress, Ill modify my question..
`else if (timer <= 0&&a)` A <= (B and C)
When your timer moves closer to 0, unity gets precision issues when you compare to float, try this:
`else if ((timer < 0) && a)` , ( A < B) and C, force A' and C comparison.
I was trying to see why you are having the last four seconds be garbled. I'm not quite sure, but I see that you are setting it to record for 15 seconds. $$anonymous$$aybe if you set that to a longer time, it will be able to catch that part of the recording.
So I was able to prevent the stutter at the end, by setting the loop attribute to true, such as, tempClip = $$anonymous$$icrophone.Start(deviceName, true,15, 44100);
I wonder why that stops the stutter..Still working on this.
Answer by Starwalker · Nov 15, 2013 at 06:17 AM
Hmm .. it seems that since the Microphone.Start is a Static method, the bool is actually setting whether or not to continue over-lap recording after the time is reached, meaning even if you set the time to 4 secs, you will not get stutter, since it really is just overlapping what it recorded in those 4 secs.
So what you are setting is basically telling unity to use the "time" as a buffer and loop back when the time runs out. I'm curious if this actually works with just 4 -5 secs, if yes, then what I said is true.
And the final reason for the stutter:
It stutters because the frame time of time.delta is lower than 1.5 secs (which you have set) and at those frames, it stops recording
Answer by jschhabria · Nov 15, 2013 at 06:46 AM
So, I solved the problem with the stutter, simply by flipping the bool to true. Heres the cleaner code, but not I have been hit by a new issue. Posting it in a new question. Thanks guys! Here is the cleaner code for Push to Talk kind of a thing using Unity Microphone, with a small stutter in between, :P using UnityEngine; using System.Collections;
public class EchoTest : MonoBehaviour
{
public AudioSource tempSource;
string deviceName = "";
// Use this for initialization
void Start()
{
}
bool m_bIsSpeak = false;
public bool IsSpeak
{
get
{
return m_bIsSpeak;
}
set
{
m_bIsSpeak = value;
}
}
// Update is called once per frame
void Update()
{
if (Input.GetKeyDown(KeyCode.S))
{
Debug.Log("PTT Enabled");
IsSpeak = true;
}
if (Input.GetKeyUp(KeyCode.S))
{
Debug.Log("PTT Disabled");
StopTheSound();
}
if (IsSpeak)
{
if (!(tempSource.audio.isPlaying))
{
PlayTheSound();
}
}
}
public void StopTheSound()
{
Debug.Log("Stopping the sound..");
IsSpeak = false;
Microphone.End(deviceName);
}
public void PlayTheSound()
{
tempSource.clip = Microphone.Start(deviceName, true, 5, 44100);
while (!(Microphone.GetPosition(deviceName) > 0))
{ }
tempSource.playOnAwake = false;
tempSource.loop = false;
tempSource.Play();
}
}
Answer by edulopez · Mar 28, 2017 at 04:40 AM
I manage to make it using different audio sources and the microphone. Simply attach 4 audio sources to your main camera and they will work do their job.
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class EchoSoundBehaviour : MonoBehaviour
{
/// <summary>
/// Audio sources for the echo effect
/// </summary>
public AudioSource EchoAudioSource1;
public AudioSource EchoAudioSource2;
public AudioSource EchoAudioSource3;
public AudioSource EchoAudioSource4;
string deviceName = null;
/// <summary>
/// Audio Clip Recorded
/// </summary>
private AudioClip _recordedClip;
private float _startedRecordingTime = 10;
private int recordLenght = 2000;
// Update is called once per frame
void Update()
{
if (!Microphone.IsRecording(deviceName) )
{
PlaySounds();
}
// After some time playing, stop the recording
else if (LevelManager.GameTimer - _startedRecordingTime > recordLenght)
StopRecording();
}
public void StopRecording()
{
Microphone.End(deviceName);
}
/// <summary>
/// Record sounds for an specific amount of time
/// </summary>
public void StartRecording()
{
_recordedClip = Microphone.Start(deviceName, true, recordLenght, 44100);
}
/// <summary>
/// Play recorded sounds
/// </summary>
public void PlaySounds()
{
StartRecording();
if (EchoAudioSource1.isPlaying) return;
EchoAudioSource1.clip = _recordedClip;
EchoAudioSource2.clip = _recordedClip;
EchoAudioSource3.clip = _recordedClip;
EchoAudioSource4.clip = _recordedClip;
_startedRecordingTime = LevelManager.GameTimer;
PlayAudioSource(EchoAudioSource1, 0.4f, 0.8f);
PlayAudioSource(EchoAudioSource2, 1f, 0.5f);
PlayAudioSource(EchoAudioSource3, 1.8f, 0.3f);
PlayAudioSource(EchoAudioSource4, 2.5f, 0.15f);
}
public static void PlayAudioSource( AudioSource audio , float delay, float volume)
{
audio.playOnAwake = false;
audio.volume = volume;
audio.PlayDelayed(delay);
audio.loop = false;
}
}
Your answer
Follow this Question
Related Questions
audio different in game than preview? 1 Answer
footstep sound 1 Answer
Audio mixed, blending on distance ? 1 Answer
Voice Recording issue ?? 0 Answers
GetSpectrumData works only for 3 sec of microphone input 0 Answers