📄 aaci_dma.c
字号:
#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 , ¶m1 , sizeof(int) , ¶m2 , 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 , ¶m1 , sizeof(int) , ¶m2 , 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 + -