📄 aaci_dmaold.c
字号:
}
RETAILMSG( (DebugMsgMask&DebugMsg_Important ), (TEXT( "AACI : DMA : leave record Thread\r\n" ) ));
return 0;
}
//定义播放缓存为1
#define PlayBufferCount 1
//播放线程
DWORD AudioDMAThread(LPVOID p)
{
int error = 0 , bufferedplayingblock = 0 , leftplayingblock = 0 , storedblock = 0 , toremove = 0;
RETAILMSG( (DebugMsgMask&DebugMsg_Important ), (TEXT( "AACI : DMA : Enter Thread\r\n" ) ));
/*
if(0)
{
int time = GetTickCount() , loopcount = 0;
while( !error && DMAPlayCmd != DMA_PLAY_EXIT )
{
if( (loopcount++%1000) == 0 )
RETAILMSG( 1 , (TEXT("AudioPlayThread loop %d\n" ) , bufferedplayingblock ));
if( DMAPlayCmd == DMA_PLAY_STOP || bufferedplayingblock == PlayBufferCount ||storedblock == 0 )
{
WaitForSingleObject( DmaPlayEvent , INFINITE );
InterruptDone( PlayDmaIntID );
}
if( (DMAPlayCmd != DMA_PLAY_START) )
continue;
if( PlayBufferStoreIndex >= PlayBufferPlayIndex)
storedblock = PlayBufferStoreIndex - PlayBufferPlayIndex;
else
storedblock = TotalPlayBufferCnt - PlayBufferPlayIndex + PlayBufferStoreIndex;
KernelIoControl( HAL_IOCTL_AACI_GETBUFFER , &leftplayingblock , sizeof(int) , 0,0 , 0);
toremove = bufferedplayingblock - leftplayingblock;
if( (leftplayingblock < bufferedplayingblock || bufferedplayingblock < PlayBufferCount) && storedblock > 0 )
if( AddPlayBuffer( &leftplayingblock ) == 0 )
{
bufferedplayingblock ++;
}
if( toremove )
{
RemovePlayBuffer(1);
bufferedplayingblock --;
}
}
}
*/
while( !error && DMAPlayCmd != DMA_PLAY_EXIT )//当没有错误并且当前DMAPlayCmd不为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 == PlayBufferCount || 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;//continue 语句被用来告诉Python跳过当前循环块中的剩余语句,然后 继续 进行下一轮循环。
RETAILMSG( (DebugMsgMask&DebugMsg_Trace) , (TEXT( "AACI : DMA : start work\r\n" ) ));
if( PlayBufferStoreIndex >= PlayBufferPlayIndex)
storedblock = PlayBufferStoreIndex - PlayBufferPlayIndex;
else
storedblock = TotalPlayBufferCnt - PlayBufferPlayIndex + PlayBufferStoreIndex;
//查看kernel 里面buff的情况
KernelIoControl( HAL_IOCTL_AACI_GETBUFFER , &leftplayingblock , sizeof(int) , 0,0 , 0);
if( DMAPlayCmd == DMA_PLAY_START )//如果当前的DmaPlayCmd为开始播放则进入下面的
if( ((leftplayingblock < bufferedplayingblock) || bufferedplayingblock < PlayBufferCount) && storedblock > 0 )
{ // add buffer
if( AddPlayBuffer( &leftplayingblock ) == 0 )//加载BUFF
{
bufferedplayingblock ++;
storedblock -- ;
}
}
if( leftplayingblock < bufferedplayingblock )
{ // remove header
//bufferedplayingblock---是当前kernel中的 buff 总数
//leftplayingblock--------是当前kernel 中没有被用的或被用但没有传送完成的buff数量
int toremove = bufferedplayingblock - leftplayingblock;//当前kernel 中已经完成的buff的数量
if( RemovePlayBuffer( toremove ) == 0 )//搬移当前已经DMA 传送完成的BUFF
bufferedplayingblock = leftplayingblock;//把当前已经DMA 传送完成的BUFF 搬移后kernel中的总BUFF数量又和当前没有利用和已经利用但没有完成的BUFF数量一样
InterruptDone( PlayDmaIntID );//告诉kernel 这次数据传送完成????
}
else if( leftplayingblock > bufferedplayingblock )//如果当前空的BUFF和没有完成的BUFF 总的数量大于kernel 中总的buff数量则表明出错了
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( WaitForSingleObject( DmaThread , 1000 ) != WAIT_OBJECT_0 )
TerminateThread( DmaThread , -1 );
CloseHandle( DmaThread );
}
DMARecordCmd = DMA_RECORD_EXIT;
if( DmaRecordThread )
{
if( DmaRecordEvent )
SetEvent( DmaRecordEvent );
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 )//如果上面的没有出现错误则继续初始化record
{
if( AllocRecordDMA() != 0 ) //分配recorddma
error = 3;//if return error then error =3
else if( InitRecordDMA() != 0 ) //初始化recorddma
error = 4;
}
if( !error )//如果初始化播放和录音都没有问题则创建录音和播放线程
{
DmaThread = CreateThread( NULL, 0, AudioDMAThread, NULL, 0, NULL);//播放线程
if( !DmaThread )
error = 5;
else
//把播放优先级放高
SetThreadPriority( DmaThread , THREAD_PRIORITY_HIGHEST );//设置线程优先级
}
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()
{
SetEvent( DmaRecordEvent );
}
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 / size ;
}
memcpy( PlayBuffer + PlayBufferBlockSize*PlayBufferStoreIndex , buf , size );
playcount ++;
/*
if( (playcount%100 ) == 0 )
RETAILMSG( 1 , (TEXT("StorePlayBuffer %d %d %d\r\n") , playcount , playedcount , playcount-playedcount));
*/
if( PlayBufferStoreIndex == PlayBufferPlayIndex )
notify = 1;
PlayBufferStoreIndex = (PlayBufferStoreIndex+1) % TotalPlayBufferCnt;
if( notify )
SetEvent( DmaPlayEvent );
}
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;
//通过KernelIoControl发送命令让系统内核开始进行DMA C传送数据
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 + -