我試圖以編程方式爲揚聲器或輸出創建零延遲麥克風環回。這用於爲耳機生成側音。正如我確信任何讀者都知道的那樣,側音必須是零延遲,否則,聽到自己的延遲會導致你失去大部分連貫的說話能力。零延遲麥克風環回,側音
我試着在C#中使用Naudio和使用C++的portaudio創建解決方案。我對PortAudio有最好的運氣,但是我無法實現我需要的零延遲側音。 Portaudio產生了5毫秒左右的延遲,這是可檢測的,並導致我的講話持續減慢。
我知道windows提供麥克風環回,而我已經測試過這個,但是即使窗口環回有足夠的延遲時間也會成爲側音惱人的。
我問我在兩個部分
1)問題是這樣的硬件/軟件的限制,並實現零的音頻等待幾乎難以逾越?
2.)這是我使用portaudio的C++代碼。有什麼方法可以減少比我已有的延遲更多嗎? (請原諒我可能馬虎的代碼,我很新的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);
}
由於輸入和輸出硬件和底層軟件棧(不是PortAudio,但是DirectSound或任何它使用的)的工作方式,你所需要的通常是不可實現的。數據在大小大於1的緩衝區中傳遞,每個樣本需要1/44000秒。因此,例如,只有88個採樣的緩衝器意味着用於回放(並且再次用於記錄)的最小2ms延遲。關於Q2,PortAudio文檔建議您將framesPerBuffer設置爲零以避免增加延遲的額外緩衝層。 – Damon