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

📄 aaci_dma.c

📁 ARM9基于WINDOWSCE的BSP源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
#include <windows.h>
#include <pkfuncs.h>
#include <ceddk.h>
#include <oalfuncs.h>
#include <dma.h>
#include "oalintr.h"
#include "wavemdd.h"

#define DebugMsg_Normal 0x01
#define DebugMsg_Important 0x02
#define DebugMsg_Trace	0x04
#define DebugMsgMask (DebugMsg_Important)

int ReleasePlayDMA(void);
int InitPlayDMA();
int AllocPlayDMA(void);
void GetPlayBuffer( unsigned int *buf );
int InitAll();
int StartPlayDMA( unsigned int bufphy, int size ,  int* actualbuffered );
int ReleaseAll();
int AllocRecordDMA(void);
int InitRecordDMA(void);
int StartRecordDMA( LPSTR buffer , DWORD size , int* actualbuffered);
DWORD AudioDMAThread(LPVOID p);

static HANDLE DmaPlayEvent = 0;
static HANDLE DmaRecordEvent = 0;
static volatile int DMAPlayCmd;
static volatile int DMARecordCmd;
static int TotalPlayBufferCnt = 0;
static volatile int PlayBufferPlayIndex = 0;
static volatile int PlayBufferStoreIndex = 0;

static int PlayDMAChannelNumber = -1;
static int PlayDmaIntID = 0;
static int RecordDMAChannelNumber = -1;
static int RecordDmaIntID = 0;
static HANDLE DmaThread = 0;
static HANDLE DmaRecordThread = 0;

#define DMA_PLAY_STOP  0
#define DMA_PLAY_START 1
#define DMA_PLAY_EXIT  2

#define DMA_RECORD_STOP  0
#define DMA_RECORD_START 1
#define DMA_RECORD_EXIT  2

int OnInit()
{
	int error = 0;
	if( InitAll() != 0 )
		error = 1;
	if( error )
	{
		DMAPlayCmd = DMA_PLAY_EXIT;
		DMARecordCmd = DMA_RECORD_EXIT;
	}
	else
	{
		DMAPlayCmd = DMA_PLAY_STOP;
		DMARecordCmd = DMA_RECORD_STOP;
	}
	return error;
}

int OnDeinit()
{
	int error = 0;	
	ReleaseAll();
	return error;
}

int OnRecordOpen()
{
	int error = 0;
	DMARecordCmd = DMA_RECORD_STOP;	
	RETAILMSG( (DebugMsgMask&DebugMsg_Normal) , (TEXT( "OnRecordOpen\r\n" ) ));
	return error;
}
int OnRecordStart()
{
	int error = 0;
	DMARecordCmd = DMA_RECORD_START;
	RETAILMSG( (DebugMsgMask&DebugMsg_Normal), (TEXT( "OnRecordStart\r\n" ) ));
	SetEvent( DmaRecordEvent );
	return error;
}
int OnRecordStop()
{
	int error = 0;
	DMARecordCmd = DMA_RECORD_STOP;
	return error;
}

int OnRecordClose()
{
	int error = 0;
	DMARecordCmd = DMA_RECORD_STOP;
	SetEvent( DmaRecordEvent );
	RETAILMSG( (DebugMsgMask&DebugMsg_Normal), (TEXT( "OnRecordClose\r\n" ) ));
	return error;
}

int OnPlayOpen()
{
	int error = 0;
	PlayBufferPlayIndex = PlayBufferStoreIndex = 0;
	DMAPlayCmd = DMA_PLAY_START;	
	RETAILMSG( (DebugMsgMask&DebugMsg_Normal), (TEXT( "OnPlayOpen\r\n" ) ));
	return error;
}

int OnPlayStart()
{
	int error = 0;
	DMAPlayCmd = DMA_PLAY_START;
	RETAILMSG( (DebugMsgMask&DebugMsg_Normal), (TEXT( "OnPlayStart\r\n" ) ));
	return error;
}
int OnPlayStop()
{
	int error = 0;
	DMAPlayCmd = DMA_PLAY_STOP;
	SetEvent( DmaPlayEvent );
	return error;
}
int OnPlayClose()
{
	int error = 0;
	DMAPlayCmd = DMA_PLAY_STOP;
	RETAILMSG( (DebugMsgMask&DebugMsg_Normal), (TEXT( "OnPlayClose\r\n" ) ));
	return error;
}

int RemoveRecordBuffer( int toremove )
{
	PWAVEHDR g_pwh;
	int error = 0;
	LOCK_GSI(WAPI_IN);
	if( gsi[WAPI_IN].bStarted == TRUE )
	{				
		g_pwh = gsi[WAPI_IN].pwh;				
		while( g_pwh && g_pwh->dwBytesRecorded == g_pwh->dwBufferLength)
			g_pwh = g_pwh->lpNext;
		while( toremove-- && g_pwh )
		{				
			g_pwh->dwBytesRecorded = g_pwh->dwBufferLength;
			g_pwh = g_pwh->lpNext;
		}
		MarkFullAsDone(WAPI_IN);
		RemoveCompleteBlocks(WAPI_IN);						
	}
	else
	{
		error = 1;
	}
	UNLOCK_GSI(WAPI_IN);
	return error;
}


int RemovePlayBuffer( int toremove )
{
	PWAVEHDR g_pwh;
	int error = 0;
	LOCK_GSI(WAPI_OUT);
	if( gsi[WAPI_OUT].bStarted == TRUE )
	{				
		g_pwh = gsi[WAPI_OUT].pwh;				
		while( g_pwh && g_pwh->dwBytesRecorded == g_pwh->dwBufferLength)
			g_pwh = g_pwh->lpNext;
		while( toremove-- && g_pwh )
		{				
			g_pwh->dwBytesRecorded = g_pwh->dwBufferLength;
			g_pwh = g_pwh->lpNext;
		}
		MarkFullAsDone(WAPI_OUT);
		RemoveCompleteBlocks(WAPI_OUT);						
	}
	else
	{
		error = 1;
	}
	UNLOCK_GSI(WAPI_OUT);
	return error;
}

int AddRecordBuffer( int* left , int* morebuffer)
{
	PWAVEHDR g_pwh;
	int error = 0;
	LOCK_GSI(WAPI_IN);
	if( gsi[WAPI_IN].bStarted == TRUE )
	{
		g_pwh = gsi[WAPI_IN].pwh;				
		while( g_pwh && g_pwh->dwBytesRecorded != 0)
			g_pwh = g_pwh->lpNext;
		if( g_pwh )
		{
			StartRecordDMA( g_pwh->lpData , g_pwh->dwBufferLength , left );
			g_pwh->dwBytesRecorded = g_pwh->dwBufferLength/2;
			if( g_pwh->lpNext )
				*morebuffer = 1;
			else
				*morebuffer = 0;
			RETAILMSG( (DebugMsgMask&DebugMsg_Trace) , (TEXT("aaci : addrecord : %x , %x\r\n")  ,g_pwh->lpData , g_pwh->dwBufferLength));
		}
		else
		{
			error = 2;
			*morebuffer = 0;
		}
	}
	else
	{
		//DMARecordCmd = DMA_RECORD_STOP;
		error = 1;
	}
	UNLOCK_GSI(WAPI_IN);
	return error;
}

int AddPlayBuffer( int* left )
{
	PWAVEHDR g_pwh;
	int error = 0;
	LOCK_GSI(WAPI_OUT);
	if( gsi[WAPI_OUT].bStarted == TRUE )
	{
		g_pwh = gsi[WAPI_OUT].pwh;				
		while( g_pwh && g_pwh->dwBytesRecorded != 0)
			g_pwh = g_pwh->lpNext;
		if( g_pwh )
		{
			DWORD bufphy;
			int size = g_pwh->dwBufferLength;
			g_pwh->dwBytesRecorded = size/2;					
			GetPlayBuffer( &bufphy );
			StartPlayDMA( bufphy , size , left );
		}
		else
			error = 2;
	}
	else
	{
	//	DMAPlayCmd = DMA_PLAY_STOP;
		error = 1;
	}
	UNLOCK_GSI(WAPI_OUT);
	return error;
}

DWORD AudioRecordThread( LPVOID p )
{
	int leftrecordblock = 0 , bufferedrecordblock = 0 , moreinputblock = 0 , error = 0;
	SetProcPermissions( 0xFFFFFFFF );
	RETAILMSG( (DebugMsgMask&DebugMsg_Important ), (TEXT( "AACI : DMA : Enter record Thread\r\n" ) ));
	while( !error && DMARecordCmd != DMA_RECORD_EXIT )
	{
		if( DMARecordCmd == DMA_RECORD_STOP )
		{
			int param1 = 0 , param2 = 1;
			KernelIoControl( HAL_IOCTL_AACI_CLEARSTATUS , &param1 , sizeof(int) , &param2 , sizeof(int) , 0);
			bufferedrecordblock = 0;
			RETAILMSG( (DebugMsgMask&DebugMsg_Trace) , (TEXT( "AACI : record : stoped \r\n" ) ));
		}
		
		if(  DMARecordCmd == DMA_RECORD_STOP || bufferedrecordblock == 21 || moreinputblock == 0 )
		{
			RETAILMSG( (DebugMsgMask&DebugMsg_Trace) , (TEXT( "AACI : record : wait %d %d\r\n" ), bufferedrecordblock , moreinputblock ));
			WaitForSingleObject( DmaRecordEvent , INFINITE );			
		}
		if( (DMARecordCmd != DMA_RECORD_START) )
			continue;
		RETAILMSG( (DebugMsgMask&DebugMsg_Trace) , (TEXT( "AACI : DMA : start work\r\n" ) ));
		KernelIoControl( HAL_IOCTL_AACI_GETBUFFER , 0 , 0 , &leftrecordblock , sizeof(int) , 0);
		
		if( DMARecordCmd == DMA_RECORD_START )
			if( (leftrecordblock!=bufferedrecordblock) || bufferedrecordblock < 2) 
			{
				RETAILMSG( (DebugMsgMask&DebugMsg_Trace) , (TEXT("aaci : to add buffer %d %d\r\n") , bufferedrecordblock, leftrecordblock ));				
				if( AddRecordBuffer( &leftrecordblock , &moreinputblock ) == 0 )
					bufferedrecordblock ++;
				if( moreinputblock == 0 )
					RETAILMSG( (DebugMsgMask&DebugMsg_Normal), (TEXT("aaci : record : no more input block\r\n" )));
			}
				
		if( leftrecordblock < bufferedrecordblock )
		{
			int toremove = bufferedrecordblock - leftrecordblock;
			RETAILMSG( (DebugMsgMask&DebugMsg_Normal), (TEXT( "AACI : remove record buffer %d %d\r\n" ) , bufferedrecordblock , leftrecordblock));
			if( RemoveRecordBuffer( toremove ) == 0 )
				bufferedrecordblock = leftrecordblock;
			InterruptDone( RecordDmaIntID );
		}	
	}
	RETAILMSG( (DebugMsgMask&DebugMsg_Important ), (TEXT( "AACI : DMA : leave record Thread\r\n" ) ));
	return 0;
}

DWORD AudioDMAThread(LPVOID p)
{
	int error = 0 , bufferedplayingblock = 0 , leftplayingblock = 0 , storedblock = 0;
	RETAILMSG( (DebugMsgMask&DebugMsg_Important ), (TEXT( "AACI : DMA : Enter Thread\r\n" ) ));
	while( !error &&  DMAPlayCmd != DMA_PLAY_EXIT  )
	{
		RETAILMSG( (DebugMsgMask&DebugMsg_Trace) , (TEXT( "AACI : DMA : loop begin\r\n" ) ));
		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 || bufferedplayingblock == 2 || storedblock == 0 )	)// buffer full or store empty, wait
		{
			RETAILMSG( (DebugMsgMask&DebugMsg_Trace) , (TEXT( "AACI : : wait %d %d\r\n" ), bufferedplayingblock , storedblock));
			WaitForSingleObject( DmaPlayEvent , INFINITE );			
		}
		if( (DMAPlayCmd != DMA_PLAY_START)  )
			continue;
		RETAILMSG( (DebugMsgMask&DebugMsg_Trace) , (TEXT( "AACI : DMA : start work\r\n" ) ));
		if( PlayBufferStoreIndex >= PlayBufferPlayIndex)
			storedblock = PlayBufferStoreIndex - PlayBufferPlayIndex;
		else
			storedblock = TotalPlayBufferCnt - PlayBufferPlayIndex + PlayBufferStoreIndex;		
		
		KernelIoControl( HAL_IOCTL_AACI_GETBUFFER , &leftplayingblock , sizeof(int) , 0,0  , 0);

		if( DMAPlayCmd == DMA_PLAY_START )
		if( ((leftplayingblock < bufferedplayingblock) || bufferedplayingblock < 2) && storedblock > 0 )
		{	// add buffer			
			if( AddPlayBuffer( &leftplayingblock ) == 0 )
			{
				bufferedplayingblock ++;
				storedblock	-- ;			
			}
		}	
		
		if( leftplayingblock < bufferedplayingblock )

⌨️ 快捷键说明

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