⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 audio_cap.cpp

📁 嵌入式linux系统的网络编程(C++) 在ARM上实现视频会议源码
💻 CPP
字号:
///////////////////////////////////////////////////////// FileName:	audio_cap.cpp// Author:		b1gm0use// Project:		myaudio#include <iostream>#include <unistd.h>#include <fcntl.h>#include <sys/types.h>#include <sys/ioctl.h>#include <linux/soundcard.h>#include <dlfcn.h>#include <qsemaphore.h>#include "audio_cap.h"#include "audio.h"#include "g711codec.h"#ifdef _ARM_CODEC_#include "coder_arm.h"#else#include "codecpc.h"#include "coder_pc.h"#endif // _ARM_CODEC_#include "avi.h"using namespace std;///////////////////////////////////////////////////////// Public Functions///////////////////////////////////////////////////////// 构造函数audio_cap::audio_cap ( avi * avi_ptr_in ) // {{{{	verbose_output( 2, "create audio_cap." );	fd_r = 0;	frame = 0;	mono_8k_buff = NULL;	mono_48k_buff = NULL;	stereo_48k_buff = NULL;	compress_buff[0] = compress_buff[1] = NULL;	normal_buff[0] = normal_buff[1] = NULL;;#ifdef _ARM_CODEC_	g723enc = NULL;	enc_flag = 0;#endif	dev_id = 0;	avi_ptr = avi_ptr_in;	current_use_g723 = avi_ptr->use_g723;} // }}}// 析构函数audio_cap::~audio_cap ( void ) // {{{{	verbose_output( 2, "delete audio_cap." );	delete [] normal_buff[0];	delete [] normal_buff[1];	delete [] compress_buff[0];	delete [] compress_buff[1];	delete mono_8k_buff;	delete mono_48k_buff;	delete stereo_48k_buff;#ifdef _ARM_CODEC_	//delete g723enc;#endif } // }}}// 初始化函数// audio_dev 是设备名称int audio_cap::init ( void ) // {{{{	verbose_output( 2, "init audio_cap." );	mono_8k_buff = new BUFF [ BUFF_SIZE / ( 2 * 6 ) ];	mono_48k_buff = new BUFF [ BUFF_SIZE / 2 ];	compress_buff[0] = new BUFF [ MAX_AUDIO_BUFF_SIZE ];	compress_buff[1] = new BUFF [ MAX_AUDIO_BUFF_SIZE ];	stereo_48k_buff = new BUFF [ BUFF_SIZE ];	normal_buff[0] = new BUFF [ FULL_AUDIO_BUFF_SIZE ];	normal_buff[1] = new BUFF [ FULL_AUDIO_BUFF_SIZE ];	init_device();	init_codec_lib();	return SUCCEED;} // }}}// 取得一帧图像// image 为传出参数,指向取得的图像// size 为传出参数,表示图像数据大小int audio_cap::get_image ( BUFF * &image, int *size) // {{{{	verbose_output( 3, "get new capture audio" );	//录音	verbose_output( 4, "begin record." );	int pos = 0;		if ( read( fd_r, normal_buff[frame], BUFF_SIZE * LENGTH ) == -1 )	{		cerr << "Can't read from audio device." << endl;	}	current_use_g723 = avi_ptr->use_g723;	if ( current_use_g723 )	{		compress_buff[frame][0] = 1;		while ( pos < LENGTH )		{			memcpy( stereo_48k_buff, normal_buff[frame] + pos * BUFF_SIZE, BUFF_SIZE );			stereo_to_mono( mono_48k_buff, stereo_48k_buff );			mono_48k_to_8k( mono_8k_buff, mono_48k_buff );			//(*(avi_ptr->audio_cap_semaphore))++;#ifdef _ARM_CODEC_			int len;			Enc_by_frame( g723enc, (short*) mono_8k_buff, 					(char*) ( compress_buff[frame] + AUDIO_BUFF_HEAD_SIZE + pos * BUFF_SIZE_G723), enc_flag, &len );#else			Coder( (WORD16*) mono_8k_buff, 				(char*) ( compress_buff[frame] + AUDIO_BUFF_HEAD_SIZE + pos * BUFF_SIZE_G723) );#endif // _ARM_CODEC_			//(*(avi_ptr->audio_cap_semaphore))--;			pos++;		}		*size = BUFF_SIZE_G723 * LENGTH + AUDIO_BUFF_HEAD_SIZE;		image = compress_buff[frame];	}	else	{		compress_buff[frame][0] = 0;		while ( pos < LENGTH )		{			memcpy( stereo_48k_buff, normal_buff[frame] + pos * BUFF_SIZE, BUFF_SIZE );			(*(avi_ptr->audio_cap_semaphore))++;			enc_fr( (short int*) stereo_48k_buff, compress_buff[frame] + AUDIO_BUFF_HEAD_SIZE + pos * BUFF_SIZE_G711 );			(*(avi_ptr->audio_cap_semaphore))--;			pos++;		}		*size = BUFF_SIZE_G711 * LENGTH + AUDIO_BUFF_HEAD_SIZE;		image = compress_buff[frame];	}	frame ^= 1;	return SUCCEED;} // }}}// 初始化设备void audio_cap::init_device ( void ) // {{{{	int arg = 0;	int status = 0;	if ( NULL == avi_ptr->audio_dev )	{		cerr << "device Can't be NULL" << endl;		exit( 1 );	}	// 打开声音设备 	fd_r = open( avi_ptr->audio_dev, O_RDONLY);	if (fd_r < 0) 	{		cerr << "open of " << avi_ptr->audio_dev << " failed" << endl;;		exit(1);	}	verbose_output( 2, "use audio device: ", avi_ptr->audio_dev );	// 设置采样时的量化位数 	arg = SIZE;	status = ioctl(fd_r, SOUND_PCM_WRITE_BITS, &arg);	if (status == -1)	{		cerr << "SOUND_PCM_WRITE_BITS ioctl failed" << endl;;		exit( 1 );	}	if (arg != SIZE)	{		cerr << "Warning! unable to set sample size" << endl;;	}	verbose_output( 2, "use sample size: ", arg );	// 设置采样时的声道数目 	arg = CHANNELS; 	status = ioctl(fd_r, SOUND_PCM_WRITE_CHANNELS, &arg);	if (status == -1)	{		cerr << "SOUND_PCM_WRITE_CHANNELS ioctl failed" << endl;;		exit( 1 );	}	if (arg != CHANNELS)	{		cerr << "Warning! unable to set number of channels" << endl;;	}	verbose_output( 2, "use audio channels: ", arg );	// 设置采样时的采样频率 	arg = RATE;	status = ioctl(fd_r, SOUND_PCM_WRITE_RATE, &arg);	if (status == -1)	{		cerr << "SOUND_PCM_WRITE_WRITE ioctl failed" << endl;;		exit( 1 );	}	if (arg != RATE )	{		cerr << "Warning! unable to set sample rate" << endl;;	}		verbose_output( 2, "use sample rate: ", arg );	return;} // }}}// 初始化动态链接库void audio_cap::init_codec_lib ( void ) // {{{{	void * dp = NULL;	char * error_string = NULL;		verbose_output( 3, "Init codec lib" );	dp = dlopen( CODEC_LIB, RTLD_LAZY ); 	if ( NULL == dp )	{		error_string = dlerror();		cerr << error_string << endl;		exit( 1 );	}#ifdef _ARM_CODEC_	//////////////////////  Arm Codec Part ///////////////////		Init_Encoder = (Init_Encoder_t) dlsym( dp, "Init_Encoder" );	if ( NULL == Init_Encoder )	{		error_string = dlerror();		cerr << error_string << endl;		exit( 1 );	}	Enc_by_frame = (Enc_by_frame_t) dlsym( dp, "Enc_by_frame" );	if ( NULL == Enc_by_frame )	{		error_string = dlerror();		cerr << error_string << endl;		exit( 1 );	}	if ( avi_ptr->g723_high_bit_rate )	{		// 低四位为0		// enc_flag = enc_flag & 0xF0;	}	else	{		// 低四位为0001		enc_flag += 1;	}	if ( avi_ptr->g723_voice_detect )	{		// 高四位为0001		enc_flag += 0x10;	}	else	{		// 高四位为0		// enc_flag += 0x00	}	Init_Encoder( &g723enc );#else	//////////////////////  PC Codec Part ///////////////////		Init_Coder = (Init_Coder_t) dlsym( dp,"Init_Coder" );	if ( NULL == Init_Coder )	{		error_string = dlerror();		cerr << error_string << endl;		exit( 1 );	}	Init_Vad = (Init_Vad_t) dlsym( dp, "Init_Vad" );	if ( NULL == Init_Vad )	{		error_string = dlerror();		cerr << error_string << endl;		exit( 1 );	}	Init_Cod_Cng = (Init_Cod_Cng_t) dlsym( dp, "Init_Cod_Cng" );	if ( NULL == Init_Cod_Cng )	{		error_string = dlerror();		cerr << error_string << endl;		exit( 1 );	}	Coder = (Coder_t) dlsym( dp, "Coder" );	if ( NULL == Coder )	{		error_string = dlerror();		cerr << error_string << endl;		exit( 1 );	}	set_enc_args = (set_enc_args_t) dlsym( dp, "set_enc_args" );	if ( NULL == set_enc_args )	{		error_string = dlerror();		cerr << error_string << endl;		exit( 1 );	}	enum Crate WrkRate;	Flag UseVx;	if ( avi_ptr->g723_high_bit_rate )	{		WrkRate= Rate63;	}	else	{		WrkRate= Rate53;	}	if ( avi_ptr->g723_voice_detect )	{		UseVx= True;	}	else	{		UseVx= False;	}	set_enc_args( WrkRate, UseVx );    Init_Coder();	if ( avi_ptr->g723_voice_detect )	{		Init_Vad();		Init_Cod_Cng();	}#endif	return;} // }}}void audio_cap::mono_48k_to_8k ( BUFF * buff_8k, BUFF * buff_48k ) // {{{{	// 均为mono数据 	// buff_8k 为 BUFF_SIZE / 2 / 6 个bytes 	// 即 BUFF_SIZE_WORD / 2 / 6 个WORD16	// buff_48k 为 BUFF_SIZE / 2 bytes	// 即 BUFF_SIZE_WORD / 2 个WORD16		WORD16 * from = (WORD16*) buff_48k;	WORD16 * to = (WORD16*) buff_8k;	for ( unsigned int i=0; i<(BUFF_SIZE_WORD/2)/6; i++ )	{		to[i] = from[i*6];	}	return;} // }}}void audio_cap::stereo_to_mono ( BUFF * buff_mono, BUFF * buff_stereo ) // {{{{	// buff_stereo 的大小为 BUFF_SIZE bytes	// 即 BUFF_SIZE_WORD * 2 个WORD16	// buff_mono 的大小为 BUFF_SIZE / 2 bytes	// 即 BUFF_SIZE_WORD 个WORD16		WORD16 * from = (WORD16*) buff_stereo;	WORD16 * to = (WORD16*) buff_mono;	for ( unsigned int i=0; i<BUFF_SIZE_WORD/2; i++ )	{		to[i] = from[i*2];	}	return;} // }}}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -