PJMEDIA之录音器的使用(capture sound to avi file)

为了熟悉pjmedia的相关函数以及使用方法,这里练习了官网上的一个录音器的例子。

核心函数:

pj_status_t pjmedia_wav_writer_port_create ( pj_pool_t pool,
    const char *  filename,
    unsigned  clock_rate,
    unsigned  channel_count,
    unsigned  samples_per_frame,
    unsigned  bits_per_sample,
    unsigned  flags,
    pj_ssize_t  buff_size,
    pjmedia_port **  p_port 
  )    

Create a media port to record streams to a WAV file. Note that the port must be closed properly (with pjmedia_port_destroy()) so that the WAV header can be filled with correct values (such as the file length). WAV writer port supports for writing audio in uncompressed 16 bit PCM format or compressed G.711 U-law/A-law format, this needs to be specified in flags param.

Parameters
pool Pool to create memory buffers for this port.
filename File name.
clock_rate The sampling rate.
channel_count Number of channels.
samples_per_frame Number of samples per frame.
bits_per_sample Number of bits per sample (eg 16).
flags Port creation flags, see pjmedia_file_writer_option.
buff_size Buffer size to be allocated. If the value is zero or negative, the port will use default buffer size (which is about 4KB).
p_port Pointer to receive the file port instance.
Returns
PJ_SUCCESS on success.
pj_status_t pjmedia_snd_port_create_rec ( pj_pool_t pool,
    int  index,
    unsigned  clock_rate,
    unsigned  channel_count,
    unsigned  samples_per_frame,
    unsigned  bits_per_sample,
    unsigned  options,
    pjmedia_snd_port **  p_port 
  )    

Create unidirectional sound device port for capturing audio streams from the sound device with the specified parameters.

Parameters
pool Pool to allocate sound port structure.
index Device index, or -1 to let the library choose the first available device.
clock_rate Sound device's clock rate to set.
channel_count Set number of channels, 1 for mono, or 2 for stereo. The channel count determines the format of the frame.
samples_per_frame Number of samples per frame.
bits_per_sample Set the number of bits per sample. The normal value for this parameter is 16 bits per sample.
options Options flag.
p_port Pointer to receive the sound device port instance.
Returns
PJ_SUCCESS on success, or the appropriate error code.
pj_status_t pjmedia_endpt_create ( pj_pool_factory pf,
    pj_ioqueue_t ioqueue,
    unsigned  worker_cnt,
    pjmedia_endpt **  p_endpt 
  )    

Create an instance of media endpoint.

Parameters
pf Pool factory, which will be used by the media endpoint throughout its lifetime.
ioqueue Optional ioqueue instance to be registered to the endpoint. The ioqueue instance is used to poll all RTP and RTCP sockets. If this argument is NULL, the endpoint will create an internal ioqueue instance.
worker_cnt Specify the number of worker threads to be created to poll the ioqueue.
p_endpt Pointer to receive the endpoint instance.
Returns
PJ_SUCCESS on success.
pj_status_t pjmedia_snd_port_connect ( pjmedia_snd_port snd_port,
    pjmedia_port port 
  )    

Connect a port to the sound device port. If the sound device port has a sound recorder device, then this will start periodic function call to the port's put_frame() function. If the sound device has a sound player device, then this will start periodic function call to the port's get_frame() function.

For this version of PJMEDIA, the media port MUST have the same audio settings as the sound device port, or otherwise the connection will fail. This means the port MUST have the same clock_rate, channel count, samples per frame, and bits per sample as the sound device port.

Parameters
snd_port The sound device port.
port The media port to be connected.
Returns
PJ_SUCCESS on success, or the appropriate error code.
//capture sound to wav file
//heat nan -test
#include<pjmedia.h>
#include<pjlib.h>
#include<stdio.h>
#include<stdlib.h>


#define CLOCK_RATE 44100 //采样率
#define NCHANNELS 2  //通道数
#define SAMPLES_PER_FRAME (NCHANNELS *(CLOCK_RATE*10/1000)) //每帧包含的采样数
#define BITS_PER_SAMPLE 16  //每个抽样的字节数

int main()
{
	pj_caching_pool cp;
	pjmedia_endpt *med_endpt;
	pj_pool_t *pool;
	pjmedia_port *file_port;  
	pjmedia_snd_port *snd_port;
	pj_status_t status;
	char tmp[10];
	char filename[20];

	status=pj_init();
	if(status!=PJ_SUCCESS)
	{
		PJ_LOG(3,("failed","pj_init"));
	}

	pj_caching_pool_init(&cp,&pj_pool_factory_default_policy,0);
//创建endpoint
	status=pjmedia_endpt_create(&cp.factory,NULL,1,&med_endpt);
	if(status!=PJ_SUCCESS)
	{
		PJ_LOG(3,("failed","pjmedia_endpt_create"));
	}

	pool=pj_pool_create(&cp.factory,
		"wav_recoder",4000,4000,NULL);
//输入要保存录音的文件名    
	PJ_LOG(3,("wav_recorder","please input the file name!"));
	gets(filename);
//创建录音端口  把音频流写成wav文件
	status=pjmedia_wav_writer_port_create(pool,filename,
		CLOCK_RATE,
		NCHANNELS,
		SAMPLES_PER_FRAME,
		BITS_PER_SAMPLE,
		0,0,
		&file_port  //指向接收该实例的pjmedia_port
		);
	if(status!=PJ_SUCCESS)
	{
		PJ_LOG(3,("failed","pjmedia_wav_write_port_create"));
	}
//创建单向的音频设备端口用来捕获音频
	status=pjmedia_snd_port_create_rec(pool,-1,
		PJMEDIA_PIA_SRATE(&file_port->info),
		PJMEDIA_PIA_CCNT(&file_port->info),
		PJMEDIA_PIA_SPF(&file_port->info),
		PJMEDIA_PIA_BITS(&file_port->info),
		0,&snd_port);
	if(status!=PJ_SUCCESS)
	{
		PJ_LOG(3,("failed","pjmedia_snd_port_create_rec"));
	}
//连接两个端口开始录音
	status=pjmedia_snd_port_connect(snd_port,file_port);
	if(status!=PJ_SUCCESS)
	{
		PJ_LOG(3,("failed","pjmedia_snd_port_connect"));
	}
 
	pj_thread_sleep(10);
  //显示终止信息  
	puts("PRESS <ENTER> to stop recording and quit");

	if(fgets(tmp,sizeof(tmp),stdin)==NULL)
	{
		puts("EOF while reading stdin,will quit now..");
	}
 //养成良好习惯,吃完饭总要刷刷碗吧! 
	pjmedia_snd_port_destroy(snd_port);
	pjmedia_port_destroy(file_port);

   pj_pool_release(pool);
   pjmedia_endpt_destroy(med_endpt);

   pj_caching_pool_destroy(&cp);

   pj_shutdown();
	return 0;
//	pj_thread_sleep(10);


}
原文地址:https://www.cnblogs.com/heat-man/p/3664558.html