📄 aaci_dma.c
字号:
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;
}
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;
if( size <= RecordTempSize )
torecord = size;
else if( size < RecordTempSize + MinRecordSize )
torecord = size / 2;
else
torecord = RecordTempSize;
torecord = (torecord/RecordFormat.nBlockAlign)*RecordFormat.nBlockAlign;
//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("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;
}
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 , ¶m1 , sizeof(int) , ¶m2 , 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 , ¶m1 , sizeof(int) , ¶m2 , sizeof(int) , 0);
}
return 0;
}
#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" ) ));
if(0)
{
int time = GetTickCount() ;
if( (loopcount++%1000) == 0 )
RETAILMSG( 1 , (TEXT("AudioRecordThread loop %d\r\n" ) , bufferedrecordblock ));
while( !error && DMARecordCmd != DMA_RECORD_EXIT )
{
if( (loopcount++%1000) == 0 )
RETAILMSG( 1 , (TEXT("AudioRecordThread loop %d\r\n" ) , bufferedrecordblock ));
if( DMARecordCmd == DMA_RECORD_STOP || moreinputblock == 0 )
WaitForSingleObject( DmaRecordEvent , INFINITE );
if( (DMARecordCmd != DMA_RECORD_START) )
continue;
if( AddRecordBuffer( &leftrecordblock , &moreinputblock ) == 0 )
{
while( GetTickCount() - time < 20 )
{
Sleep( 5 );
}
time = GetTickCount();
RemoveRecordBuffer(1);
}
}
}
while( !error && DMARecordCmd != DMA_RECORD_EXIT )
{
if( (loopcount++%1000) == 0 )
RETAILMSG( 1 , (TEXT("AudioRecordThread loop %d\r\n" ) , bufferedrecordblock ));
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 || ( moreinputblock == 0 && bufferedrecordblock == 0 ))
{
WaitRecordBuffer = 1;
WaitForSingleObject( RecordCmdEvent , INFINITE );
WaitRecordBuffer = 0;
}
if( bufferedrecordblock && ( bufferedrecordblock == RecordBufferCount||moreinputblock==0) )
{
RETAILMSG( (DebugMsgMask&DebugMsg_Trace) , (TEXT( "AACI : record : wait %d %d\r\n" ), bufferedrecordblock , moreinputblock ));
//RETAILMSG( (DebugMsgMask&DebugMsg_Normal) , (TEXT( "AACI : record : wait %d %d\r\n" ), bufferedrecordblock , moreinputblock ));
if( WaitForSingleObject( DmaRecordEvent , 100 ) == 0 )
InterruptDone( RecordDmaIntID );
else
{
OnRecordDmaFail();
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" );
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 )
if( (leftrecordblock!=bufferedrecordblock) || bufferedrecordblock < RecordBufferCount)
{
RETAILMSG( (DebugMsgMask&DebugMsg_Trace) , (TEXT("aaci : to add buffer %d %d\r\n") , bufferedrecordblock, leftrecordblock ));
//AddDebugMsg( "to add record\n" );
if( AddRecordBuffer( &leftrecordblock , &moreinputblock ) == 0 )
{
bufferedrecordblock ++;
//AddDebugMsg( "add record over\n" );
}
if( moreinputblock == 0 )
RETAILMSG( (DebugMsgMask&DebugMsg_Normal), (TEXT("aaci : record : no more input block %d\r\n" ) , moreinputblock));
}
if( leftrecordblock < bufferedrecordblock )
{
int toremove = 1;//bufferedrecordblock - leftrecordblock;
// int toremove = bufferedrecordblock - leftrecordblock;//其实上面和这个是一样的
//AddDebugMsg( "to remove record\n" );
if( RemoveRecordBuffer( 1 ) == 0 )
{
bufferedrecordblock --;
//AddDebugMsg( "remove record over\n" );
}
}
}
RETAILMSG( (DebugMsgMask&DebugMsg_Important ), (TEXT( "AACI : DMA : leave record Thread\r\n" ) ));
return 0;
}
#define PlayBufferCount 3
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( 0 , (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( 0 , (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 , ¶m1 , sizeof(int) , ¶m2 , sizeof(int) , 0);
bufferedplayingblock = 0;
}
if(DMAPlayCmd == DMA_PLAY_STOP || ( bufferedplayingblock == 0 && storedblock == 0 ) )
{
WaitPlayBuffer = 1;
RETAILMSG( 0 , (TEXT("AudioPlayThread to wait%d\r\n" ) , storedblock ));
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();
InterruptDone( PlayDmaIntID );
}
//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;
KernelIoControl( HAL_IOCTL_AACI_GETBUFFER , &leftplayingblock , sizeof(int) , 0,0 , 0);
//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;
PlayBufferToRemove = toremove;
SetEvent( RemoveCmdEvent );
if( RemovePlayBuffer( toremove ) == 0 )
{
bufferedplayingblock -= toremove;
//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;
}
DWORD AudioRemoveThread(LPVOID p)
{
int error = 0 ;
return 0;
while( !error )
{
WaitForSingleObject( RemoveCmdEvent , -1 );
if( PlayBufferToRemove )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -