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

📄 aaci_dmabak.c

📁 此压缩包为杰得开发得z228的BSP的源代码,可以实现很多功能,尤其是视频解码有很好的效果.
💻 C
📖 第 1 页 / 共 2 页
字号:
}
#define PlayBufferCount 2
DWORD AudioDMAThread(LPVOID p)
{
	int error = 0 , bufferedplayingblock = 0 , leftplayingblock = 0 , storedblock = 0 , toremove = 0;
	int loopcount = 0;
	RETAILMSG( (DebugMsgMask&DebugMsg_Important ), (TEXT( "AACI : DMA : Enter Thread\r\n" ) ));

	if(0)
	{
		int time = GetTickCount() ;
		while( !error && DMAPlayCmd != DMA_PLAY_EXIT )
		{
			if( (loopcount++%1000) == 0 )
				RETAILMSG( 1 , (TEXT("AudioPlayThread loop %d\n" ) , bufferedplayingblock ));
			if( DMAPlayCmd == DMA_PLAY_STOP || storedblock == 0 )
			{
				WaitForSingleObject( DmaPlayEvent , INFINITE );
				InterruptDone( PlayDmaIntID );
			}
			if( (DMAPlayCmd != DMA_PLAY_START) )
				continue;
			if( PlayBufferStoreIndex >= PlayBufferPlayIndex)
				storedblock = PlayBufferStoreIndex - PlayBufferPlayIndex;
			else
				storedblock = TotalPlayBufferCnt - PlayBufferPlayIndex + PlayBufferStoreIndex;
			if( storedblock > 0 )
			{
				if( AddPlayBuffer( &leftplayingblock ) == 0 )
				{
					int now;
					while(1)
					{
						now = GetTickCount();
						if( now - time > 11 )
							break;
						Sleep( 1 );
					}
					time = now;
					RemovePlayBuffer(1);
				}
			}
		}
	}

	while( !error &&  DMAPlayCmd != DMA_PLAY_EXIT  )
	{
		if( (loopcount++%1000) == 0 )
			RETAILMSG( 1 , (TEXT("AudioPlayThread loop %d\r\n" ) , bufferedplayingblock ));		
		RETAILMSG( (DebugMsgMask&DebugMsg_Trace) , (TEXT( "AACI : DMA : loop begin\r\n" ) ));
		AddDebugMsg( "new play round  %d %d %d %d\n" , DMAPlayCmd , leftplayingblock, bufferedplayingblock , storedblock);
		if( DMAPlayCmd == DMA_PLAY_STOP )
		{
			int param1 = 1 , param2 = 0;
			KernelIoControl( HAL_IOCTL_AACI_CLEARSTATUS , &param1 , sizeof(int) , &param2 , sizeof(int) , 0);
			bufferedplayingblock = 0;
		}
		if(DMAPlayCmd == DMA_PLAY_STOP || storedblock == 0 )
		{
			WaitPlayBuffer = 1;
			WaitForSingleObject( PlayCmdEvent , INFINITE );
			WaitPlayBuffer = 0;
		}
		if( (DMAPlayCmd != DMA_PLAY_START)  )
			continue;
		if( bufferedplayingblock && (bufferedplayingblock == PlayBufferCount || storedblock == 0) )	// buffer full or store empty, wait
		{
			AddDebugMsg("wait play event %d %d %d %x\n" , leftplayingblock, bufferedplayingblock , storedblock, DmaPlayEvent);
			RETAILMSG( (DebugMsgMask&DebugMsg_Trace) , (TEXT( "AACI : : wait %d %d\r\n" ), bufferedplayingblock , storedblock));
			if( WaitForSingleObject( DmaPlayEvent , 100 ) == 0 )
				InterruptDone( PlayDmaIntID );
			else
			{
				OnPlayDmaFail();
			}
			AddDebugMsg( "wait play dma over\n" );
		}
		RETAILMSG( (DebugMsgMask&DebugMsg_Trace) , (TEXT( "AACI : DMA : start work\r\n" ) ));
		if( PlayBufferStoreIndex >= PlayBufferPlayIndex)
			storedblock = PlayBufferStoreIndex - PlayBufferPlayIndex;
		else
			storedblock = TotalPlayBufferCnt - PlayBufferPlayIndex + PlayBufferStoreIndex;		
		EnterCriticalSection( &Critical );
		KernelIoControl( HAL_IOCTL_AACI_GETBUFFER , &leftplayingblock , sizeof(int) , 0,0  , 0);
		LeaveCriticalSection( &Critical );
		AddDebugMsg( "get play status %d %d %d\n" , leftplayingblock, bufferedplayingblock , storedblock);
		if( DMAPlayCmd == DMA_PLAY_START )
		if( ( leftplayingblock < bufferedplayingblock || bufferedplayingblock < PlayBufferCount) && storedblock > 0 )
		{	// add buffer			
			AddDebugMsg( "to add play %d %d \n" , leftplayingblock , bufferedplayingblock);
			if( AddPlayBuffer( &leftplayingblock ) == 0 )
			{
				AddDebugMsg( "add play over %d\n" , leftplayingblock );
				bufferedplayingblock ++;
				storedblock	-- ;			
			}
		}	
		AddDebugMsg( "to remove play %d %d \n" , leftplayingblock , bufferedplayingblock );
		if( leftplayingblock < bufferedplayingblock )
		{	// remove header
			int toremove = bufferedplayingblock - leftplayingblock;
			if( RemovePlayBuffer( toremove ) == 0 )
			{
				bufferedplayingblock = leftplayingblock;
				AddDebugMsg( "remove play over %d \n" , bufferedplayingblock );
			}			
		}
		else if( leftplayingblock > bufferedplayingblock )
			RETAILMSG( (DebugMsgMask&DebugMsg_Normal), (TEXT( "AACI : Thread : error, more left %d %d\r\n") , bufferedplayingblock , leftplayingblock )); 				
	}
	RETAILMSG( (DebugMsgMask&DebugMsg_Important ), (TEXT( "AACI : DMA : leave Thread\r\n" ) ));
	return error;
}

int ReleaseAll()
{
	int error = 0;
	DMAPlayCmd = DMA_PLAY_EXIT;
	if( DmaThread )
	{
		if( DmaPlayEvent )
			SetEvent( DmaPlayEvent );
		if( PlayCmdEvent )
			SetEvent( PlayCmdEvent );
		if( WaitForSingleObject( DmaThread , 1000 ) != WAIT_OBJECT_0 )
			TerminateThread( DmaThread , -1 );
		CloseHandle( DmaThread );
	}
	DMARecordCmd = DMA_RECORD_EXIT;
	if( DmaRecordThread )
	{
		if( DmaRecordEvent )
			SetEvent( DmaRecordEvent );
		if( RecordCmdEvent )
			SetEvent( RecordCmdEvent );
		if( WaitForSingleObject( DmaRecordThread , 1000 ) != WAIT_OBJECT_0 )
			TerminateThread( DmaRecordThread , -1 );
		CloseHandle( DmaRecordThread );
	}
	if( ReleasePlayDMA() != 0 )
		error = 1;
	return error;
}

int InitAll()
{
	int error = 0;
	if( AllocPlayDMA() != 0 )
		error = 1;
	else if( InitPlayDMA() != 0 )
		error = 2;
	if( !error )
	{
		if( AllocRecordDMA() != 0 ) 			
			error =  3;
		else if( InitRecordDMA() != 0 ) 
			error = 4;
	}
	if( !error )
	{
		PlayCmdEvent = CreateEvent( NULL , 0 , 0, NULL );
		RecordCmdEvent = CreateEvent( NULL , 0 , 0, NULL );
		if( !PlayCmdEvent || !RecordCmdEvent )
			error = 7;
	}
	if( !error )
	{
		DmaThread  = CreateThread( NULL, 0, AudioDMAThread, NULL, 0, NULL);
		if( !DmaThread  )
			error = 5;
		else
			SetThreadPriority( DmaThread , THREAD_PRIORITY_ABOVE_NORMAL );
	}
	if( !error )
	{
		DmaRecordThread  = CreateThread( NULL, 0, AudioRecordThread , NULL, 0, NULL);
		if( !DmaRecordThread )
			error = 6;
//		else
//			SetThreadPriority( DmaRecordThread , THREAD_PRIORITY_ABOVE_NORMAL );		
	}
	if( error )
		RETAILMSG( (DebugMsgMask&DebugMsg_Normal), (TEXT("InitAll : %d\r\n") , error));
	
	return error;
}

static unsigned char* PlayBuffer = 0;
static unsigned int PlayBuffer_phy;

static const int TotalPlayBufferSize = 0x1000 * 10;

static int PlayBufferBlockSize = 0;

void StoreRecordBuffer()
{
	recordcount ++;
	if( (recordcount%100 ) == 0 )
		RETAILMSG( 1 , (TEXT("StoreRecordBuffer %d %d %d\r\n") , recordcount , recordedcount , recordcount-recordedcount));
	AddDebugMsg( "store record buffer %d %d %x\n", recordcount, recordedcount , DmaRecordEvent );
	if( WaitRecordBuffer )
		SetEvent( RecordCmdEvent );	
}

void StorePlayBuffer( char*buf , int size)
{	
	int notify = 0;
	if( DMAPlayCmd != DMA_PLAY_START )
		return ;
	if( TotalPlayBufferCnt == 0 )
	{
		RETAILMSG( (DebugMsgMask&DebugMsg_Trace) , (TEXT("AACI : DMA : first store\r\n")));
		PlayBufferBlockSize = size;
		TotalPlayBufferCnt = TotalPlayBufferSize / max( size , 0x1000 );		
	}
	
	memcpy( PlayBuffer + PlayBufferBlockSize*PlayBufferStoreIndex , buf , size );
	playcount ++;
	if( (playcount%100 ) == 0 )
		RETAILMSG( 1 , (TEXT("StorePlayBuffer %d %d %d\r\n") , playcount , playedcount , playcount-playedcount));
	AddDebugMsg( "store play buffer %d %d %d %x\n" , PlayBufferStoreIndex , playcount , playedcount , DmaPlayEvent );
	if( PlayBufferStoreIndex == PlayBufferPlayIndex )
		notify = 1;
	PlayBufferStoreIndex = (PlayBufferStoreIndex+1) % TotalPlayBufferCnt;	
	if( WaitPlayBuffer )
		SetEvent( PlayCmdEvent );
}
void GetPlayBuffer( unsigned int *buf )
{
	*buf = PlayBuffer_phy + PlayBufferPlayIndex*PlayBufferBlockSize;
	PlayBufferPlayIndex = ( PlayBufferPlayIndex+1 ) % TotalPlayBufferCnt;
}

int StartPlayDMA( unsigned int bufphy, int size ,  int* actualbuffered )
{	
	int error = 0;
	DWORD FIFOAddr = 0x20037090 , dwRet;
	START_DMA_PARAMS    StartDMAParams;
	
	StartDMAParams.ucChannelNumber = (unsigned char)PlayDMAChannelNumber;	
	StartDMAParams.pdwSourceBuffer = &bufphy;
	StartDMAParams.pdwDestBuffer = &FIFOAddr;
	StartDMAParams.dwTransferSize = size;	
	
	if ( !KernelIoControl(	HAL_IOCTL_AACI_DMA , &StartDMAParams, sizeof(StartDMAParams),
								actualbuffered, sizeof(int), &dwRet))
	{
		error = 1;
		RETAILMSG( (DebugMsgMask&DebugMsg_Important ), (TEXT("aaci : Start dma error\r\n" )));
	}
	return error;
}

int ReleasePlayDMA(void)
{
	int error = 0;
	DWORD dwRet;
	if( PlayDMAChannelNumber >= 0 && PlayDMAChannelNumber <= 7 )
	{
		FREE_DMA_PARAMS FreeDMAParams;
		FREE_DMA_RESULT FreeDMAResult;
		FreeDMAParams.ucChannelNumber = PlayDMAChannelNumber;
		if (!KernelIoControl(IOCTL_HAL_FREE_DMA_CHANNEL,
			&FreeDMAParams, sizeof(FreeDMAParams),
			&FreeDMAResult, sizeof(FreeDMAResult), &dwRet))
		{
			error = 1;
		}
	}
	if( DmaPlayEvent )
		CloseHandle( DmaPlayEvent );
	if( PlayDmaIntID )
		InterruptDisable( PlayDmaIntID );
	if( PlayBuffer )
		FreePhysMem(PlayBuffer);
	
	PlayBuffer = 0;
	return error;
}

int InitPlayDMA()
{		
	int error = 0;
	unsigned long dwRet = 0;
	
	INITIALIZE_DMA_PARAMS InitializeDMAParams;
	INITIALIZE_DMA_RESULT InitializeDMAResult;
	InitializeDMAParams.ucChannelNumber = PlayDMAChannelNumber;
	InitializeDMAParams.ucSourceWidth = TRANSFER_WIDTH_WORD; 
	InitializeDMAParams.ucDestWidth = TRANSFER_WIDTH_WORD; 
	InitializeDMAParams.ucSourceBurstSize = BURST_SIZE_64; 
	InitializeDMAParams.ucDestBurstSize = BURST_SIZE_64;
	InitializeDMAParams.fIncrementSource = TRUE;	//source - auto increment
	InitializeDMAParams.fIncrementDest = FALSE;		//dest - constant
	InitializeDMAParams.ucFlowControl = FLOW_MEM_PER_DMAC;
	
	if (!KernelIoControl(IOCTL_HAL_INITIALIZE_DMA_CHANNEL,
		&InitializeDMAParams, sizeof(InitializeDMAParams),
		&InitializeDMAResult, sizeof(InitializeDMAResult), &dwRet))
	{
		error = 1;
	}
	
	return error;
}

int AllocPlayDMA(void)
{
	int error = 0;
	unsigned long dwRet = 0;
	
	PlayBuffer = AllocPhysMem( TotalPlayBufferSize, PAGE_READWRITE, 0, 0, &PlayBuffer_phy );
    if( !PlayBuffer )
		error = 1;
	if( !error )
	{
		ALLOCATE_DMA_PARAMS AllocateDMAParams;
		ALLOCATE_DMA_RESULT AllocateDMAResult;
		AllocateDMAParams.ucSourceDevice = 0;
		AllocateDMAParams.ucDestDevice = 14;
		AllocateDMAParams.ucPreferedPriority = 0xff;    // no preference
		if (!KernelIoControl(IOCTL_HAL_ALLOCATE_DMA_CHANNEL,
			&AllocateDMAParams, sizeof(AllocateDMAParams),
			&AllocateDMAResult, sizeof(AllocateDMAResult), &dwRet))
		{
			error = 2;			
		}
		PlayDMAChannelNumber = AllocateDMAResult.ucChannelNumber;
		PlayDmaIntID = AllocateDMAResult.dwInterruptID;
	}		
	if( !error )
	{
		DmaPlayEvent = CreateEvent( NULL, 0 , 0 , NULL );		
		if( DmaPlayEvent )
		{
			if (!InterruptInitialize( PlayDmaIntID , DmaPlayEvent , NULL, 0))
				error = 4;
		}
		else
			error = 5;
	}
	if( error )
		RETAILMSG( (DebugMsgMask&DebugMsg_Important ), (TEXT( "AACI : AllocPlayDMA : %d\r\n" ) , error ));
	return error;
}


int ReleaseRecordDMA(void)
{
	int error = 0;
	DWORD dwRet;
	if( RecordDMAChannelNumber >= 0 && RecordDMAChannelNumber <= 7 )
	{
		FREE_DMA_PARAMS FreeDMAParams;
		FREE_DMA_RESULT FreeDMAResult;
		FreeDMAParams.ucChannelNumber = RecordDMAChannelNumber;
		if (!KernelIoControl(IOCTL_HAL_FREE_DMA_CHANNEL,
			&FreeDMAParams, sizeof(FreeDMAParams),
			&FreeDMAResult, sizeof(FreeDMAResult), &dwRet))
		{
			error = 1;
		}
	}
	if( DmaRecordEvent )
		CloseHandle( DmaRecordEvent );
	if( RecordDmaIntID )
		InterruptDisable( RecordDmaIntID );
	return error;
}

int StartRecordDMA( LPSTR buffer , DWORD size , int* actualbuffered)
{	
	int error = 0;
	static DWORD pages[0x1000];
	DWORD FIFOAddr = 0x20037090 , dwRet;
	START_DMA_PARAMS    StartDMAParams;
	
	LockPages( buffer , size , pages , LOCKFLAG_READ|LOCKFLAG_WRITE );
//	LockPages( PlayBuffer , PAGE_SIZE*10 , pages , LOCKFLAG_READ|LOCKFLAG_WRITE );
	
	pages[0] = (pages[0]&(~0xfff)) | ((DWORD)buffer&0xfff);

	StartDMAParams.ucChannelNumber = (unsigned char)RecordDMAChannelNumber;	
	StartDMAParams.pdwSourceBuffer = &FIFOAddr;
	StartDMAParams.pdwDestBuffer = pages;
	StartDMAParams.dwTransferSize = size;	
	
	if ( !KernelIoControl(	HAL_IOCTL_AACI_DMA , &StartDMAParams, sizeof(StartDMAParams),
								actualbuffered, sizeof(int), &dwRet))
	{
		error = 1;
		RETAILMSG( (DebugMsgMask&DebugMsg_Important ), (TEXT("aaci : Start dma error\r\n" )));
	}
	return error;
}

int InitRecordDMA()
{		
	int error = 0;
	unsigned long dwRet = 0;
	
	INITIALIZE_DMA_PARAMS InitializeDMAParams;
	INITIALIZE_DMA_RESULT InitializeDMAResult;
	InitializeDMAParams.ucChannelNumber = RecordDMAChannelNumber;
	InitializeDMAParams.ucSourceWidth = TRANSFER_WIDTH_WORD; 
	InitializeDMAParams.ucDestWidth = TRANSFER_WIDTH_WORD; 
	InitializeDMAParams.ucSourceBurstSize = BURST_SIZE_64; 
	InitializeDMAParams.ucDestBurstSize = BURST_SIZE_64;
	InitializeDMAParams.fIncrementSource = FALSE;
	InitializeDMAParams.fIncrementDest = TRUE;	
	InitializeDMAParams.ucFlowControl = FLOW_PER_MEM_DMAC;
	
	if (!KernelIoControl(IOCTL_HAL_INITIALIZE_DMA_CHANNEL,
		&InitializeDMAParams, sizeof(InitializeDMAParams),
		&InitializeDMAResult, sizeof(InitializeDMAResult), &dwRet))
	{
		error = 1;
	}
	
	return error;
}

int AllocRecordDMA(void)
{
	int error = 0;
	unsigned long dwRet = 0;
	
	if( !error )
	{
		ALLOCATE_DMA_PARAMS AllocateDMAParams;
		ALLOCATE_DMA_RESULT AllocateDMAResult;
		AllocateDMAParams.ucSourceDevice = 13;
		AllocateDMAParams.ucDestDevice = 0;
		AllocateDMAParams.ucPreferedPriority = 0xff;    // no preference
		if (!KernelIoControl(IOCTL_HAL_ALLOCATE_DMA_CHANNEL,
			&AllocateDMAParams, sizeof(AllocateDMAParams),
			&AllocateDMAResult, sizeof(AllocateDMAResult), &dwRet))
		{
			error = 2;			
		}
		RecordDMAChannelNumber = AllocateDMAResult.ucChannelNumber;
		RecordDmaIntID = AllocateDMAResult.dwInterruptID;
	}		
	if( !error )
	{
		DmaRecordEvent = CreateEvent( NULL, 0 , 0 , NULL );		
		if( DmaRecordEvent )
		{
			if (!InterruptInitialize( RecordDmaIntID , DmaRecordEvent , NULL, 0))
				error = 4;
		}
		else
			error = 5;
	}
	if( error )
		RETAILMSG( (DebugMsgMask&DebugMsg_Important ), (TEXT( "AACI : AllocPlayDMA : %d\r\n" ) , error ));
	return error;
}

⌨️ 快捷键说明

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