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;
} // }}}