I am trying to send incoming microphone audio from Unity to Wwise in real time. I have a "producer thread" and a "consumer thread". I am trying to copy my incoming buffer from the producer to the consumer.
// Unity callback on microphone input (“producer thread“)
void OnAudioFilterRead(float[] data, int channels)
{
// acquire ownership of mutex and buffer
mutex.WaitOne();
// copy samples to buffer (de–interleave channels)
for (int i = 0; i < data.Length / channels; i++)
{
buffer.Add(data[i * channels]);
}
// release ownership of mutex and buffer
mutex.ReleaseMutex();
}
// Wwise callback that sends buffered samples to Wwise (“consumer thread“)
bool AudioSamplesDelegate(uint playingID, uint channelIndex, float[] samples)
{
// acquire ownership of mutex and buffer
mutex.WaitOne();
// copy samples from buffer to temporary block
int blockSize = Math.Min(buffer.Count, samples.Length);
List<float> block = buffer.GetRange(0, blockSize);
buffer.RemoveRange(0, blockSize);
// release ownership of mutex and buffer (release mutex as quickly as possible)
mutex.ReleaseMutex();
// copy samples from temporary block to output array
block.CopyTo(samples);
// Return false to indicate that there is no more data to provide. This will also stop the associated event.
return IsPlaying;
}
This works but the audio I get from Wwise is glitchy. Any inputs on the best method to do this/improve this? Are circular buffers the way to go?
I think use multiple buffers instead of a large one to reduce synchronous time will be helpful.
// Create a thread-safed queue
Queue bufferQueue = Queue.Synchronized(new Queue());
List<float> remains;
// Unity callback on microphone input (“producer thread“)
void OnAudioFilterRead(float[] data, int channels)
{
var buffer = new List<folat>(data.Length);
// copy samples to buffer (de–interleave channels)
for (int i = 0; i < data.Length / channels; i++)
{
buffer.Add(data[i * channels]);
}
// Add buffer to the queue
bufferQueue.Enqueue(buffer);
}
// Wwise callback that sends buffered samples to Wwise (“consumer thread“)
bool AudioSamplesDelegate(uint playingID, uint channelIndex, float[] samples)
{
// Fill samples
var requiredLength = samples.Length;
while (requiredLength > 0)
{
if (remains == null)
if (bufferQueue.Count > 0)
remains = bufferQueue.Dequeue();
else
break;
if (remains.Length > requiredLength)
{
remains.CopyTo(0, samples, samples.Length - requiredLength, requiredLength);
remains.RemoveRange(0, requiredLength);
break;
}
remains.CopyTo(0, samples, samples.Length - requiredLength, remains.Length);
requiredLength -= remains.Length;
remains = null;
}
// Return false to indicate that there is no more data to provide. This will also stop the associated event.
return IsPlaying;
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.