gusucode.com > 嵌入式linux系统的网络编程源码程序 > 嵌入式linux系统的网络编程源码程序/视频会议源码/audio_player.cpp
/////////////////////////////////////////////////////// // FileName: audio_player.cpp // Author: b1gm0use // Project: myvideo #include <iostream> #include <qsemaphore.h> #include <dlfcn.h> #include <qwaitcondition.h> #include "audio_player.h" #include "capture_event.h" #include "audio_cap_thread.h" #include "audio_play_thread.h" #include "audio.h" #include "network.h" #include "g711codec.h" #include "avi.h" #ifdef _ARM_CODEC_ #include "decod_arm.h" #else #include "codecpc.h" #include "decod_pc.h" #endif // _ARM_CODEC_ using namespace std; extern void dump_image ( BUFF * image, size_t size, const char * filename ); /////////////////////////////////////////////////////// // Public Functions /////////////////////////////////////////////////////// // 构造函数 AudioPlayer::AudioPlayer( avi * avi_ptr_in, QWidget *parent, const char *name ) : QWidget( parent, name ) // {{{ { verbose_output( 2, "create AudioPlayer." ); act = NULL; apt = NULL; frame = 0; mono_8k_buff = NULL; mono_48k_buff = NULL; stereo_48k_buff = NULL; g723_buff = NULL; g711_buff = NULL; normal_buff = NULL;; #ifdef _ARM_CODEC_ g723dec = NULL; #endif avi_ptr = avi_ptr_in; is_running = false; ready_to_play_audio = new QWaitCondition; current_use_g723 = false; } // }}} // 析构函数 AudioPlayer::~AudioPlayer( void ) // {{{ { verbose_output( 2, "delete AudioPlayer." ); if ( NULL != act ) { if ( act->running() ) { act->terminate(); } delete act; } delete [] mono_8k_buff; delete [] mono_48k_buff; delete [] stereo_48k_buff; delete [] normal_buff; // 不用delete,没开辟内存 // g723_buff = NULL; // g711_buff = NULL; #ifdef _ARM_CODEC_ //delete g723dec; #endif } // }}} // 初始化函数 int AudioPlayer::init ( void ) // {{{ { verbose_output( 2, "init AudioPlayer." ); normal_buff = new BUFF [ BUFF_SIZE * LENGTH ]; // 初始化所有缓冲区,保证动态切换编码 mono_8k_buff = new BUFF [ BUFF_SIZE / ( 2 * 6 ) ]; mono_48k_buff = new BUFF [ BUFF_SIZE / 2 ]; g723_buff = NULL; g711_buff = NULL; stereo_48k_buff = new BUFF [ BUFF_SIZE ]; for ( int i=0; i<3; i++ ) { avi_ptr->snd_buff_semaphore[i] = new QSemaphore( 1 ); } init_codec_lib(); return SUCCEED; } // }}} void AudioPlayer::begin_running ( void ) // {{{ { verbose_output( 2, "AudioPlayer begin running." ); if ( avi_ptr->net_mode != CONNECT ) { act = new audio_cap_thread( avi_ptr, this ); act->start(); } if ( avi_ptr->net_mode != LISTEN ) { apt = new audio_play_thread( avi_ptr, this ); apt->init(); apt->start(); } is_running = true; return; } // }}} bool AudioPlayer::running ( void ) // {{{ { return is_running; } // }}} /////////////////////////////////////////////////////// // Protected Functions /////////////////////////////////////////////////////// // 内部函数,用于接收自定义的事件 void AudioPlayer::customEvent ( QCustomEvent * e ) // {{{ { verbose_output( 4, "AudioPlayer playback event." ); if ( e->type() == AUDIO_EVENT ) { capture_event * ce = ( capture_event * ) e; g723_buff = ce->get_buff(); if ( g723_buff[0] == 0 ) { current_use_g723 = false; } else { if ( g723_buff[0] == 1 ) { current_use_g723 = true; } else { cerr << "Error! There is only two possible value." << endl; } } if ( current_use_g723 ) { if ( NULL == g723_buff ) { cerr << "Send buffer Can't be NULL" << endl; exit( 1 ); } int pos = 0; while ( pos < LENGTH ) { #ifdef _ARM_CODEC_ Dec_by_frame( g723dec, (char*) ( g723_buff + AUDIO_BUFF_HEAD_SIZE + pos * BUFF_SIZE_G723 ), 0, (short*) mono_8k_buff ); #else Decod( (WORD16*) mono_8k_buff, (char*) ( g723_buff + AUDIO_BUFF_HEAD_SIZE + pos * BUFF_SIZE_G723 ), (WORD16) 0); #endif mono_8k_to_48k( mono_48k_buff, mono_8k_buff ); mono_to_stereo( stereo_48k_buff, mono_48k_buff ); memcpy( normal_buff + pos * BUFF_SIZE, stereo_48k_buff, BUFF_SIZE ); pos++; } } else { g711_buff = ce->get_buff(); if ( NULL == g711_buff ) { cerr << "Send buffer Can't be NULL" << endl; exit( 1 ); } int pos = 0; while ( pos < LENGTH ) { dec_fr( g711_buff + AUDIO_BUFF_HEAD_SIZE + pos * BUFF_SIZE_G711, (short int*) stereo_48k_buff ); memcpy( normal_buff + pos * BUFF_SIZE, stereo_48k_buff, BUFF_SIZE ); pos++; } } verbose_output( 4, "fill the snd_buff No.", frame ); (*(avi_ptr->snd_buff_semaphore[frame]))++; if ( NULL == avi_ptr->snd_buff[frame] ) { cerr << "Receive buffer Can't be NULL" << endl; exit( 1 ); } memcpy( avi_ptr->snd_buff[frame], normal_buff, BUFF_SIZE * LENGTH ); (*(avi_ptr->snd_buff_semaphore[frame]))--; //if ( avi_ptr->audio_can_play_semaphore->available() == 0 ) //{ //(*(avi_ptr->audio_can_play_semaphore))--; //} ready_to_play_audio->wakeAll(); frame = ( frame + 1 ) % 3; } } // }}} // 初始化动态链接库 void AudioPlayer::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_Decoder = (Init_Decoder_t) dlsym( dp, "Init_Decoder" ); if ( NULL == Init_Decoder ) { error_string = dlerror(); cerr << error_string << endl; exit( 1 ); } Dec_by_frame = (Dec_by_frame_t) dlsym( dp, "Dec_by_frame" ); if ( NULL == Dec_by_frame ) { error_string = dlerror(); cerr << error_string << endl; exit( 1 ); } Init_Decoder( &g723dec ); #else ////////////////////// PC Codec Part /////////////////// Init_Decod = (Init_Decod_t) dlsym( dp,"Init_Decod" ); if ( NULL == Init_Decod ) { error_string = dlerror(); cerr << error_string << endl; exit( 1 ); } Init_Dec_Cng = (Init_Dec_Cng_t) dlsym( dp, "Init_Dec_Cng" ); if ( NULL == Init_Dec_Cng ) { error_string = dlerror(); cerr << error_string << endl; exit( 1 ); } Decod = (Decod_t) dlsym( dp, "Decod" ); if ( NULL == Decod ) { error_string = dlerror(); cerr << error_string << endl; exit( 1 ); } Init_Decod(); Init_Dec_Cng(); #endif // _ARM_CODEC_ return; } // }}} void AudioPlayer::mono_8k_to_48k ( BUFF * buff_48k, BUFF * buff_8k ) // {{{ { // 均为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_8k; WORD16 * to = (WORD16*) buff_48k; for ( unsigned int i=0; i<(BUFF_SIZE_WORD/2)/6; i++ ) { for ( unsigned int j=0; j<6; j++ ) { to[i*6+j] = from[i]; } } return; } // }}} void AudioPlayer::mono_to_stereo ( BUFF * buff_stereo, BUFF * buff_mono ) // {{{ { // buff_stereo 的大小为 BUFF_SIZE bytes // 即 BUFF_SIZE_WORD 个WORD16 // buff_mono 的大小为 BUFF_SIZE / 2 bytes // 即 BUFF_SIZE_WORD / 2 个WORD16 WORD16 * from = (WORD16*) buff_mono; WORD16 * to = (WORD16*) buff_stereo; for ( unsigned int i=0; i<BUFF_SIZE_WORD/2; i++ ) { to[2*i] = from[i]; to[2*i+1] = from[i]; } return; } // }}}