我正在尝试以编程方式创建一个零延迟麦克风环回到扬声器或输出。这用于生成耳机的侧音。正如我确信任何读者都知道的那样,侧音必须是零延迟,否则,听到你的延迟会导致你失去大部分连贯的说话能力。
我尝试使用C#中的Naudio和使用C ++的portaudio创建解决方案。我对PortAudio有最好的运气,但是我无法实现我需要的零延迟侧标。 Portaudio产生5ms左右的延迟,这是可以检测到的,并导致我的语音持续减慢。
我知道windows提供了一个麦克风环回,我已经测试了这个,但是即使windows环回也有足够的延迟来作为侧音来讨厌。
我在两个部分提出我的问题
1。)这是硬件/软件的限制,实现零音频延迟几乎无法克服吗?
2.。)这是我使用portaudio的C ++代码。有没有办法比我已经有更多的减少延迟? (请原谅我可能邋code的代码,我对C ++很新,我还在学习)
class vC_sidetone {
public:
void enable(int in_ch, int out_ch);
void disable();
vC_sidetone(int inputDevice, int outputDevice){
st_inputDevice = inputDevice;
st_outputDevice = outputDevice;
}
int st_instanceCallBack(const void *inputBuffer,
void *outputBuffer,
unsigned long framesPerBuffer,
const PaStreamCallbackTimeInfo *timeInfo,
PaStreamCallbackFlags statusFlags);
private:
int st_inputDevice;
int st_outputDevice;
PaError st_error;
PaStream *st_stream = NULL;
};
PaStreamParameters vC_getParam(PaDeviceIndex dev, int ch, PaSampleFormat smplFormat){
PaStreamParameters param;
param.device = dev;
param.channelCount = ch;
param.sampleFormat = smplFormat;
//param.suggestedLatency = Pa_GetDeviceInfo(dev)->defaultLowInputLatency;
param.suggestedLatency = 0.000; //here is a good place to tweak latency
param.hostApiSpecificStreamInfo = NULL;
return param;
}
void vC_sidetone::enable(int in_ch, int out_ch){
int framesPerBuffer = 1;
PaSampleFormat smplFormat = paFloat32;
int smplRate = 44100;
PaStreamParameters inParam = vC_getParam(st_inputDevice, in_ch, smplFormat);
PaStreamParameters outParam = vC_getParam(st_outputDevice, out_ch, smplFormat);
st_error = Pa_Initialize();
// Open and start stream using callback:
st_error = Pa_OpenStream(
&st_stream,
&inParam,
&outParam,
smplRate,
framesPerBuffer,
paClipOff,
st_gblCallBack,
this
);
st_error = Pa_StartStream(st_stream);
}
void vC_sidetone::disable(){
st_error = Pa_StopStream(st_stream);
Pa_AbortStream(st_stream);
Pa_CloseStream(st_stream);
Pa_Terminate();
}
int vC_sidetone::st_instanceCallBack(const void *inputBuffer,
void *outputBuffer,
unsigned long framesPerBuffer,
const PaStreamCallbackTimeInfo *timeInfo,
PaStreamCallbackFlags statusFlags){
(void)timeInfo; // Prevent unused variable warnings.
(void)statusFlags;
// Cast data to floats:
float *out = (float*)outputBuffer;
float *in = (float*)inputBuffer;
unsigned long i;
//for (i = 0; i < framesPerBuffer*NUM_CHANNELS; i++)
// out[i] = in[i];
for (i = 0; i < framesPerBuffer; i++) //another good place for latency
out[i] = in[i];
return paContinue;
}
//this is actually not part of the vC_sidetone class, I was getting linker errors
static int st_gblCallBack(const void *inputBuffer,
void *outputBuffer,
unsigned long framesPerBuffer,
const PaStreamCallbackTimeInfo *timeInfo,
PaStreamCallbackFlags statusFlags,
void *userData){
return ((vC_sidetone*)userData)->st_instanceCallBack(inputBuffer, outputBuffer,
framesPerBuffer,
timeInfo,
statusFlags);
}
答案 0 :(得分:0)
抽象层只能增加延迟,而不能减少延迟。很明显,时间旅行是不可能的。 PulseAudio不是Windows上的本机API,它建立在原生音频架构之上。
当前的本机Windows API是WASAPI。它具有低延迟的良好声誉。但它也是底层硬件的抽象层。例如USB也有延迟。你不能做得更好。