Hello All,
I've got working code that receives samples and outputs the audio to speakers but re-sampling is very slow. Do you have suggestions that could immensely speed up the processing? Right now there are gaps in my audio which cause crackling because of the slowness. Most of the code is below for reference.
using (WasapiOut wasapiOut = new WasapiOut(audioClientShareMode_output, 700))
{
try
{
wasapiOut.Init(bufferedWaveProvider);
wasapiOut.Volume = 1f;
wasapiOut.Play();
while (true)
{
byte[] arrayByte = m_queue.Dequeue();
if (null == arrayByte) { break; }
bufferedWaveProvider.AddSamples(arrayByte, 0, arrayByte.Length);
}
}
catch (Exception x) { }
wasapiOut.Stop();
}
/// <summary>
/// http://mark-dot-net.blogspot.com/2014/05/how-to-resample-audio-with-naudio.html
/// </summary>
/// <param name="waveFormat_input"></param>
/// <param name="waveFormat_output"></param>
/// <param name="arrayByte_input"></param>
/// <returns></returns>
private byte[] Resample(EnumResamplerType enumResamplerType, WaveFormat waveFormat_input, WaveFormat waveFormat_output, byte[] arrayByte_input)
{
List<byte[]> listArrayByte_output = new List<byte[]>();
int totalBytesRead = 0, bytesRead = -1;
using (MemoryStream memoryStream_input = new MemoryStream(arrayByte_input))
{
using (RawSourceWaveStream rawSourceWaveStream_input =
new RawSourceWaveStream(memoryStream_input, waveFormat_input))
{
byte[] arrayByte_sub = null;
if (EnumResamplerType.ACM.Equals(enumResamplerType)) // Limited to 16bit sample rate
{
using (WaveFormatConversionStream waveFormatConversionStream_output =
new WaveFormatConversionStream(waveFormat_output, rawSourceWaveStream_input))
{
byte[] arrayByte = new byte[waveFormatConversionStream_output.WaveFormat.AverageBytesPerSecond];
while (0 < (bytesRead = waveFormatConversionStream_output.Read(
arrayByte, 0, arrayByte.Length)))
{
arrayByte_sub = ArraySub(arrayByte, 0, bytesRead);
//Filter(waveFormat_output, ref arrayByte_sub);
listArrayByte_output.Add(arrayByte_sub);
totalBytesRead += bytesRead;
}
}
}
else if (EnumResamplerType.MediaFoundation.Equals(enumResamplerType))
{
using (MediaFoundationResampler mediaFoundationResampler = new MediaFoundationResampler(rawSourceWaveStream_input, waveFormat_output))
{
mediaFoundationResampler.ResamplerQuality = 60;
byte[] arrayByte = new byte[waveFormat_output.AverageBytesPerSecond];
while (0 < (bytesRead = mediaFoundationResampler.Read(
arrayByte, 0, arrayByte.Length)))
{
arrayByte_sub = ArraySub(arrayByte, 0, bytesRead);
//Filter(waveFormat_output, ref arrayByte_sub);
listArrayByte_output.Add(arrayByte_sub);
totalBytesRead += bytesRead;
}
}
}
else if (EnumResamplerType.WDL.Equals(enumResamplerType))
{
WdlResamplingSampleProvider wdlResamplingSampleProvider = new WdlResamplingSampleProvider(rawSourceWaveStream_input.ToSampleProvider(), waveFormat_output.SampleRate);
float[] arrayFloat = new float[waveFormat_output.AverageBytesPerSecond / 4];
while (0 < (bytesRead = wdlResamplingSampleProvider.Read(
arrayFloat, 0, arrayFloat.Length)))
{
arrayByte_sub = ArrayFloatToByte(ArraySub(arrayFloat, 0, bytesRead));
//Filter(waveFormat_output, ref arrayByte_sub);
listArrayByte_output.Add(arrayByte_sub);
totalBytesRead += bytesRead;
}
}
}
}
byte[] arrayByte_output = new byte[totalBytesRead];
for (int i = 0; i < listArrayByte_output.Count; i++)
{
Buffer.BlockCopy(listArrayByte_output[i], 0, arrayByte_output, bytesRead, listArrayByte_output[i].Length);
bytesRead += listArrayByte_output[i].Length;
}
return arrayByte_output;
}
/// <summary>
///
/// </summary>
public enum EnumResamplerType
{
ACM,
MediaFoundation,
WDL
}