//================================================ STDMETHODIMP_(void) CMiniportWaveCyclicStream::CopyFrom( IN PVOID Destination, IN PVOID Source, IN ULONG ByteCount ) /* Routine Description: The CopyFrom function copies sample data from the DMA buffer. Callers of CopyFrom can run at any IRQL Arguments: Destination - Points to the destination buffer. Source - Points to the source buffer. ByteCount - Points to the source buffer. Return Value: void */ { ULONG i=0; ULONG FrameCount = ByteCount/2; //we guess 16-Bit sample rate //DbgPrint(DBGMESSAGE "CopyFrom - ReadPos=%d",myBufferReadPos); DbgPrint(DBGMESSAGE "CopyFrom - WritePos=%d",myBufferWritePos); if (!m_pMiniport->myBufferLocked) { //DbgPrint(DBGMESSAGE "CopyFrom - ByteCount=%d", ByteCount); InterlockedExchange(&m_pMiniport->myBufferLocked, TRUE); ULONG umyBufferSize=(ULONG)m_pMiniport->myBufferSize; ULONG availableDataCount = (umyBufferSize + m_pMiniport->myBufferWritePos) - m_pMiniport->myBufferReadPos; if (availableDataCount >= umyBufferSize) availableDataCount -= umyBufferSize; if (availableDataCount < FrameCount) { //if the caller wants to read more data than the buffer size is, //we fill the rest with silence //we write the silence at the beginning, //because in the most cases we need to do this the caller begins to read - so we care //for a continually stream of sound data ULONG silenceCount = FrameCount - availableDataCount; //DbgPrint(DBGMESSAGE "CopyFrom - need more data! NeedCount=%d", silenceCount); for (i=0; i<=silenceCount ; i++) { ((PWORD)Destination)[i]=0; } } //i=0; while ((i < FrameCount) && //we have more data in the buffer than the caller would like to get ((m_pMiniport->myBufferWritePos != m_pMiniport->myBufferReadPos+1) && !((m_pMiniport->myBufferWritePos==0) && (m_pMiniport->myBufferReadPos==m_pMiniport->myBufferSize))) ) { ((PWORD)Destination)[i]=((PWORD)m_pMiniport->myBuffer)[m_pMiniport->myBufferReadPos]; i++; m_pMiniport->myBufferReadPos++; if (m_pMiniport->myBufferReadPos >= m_pMiniport->myBufferSize) //Loop the buffer m_pMiniport->myBufferReadPos=0; } InterlockedExchange(&m_pMiniport->myBufferReading, TRUE); //now the caller reads from the buffer - so we can notify the CopyTo function //DbgPrint(DBGMESSAGE "CopyFrom TRUE ByteCount=%d", ByteCount); InterlockedExchange(&m_pMiniport->myBufferLocked, FALSE); } else { //in this case we can't obtain the data from buffer because it is locked //the best we can do (to satisfy the caller) is to fill the whole buffer with silence for (i=0; i < FrameCount ; i++) { ((PWORD)Destination)[i]=0; } DBGPRINT("CopyFrom FALSE"); } } // CopyFrom //==================================================== STDMETHODIMP_(void) CMiniportWaveCyclicStream::CopyTo( IN PVOID Destination, IN PVOID Source, IN ULONG ByteCount ) /* Routine Description: The CopyTo function copies sample data to the DMA buffer. Callers of CopyTo can run at any IRQL. Arguments: Destination - Points to the destination buffer. Source - Points to the source buffer ByteCount - Number of bytes to be copied Return Value: void */ { ULONG i=0; ULONG FrameCount = ByteCount/2; //we guess 16-Bit sample rate if (m_pMiniport->myBuffer==NULL) { ULONG bufSize=64*1024; //size in bytes DBGPRINT("Try to allocate buffer"); m_pMiniport->myBuffer = (PVOID) ExAllocatePoolWithTag(NonPagedPool, bufSize, RTSDAUDIO_POOLTAG); if (!m_pMiniport->myBuffer) { DBGPRINT("FAILED to allocate buffer"); } else { DBGPRINT("Successfully allocated buffer"); m_pMiniport->myBufferSize = bufSize/2; //myBufferSize in frames InterlockedExchange(&m_pMiniport->myBufferLocked, FALSE); } } if (!m_pMiniport->myBufferLocked) { //DbgPrint(DBGMESSAGE "Fill Buffer ByteCount=%d", ByteCount); InterlockedExchange(&m_pMiniport->myBufferLocked, TRUE); i=0; while (i < FrameCount) {//while data is available //test wether we arrived at the read-pos //if (! ((myBufferWritePos+1 != myBufferReadPos) && !((myBufferReadPos==0) && (myBufferWritePos==myBufferSize)))) { if ((m_pMiniport->myBufferWritePos+1==m_pMiniport->myBufferReadPos) || (m_pMiniport->myBufferReadPos==0 && m_pMiniport->myBufferWritePos==m_pMiniport->myBufferSize)){ //DbgPrint(DBGMESSAGE "CopyTo - there is no space for new data! NeedCount=%d", FrameCount-i); if (m_pMiniport->myBufferReadPos==m_pMiniport->myBufferSize) m_pMiniport->myBufferReadPos=0; else m_pMiniport->myBufferReadPos++; //break; //we have to break - because there is no space for the rest data } ((PWORD)m_pMiniport->myBuffer)[m_pMiniport->myBufferWritePos]=((PWORD)Source)[i]; i++; m_pMiniport->myBufferWritePos++; if (m_pMiniport->myBufferWritePos >= m_pMiniport->myBufferSize) //Loop the buffer m_pMiniport->myBufferWritePos=0; } //DbgPrint(DBGMESSAGE "CopyTo - ReadPos=%d",myBufferReadPos); DbgPrint(DBGMESSAGE "CopyTo - WritePos=%d",myBufferWritePos); InterlockedExchange(&m_pMiniport->myBufferLocked, FALSE); //DbgPrint(DBGMESSAGE "(2) CopyTo - ReadPos=%d",myBufferReadPos); DbgPrint(DBGMESSAGE "(2) CopyTo - WritePos=%d",myBufferWritePos); //DbgPrint(DBGMESSAGE "(2) CopyTo - Locked=%d",myBufferLocked); } } // CopyTo
var
This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)