[wdmaudiodev] Re: msvad wdm audio CopyForm buffer problem

  • From: 何海洲 <hehaizhou8888@xxxxxxx>
  • To: wdmaudiodev@xxxxxxxxxxxxx
  • Date: Tue, 30 Oct 2018 10:33:43 +0800 (CST)

Thank you for your reply, blue screen termination code: IRQL GT ZERO AT SYSTEM 
SERVICE, I have now removed the KeWaitForSingleObject, you are right that can't 
wait, I have now increased the FIFO buffer

Also changed the GetPosition method, more precise timing by 
KeQueryInterruptTime into KeQueryPerformanceCounter, in addition to reset the 
position over fragments of noise, can cause delay problems, don't know whether 
it is correct, if there is a good way to solve this problem?





GetPosition  code:
if (m_ksState == KSSTATE_RUN)
{
//
// Get the current time and update position.
//
LARGE_INTEGER ilQPC = KeQueryPerformanceCounter(NULL);


// Convert ticks to 100ns units.
LONGLONG  hnsCurrentTime = 
KSCONVERT_PERFORMANCE_TIME(m_ullPerformanceCounterFrequency.QuadPart, ilQPC);


// Calculate the time elapsed since the last call to GetPosition() or since the
// DMA engine started.  Note that the division by 10000 to convert to 
milliseconds
// may cause us to lose some of the time, so we will carry the remainder 
forward 
// to the next GetPosition() call.
//
ULONG TimeElapsedInMS = (ULONG)(hnsCurrentTime - m_ullDmaTimeStamp + 
m_ullElapsedTimeCarryForward) / 10000;


// Carry forward the remainder of this division so we don't fall behind with 
our position too much.
//
m_ullElapsedTimeCarryForward = (hnsCurrentTime - m_ullDmaTimeStamp + 
m_ullElapsedTimeCarryForward) % 10000;


// Calculate how many bytes in the DMA buffer would have been processed in the 
elapsed
// time.  Note that the division by 1000 to convert to milliseconds may cause 
us to 
// lose some bytes, so we will carry the remainder forward to the next 
GetPosition() call.
//
// need to divide by 1000 because m_ulDmaMovementRate is average bytes per sec.
ULONGByteDisplacement =
((m_ulDmaMovementRate * TimeElapsedInMS) + m_ulByteDisplacementCarryForward) / 
1000;


// Carry forward the remainder of this division so we don't fall behind with 
our position.
m_ulByteDisplacementCarryForward = (
(m_ulDmaMovementRate * TimeElapsedInMS) + m_ulByteDisplacementCarryForward ) % 
1000;
_data_trans_t* dt = (_data_trans_t*)this->m_pOwner->m_hDataTrans;
if (m_fCapture) {
                                //dt-> req_size is CopyFrom ByteCount- * 
existing data length in the buffer *
m_ulDmaPosition = (m_ulDmaPosition+(ByteDisplacement - dt->req_size)) % 
m_ulDmaBufferSize;
InterlockedExchange(&dt->req_size, 0);
}
else {
m_ulDmaPosition = (m_ulDmaPosition+ByteDisplacement) % m_ulDmaBufferSize;
}
*Position = m_ulDmaPosition;


m_ullDmaTimeStamp = hnsCurrentTime;
}


At 2018-10-30 02:25:09, "Tim Roberts" <timr@xxxxxxxxx> wrote:

何海洲 wrote:


When I use the KeWaitForSingleObject to wait for the buffering to complete, the 
blue screen will occur. How do I resolve it


Why would you not tell us which blue screen you got?  I'm pretty sure I know 
what it was, but you need to do some of your own debugging here.

The CopyFrom process happens in real-time at a raised IRQL.  You can't wait for 
anything.  If you don't have the data, you'll have to return and hope that you 
catch up sooner or later.

This is a tricky environment.  The system asks for 10ms at a time.  If the 
entity that is producing your data works in larger blocks than that, it's up to 
you to provide the glue, usually by buffering up enough initial data to work 
through the mismatch.

-- 
Tim Roberts, timr@xxxxxxxxx
Providenza & Boekelheide, Inc.

Other related posts: