How to change sample rate in FAudioCapture?

I’m using FAudioCapture to record from the microphone and get the data in the callback function. However, the sample rate is 48000 and I want to change it to 16000.

I looked at all of the FAudioCapture functions and the only thing I can change is the microphone itself in FAudioCaptureDeviceParams.

I tried downsampling the data in the callback function using Audio::FResampler() But I think it would be way better if I could initialize my microphone with a 16000 sample rate instead of doing the extra work and downsample them afterward.

Is there any way to do that?

Thanks in advance.

In theory, instead of resampling, you should be able to subclass the UAudioCapture class and override its protected Init() function (from parent class UAudioGenerator). This should allow you to initialize the capture device with SampleRate and InputChannels. But the problem is that Init() is called in UAudioCapture’s OpenDefaultStream() AFTER it tells the device to open the stream with a sample rate and input channels. That means your sample rate and channels values never get sent to the capture device when the stream is opened.

FAudioCapture is a member variable of UAudioCapture, and it’s OpenCaptureStream() is called to open the stream with some parameters, but like you mentioned, those parameters don’t include the sample rate or input channels. Instead, the function automatically uses the device’s preferred sample rate and input channels.

So in practice, you would have to rewrite the OpenCaptureStream function (on desktop, the actual implementation is in the FAudioCaptureRtAudioStream class) to accept sample rate and input channels parameters and pass them in before opening the capture stream, assuming their supported by the device. I didn’t feel like doing that, so I just used the resampler.

For other people who want to use the resampler, you can do something similar to this:
(first, include the “AudioPlatformConfiguration” module)

#include "AudioResampler.h"

bool Resample(const float* InAudio, int32 NumFrames, int32 NumChannels, int32 StartSampleRate, int32 EndSampleRate, Audio::VectorOps::FAlignedFloatBuffer& OutAudio)
{
	Audio::VectorOps::FAlignedFloatBuffer AudioBuffer(InAudio, NumFrames * NumChannels);

	Audio::FResamplingParameters ResampleParameters = {
		Audio::EResamplingMethod::BestSinc,
		NumChannels,
		StartSampleRate,
		EndSampleRate,
		AudioBuffer
	};

	int32 ResampleBufferSize = Audio::GetOutputBufferSize(ResampleParameters);
	Audio::FResamplerResults ResampleResults;
	OutAudio.Reset();
	OutAudio.AddZeroed(ResampleBufferSize);
	ResampleResults.OutBuffer = &OutAudio;
	
	return Audio::Resample(ResampleParameters, ResampleResults);
}
1 Like

Are you able to provide a bit more detail or insight into your code structure for this? I am trying to do the same but unsure how to proceed with the snippet you’ve provided. Any more detailed steps would be appreciated!

Haven’t looked at this in awhile, but maybe this article can help you with getting audio data as a float pointer and number of frames. Number of channels and start sample rate depends on your input device. OutAudio is where the resampled audio data should be stored.

1 Like