📄 audio_cap.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 + -