首页 > 代码库 > 使用portaudio实现语音框架

使用portaudio实现语音框架

在冰冻期间的主要工作就是使用portaudio实现了一套语音采集框架。

因为工作内容所限,所以一直不好谈这块的内容,现在已经离开冰冻了,终于可以和大家交流下这部分的内容了

	const PaDeviceInfo * info = Pa_GetDeviceInfo(indexInputDevice);	PaStreamParameters inputStreamParameters;	inputStreamParameters.device = indexInputDevice;	inputStreamParameters.channelCount = info->maxInputChannels;	inputStreamParameters.hostApiSpecificStreamInfo = 0;	inputStreamParameters.sampleFormat = paFloat32;	inputStreamParameters.suggestedLatency = info->defaultLowInputLatency;	info = Pa_GetDeviceInfo(indexOutputDevice);	PaStreamParameters outputStreamParameters;	outputStreamParameters.device = indexOutputDevice;	outputStreamParameters.channelCount = info->maxOutputChannels;	inputStreamParameters.hostApiSpecificStreamInfo = 0;	inputStreamParameters.sampleFormat = paFloat32;	inputStreamParameters.suggestedLatency = info->defaultLowInputLatency;	PaError err = Pa_OpenStream(&input, &inputStreamParameters, &outputStreamParameters, info->defaultSampleRate, BUFF_LONG, paClipOff, 0, 0);	if (err != paNoError){		throw std::exception("open stream err=%d", err);	}

初始化语音设备

其中一个重要的参数是PaStreamCallback * streamCallback,这个函数是采集和播放的回调函数,用于处理采集到的数据和为播放传入缓冲数据(采集和播放的都是PCM数据),这里和在冰冻不同,我采用了阻塞式的API所以回调函数填写了NULL。

另外2个重要的参数是const PaStreamParameters * inputParameters和const PaStreamParameters * outputParameters

分别是输入设备和输出设备

关于设备的初始化

Pa_GetDeviceCount获取设备数, Pa_GetDeviceInfo获取设备信息

Pa_GetHostApiCount获取主机上可用的接口数目(windows上就是MME和DX Sound),Pa_GetHostApiInfo获取API信息。

PaError sound::read_buff(){	PaError err = Pa_ReadStream(input, outputbuff, BUFF_LONG);	if (err == paNoError){		sigCapture(outputbuff, BUFF_LONG);	}	return err;}PaError sound::write_buff(char * inputbuff, int bufflong){	return  Pa_WriteStream(input, inputbuff, BUFF_LONG);}

采样和播放

和老式的回调不同,阻塞式的读写,具有优雅的可编程性但是性能略低。

另在回调的模式中,和阻塞式不同的是,需要编写2个冗长的回调函数

typedef int PaStreamCallback(const void *input, void *output, unsigned long frameCount, const PaStreamCallbackTimeInfo *timeInfo, PaStreamCallbackFlags statusFlags, void *userData)

在input回调中向写入input缓冲区写入,在output回调中处理output缓冲区中采集到的数据。