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

📄 aaci_dma.c_zq

📁 此压缩包为杰得开发得z228的BSP的源代码,可以实现很多功能,尤其是视频解码有很好的效果.
💻 C_ZQ
📖 第 1 页 / 共 2 页
字号:
#include <windows.h>
#include <pkfuncs.h>
#include <ceddk.h>
#include <oalfuncs.h>
#include <dma.h>
#include "oalintr.h"
#include "wavemdd.h"
#include "pdd_audio.h"
#define DebugMsg_Normal 0x00
#define DebugMsg_Important 0x02
#define DebugMsg_Trace	0x04
#define DebugMsgMask (DebugMsg_Important|DebugMsg_Normal)

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 PlayCmdEvent = 0;
static volatile int WaitPlayBuffer = 0;
static HANDLE DmaRecordEvent = 0;
static HANDLE RecordCmdEvent = 0;
static volatile int WaitRecordBuffer = 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 RecordTempCnt 4
#define RecordTempSize 0x1000
#define MinRecordSize 160
static char RecordTemp[RecordTempCnt][RecordTempSize];
static int  RecordSize[RecordTempCnt];
static int RecordIndex = 0;
static int RecordUsedIndex = 0;


WAVEFORMATEX	RecordFormat;

static int playcount = 0;
static int playedcount = 0;
int InRemove = 0;

static int recordcount = 0;
static int recordedcount = 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

static int RecordOver = 0;

static char DebugMsg[1024*512];
static int MsgLength = 0;
CRITICAL_SECTION Critical;

static void StartDebugMsg()
{
	MsgLength = 0;
	memset( DebugMsg , 0 , sizeof(DebugMsg) );
}

static void EndDebugMsg()
{
	return;
	EnterCriticalSection( &Critical );
	if( MsgLength )
	{
		char temp[256];
		FILE* fp;
		sprintf( temp , "save %d" , MsgLength );
		fp = fopen( temp , "wb" );
		if( fp )
		{
			fwrite( DebugMsg + MsgLength , 1 , sizeof(DebugMsg)-MsgLength , fp );
			fwrite( DebugMsg , 1 , MsgLength , fp );
			fclose( fp );
		}
		MsgLength = 0;
	}
	LeaveCriticalSection( &Critical );
}
static void AddDebugMsg( char* fmt, ... )
{
	char temp[256];
	int length;
	va_list args;
	return;
	EnterCriticalSection( &Critical );	
	va_start(args, fmt);
	vsprintf( temp , fmt , args);
	length = strlen( temp );
	if( MsgLength + length >= sizeof(DebugMsg) )
		MsgLength = 0;
	{
		memcpy( DebugMsg+MsgLength , temp , length );
		MsgLength += length;
		DebugMsg[MsgLength++] = '\0';
	}
	LeaveCriticalSection( &Critical );
}

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;
	}
	InitializeCriticalSection( &Critical );
	return error;
}

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

int OnRecordOpen()
{
	int error = 0;
	DMARecordCmd = DMA_RECORD_STOP;	
	recordcount = recordedcount = 0;
	RecordIndex = RecordOver = 0;
	StartDebugMsg();
	//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" ) ));
	RecordIndex = RecordUsedIndex = 0;	
	SetEvent( RecordCmdEvent );
	return error;
}
int OnRecordStop()
{
	int error = 0;
	DMARecordCmd = DMA_RECORD_STOP;
	return error;
}

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

int OnPlayOpen()
{
	int error = 0;
	PlayBufferPlayIndex = PlayBufferStoreIndex = 0;
	DMAPlayCmd = DMA_PLAY_START;	
	playcount = playedcount = 0;
	StartDebugMsg();
	//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;
	MsgLength = 0;
	SetEvent( PlayCmdEvent );
	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 )
		{		
			memcpy( g_pwh->lpData + g_pwh->dwBytesRecorded , 
				RecordTemp[ RecordUsedIndex ] , 
				RecordSize[ RecordUsedIndex ] );
			g_pwh->dwBytesRecorded += RecordSize[ RecordUsedIndex ];
			RecordUsedIndex = (RecordUsedIndex+1)%RecordTempCnt;
			if( g_pwh->dwBytesRecorded == g_pwh->dwBufferLength )
			{
				MARK_BUFFER_DONE(g_pwh);
				g_pwh->reserved = 0;
				g_pwh = g_pwh->lpNext;
				recordedcount ++;
				if( recordcount == recordedcount )
					RETAILMSG( 1 , (TEXT("record buffer over")));
			}
		}
		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;
			playedcount ++;
		}
		MarkFullAsDone(WAPI_OUT);
		InRemove = 1;
		RemoveCompleteBlocks(WAPI_OUT);						
		InRemove = 0;
	}
	else
	{
		AddDebugMsg( "play not started\n" );
		error = 1;
	}
	UNLOCK_GSI(WAPI_OUT);
	return error;
}


/*

typedef struct tWAVEFORMATEX
{
    WORD        wFormatTag;          format type/
    WORD        nChannels;         number of channels (i.e. mono, stereo...)
    DWORD       nSamplesPerSec;      sample rate 
    DWORD       nAvgBytesPerSec;    /* for buffer estimation 
    WORD        nBlockAlign;        /* block size of data 
    WORD        wBitsPerSample;     /* number of bits per sample of mono data 
    WORD        cbSize;             /* the count in bytes of the size of 
                    /* extra information (after cbSize) 
} WAVEFORMATEX, *PWAVEFORMATEX, NEAR *NPWAVEFORMATEX, FAR *LPWAVEFORMATEX;

*/
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 == g_pwh->dwBufferLength || g_pwh->reserved == g_pwh->dwBufferLength) )
			g_pwh = g_pwh->lpNext;
		if( g_pwh )
		{
			DWORD size = g_pwh->dwBufferLength - g_pwh->reserved;
			DWORD torecord;
//#define RecordTempSize 0x1000
//#define MinRecordSize 160
			if( size <= RecordTempSize )
				torecord = size;
			else if( size < RecordTempSize + MinRecordSize )
				torecord = size / 2;
			else 
				torecord = RecordTempSize;			
			torecord = (torecord/RecordFormat.nBlockAlign)*RecordFormat.nBlockAlign;//把数据取成BLOCK的整数倍
			//StartRecordDMA( g_pwh->lpData , g_pwh->dwBufferLength , left );
 			StartRecordDMA( RecordTemp[RecordIndex] , torecord , left );
 			RecordSize[RecordIndex] = torecord;
			g_pwh->reserved += torecord;
			RecordIndex = (RecordIndex+1)%RecordTempCnt;

			if( g_pwh->lpNext || g_pwh->reserved < g_pwh->dwBufferLength )
				*morebuffer = 1;
			else
				*morebuffer = 0;

			RETAILMSG( (DebugMsgMask&DebugMsg_Trace)  , (TEXT("g_pwh->reserved  ---morebuffer   : %d,%d \r\n") , g_pwh->reserved,morebuffer));
			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;
}

/*

/* wave data block header 
typedef struct wavehdr_tag {
    LPSTR       lpData;                 /* pointer to locked data buffer 
    DWORD       dwBufferLength;         /* length of data buffer 
    DWORD       dwBytesRecorded;        /* used for input only 
    DWORD       dwUser;                 /* for client's use 
    DWORD       dwFlags;                /* assorted flags (see defines) 
    DWORD       dwLoops;                /* loop control counter 
    struct wavehdr_tag FAR *lpNext;     /* reserved for driver 
    DWORD       reserved;               /* reserved for driver 
} WAVEHDR, *PWAVEHDR, NEAR *NPWAVEHDR, FAR *LPWAVEHDR;
*/
//DWORD size = g_pwh->dwBufferLength - g_pwh->reserved;
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;
}

int OnPlayDmaFail()
{
	{
		GET_ERROR_PARAMS p;
		GET_ERROR_RESULT r;
		KernelIoControl( IOCTL_HAL_GET_ERROR_STATUS , &p , sizeof(GET_ERROR_PARAMS) , &r , sizeof(GET_ERROR_RESULT) , 0);
		RETAILMSG( 1 , (TEXT("OnPlayDmaFail %x\r\n" ) , r.ucErrorStatus ));	
	}
	{
		CLEAR_ERROR_PARAMS p;
		CLEAR_ERROR_RESULT r;
		KernelIoControl( IOCTL_HAL_CLEAR_ERROR_STATUS, &p , sizeof(CLEAR_ERROR_PARAMS) , &r , sizeof(CLEAR_ERROR_RESULT) , 0);
	}
	{
		int param1 = 1 , param2 = 0;
		KernelIoControl( HAL_IOCTL_AACI_CLEARSTATUS , &param1 , sizeof(int) , &param2 , sizeof(int) , 0);
	}
	return 0;
}
int OnRecordDmaFail()
{
	{
		GET_ERROR_PARAMS p;
		GET_ERROR_RESULT r;
		KernelIoControl( IOCTL_HAL_GET_ERROR_STATUS , &p , sizeof(GET_ERROR_PARAMS) , &r , sizeof(GET_ERROR_RESULT) , 0);
		RETAILMSG( 1 , (TEXT("OnRecordDmaFail %x\r\n" ) , r.ucErrorStatus ));	
	}
	{
		CLEAR_ERROR_PARAMS p;
		CLEAR_ERROR_RESULT r;
		KernelIoControl( IOCTL_HAL_CLEAR_ERROR_STATUS, &p , sizeof(CLEAR_ERROR_PARAMS) , &r , sizeof(CLEAR_ERROR_RESULT) , 0);
	}
	{
		int param1 = 0 , param2 = 1;
		KernelIoControl( HAL_IOCTL_AACI_CLEARSTATUS , &param1 , sizeof(int) , &param2 , sizeof(int) , 0);
	}
	return 0;
}
#define RecordBufferCount 1
//#define RecordBufferCount 2
DWORD AudioRecordThread( LPVOID p )
{
	int leftrecordblock = 0 , bufferedrecordblock = 0 , moreinputblock = 0 , error = 0;
	int loopcount = 0  ,temp;
	SetProcPermissions( 0xFFFFFFFF );
	RETAILMSG( (DebugMsgMask&DebugMsg_Important ), (TEXT( "AACI : DMA : Enter record Thread\r\n" ) ));



	while( !error && DMARecordCmd != DMA_RECORD_EXIT )
	{
		if( (loopcount++%1000) == 0 )
		RETAILMSG(  (DebugMsgMask&DebugMsg_Trace) , (TEXT("AudioRecordThread loop %d\r\n" ) , bufferedrecordblock ));		
		//如果 DMARecordCmd == DMA_RECORD_STOP则清除DMA状态 
		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" ) ));
		}

		//如果当前为DMARecordCmd == DMA_RECORD_STOP   或则没有更多的录音需求则等待
		if(  DMARecordCmd == DMA_RECORD_STOP || moreinputblock == 0  )//
		{
			WaitRecordBuffer = 1;
			WaitForSingleObject( RecordCmdEvent , INFINITE );//等待有录音需求来唤醒
			WaitRecordBuffer = 0;
		}
		if( bufferedrecordblock && ( bufferedrecordblock == RecordBufferCount||moreinputblock==0) )
		{
			if( WaitForSingleObject( DmaRecordEvent , INFINITE ) == 0 )
				InterruptDone( RecordDmaIntID );
			AddDebugMsg( "wait record dma over\n" );
		}
		if( (DMARecordCmd != DMA_RECORD_START) )
			continue;
		
		RETAILMSG( (DebugMsgMask&DebugMsg_Trace)  , (TEXT( "AACI : DMA : start work\r\n" ) ));
		AddDebugMsg( "to get record status \n" );
		//获取当前kernel中没有准备好数据的buff 数量
		KernelIoControl( HAL_IOCTL_AACI_GETBUFFER , &temp , sizeof(int) , &leftrecordblock , sizeof(int) , 0);
		AddDebugMsg("get record status %d %d %d\n" , leftrecordblock, bufferedrecordblock , temp);
		if( DMARecordCmd == DMA_RECORD_START )
			//bufferedrecordblock    当前kernel中有的buff数量
			//leftrecordblock   当前kernel中没有准备好数据的buff数量

⌨️ 快捷键说明

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