diff --git a/reactos/drivers/wdm/audio/backpln/portcls/interfaces.hpp b/reactos/drivers/wdm/audio/backpln/portcls/interfaces.hpp index 7b8b6fdd0c8..031a00fc465 100644 --- a/reactos/drivers/wdm/audio/backpln/portcls/interfaces.hpp +++ b/reactos/drivers/wdm/audio/backpln/portcls/interfaces.hpp @@ -322,9 +322,8 @@ DECLARE_INTERFACE_(IIrpQueue, IUnknown) IN PVOID SilenceBuffer) PURE; STDMETHOD_(NTSTATUS, AddMapping)(THIS_ - IN PUCHAR Buffer, - IN ULONG BufferSize, - IN PIRP Irp) PURE; + IN PIRP Irp, + OUT PULONG Data) PURE; STDMETHOD_(NTSTATUS, GetMapping)(THIS_ OUT PUCHAR * Buffer, @@ -372,9 +371,8 @@ DECLARE_INTERFACE_(IIrpQueue, IUnknown) IN PVOID SilenceBuffer); \ \ STDMETHODIMP_(NTSTATUS) AddMapping(THIS_ \ - IN PUCHAR Buffer, \ - IN ULONG BufferSize, \ - IN PIRP Irp); \ + IN PIRP Irp, \ + OUT PULONG Data); \ \ STDMETHODIMP_(NTSTATUS) GetMapping(THIS_ \ OUT PUCHAR * Buffer, \ diff --git a/reactos/drivers/wdm/audio/backpln/portcls/irpstream.cpp b/reactos/drivers/wdm/audio/backpln/portcls/irpstream.cpp index f3b1d7b0e2f..37595855dfa 100644 --- a/reactos/drivers/wdm/audio/backpln/portcls/irpstream.cpp +++ b/reactos/drivers/wdm/audio/backpln/portcls/irpstream.cpp @@ -39,7 +39,7 @@ protected: LONG m_NumMappings; ULONG m_NumDataAvailable; BOOL m_StartStream; - KSPIN_CONNECT * m_ConnectDetails; + PKSPIN_CONNECT m_ConnectDetails; PKSDATAFORMAT_WAVEFORMATEX m_DataFormat; KSPIN_LOCK m_IrpListLock; @@ -110,9 +110,8 @@ CIrpQueue::Init( NTSTATUS NTAPI CIrpQueue::AddMapping( - IN PUCHAR Buffer, - IN ULONG BufferSize, - IN PIRP Irp) + IN PIRP Irp, + OUT PULONG Data) { PKSSTREAM_HEADER Header; NTSTATUS Status = STATUS_SUCCESS; @@ -125,8 +124,6 @@ CIrpQueue::AddMapping( // get current irp stack location IoStack = IoGetCurrentIrpStackLocation(Irp); - PC_ASSERT(!Buffer); - if (!Irp->MdlAddress) { // ioctl from KsStudio @@ -172,8 +169,8 @@ CIrpQueue::AddMapping( NumData = 0; // prepare all headers - for(Index = 0; Index < NumHeaders; Index++) - { + for(Index = 0; Index < NumHeaders; Index++) + { // sanity checks PC_ASSERT(Header); PC_ASSERT(Mdl); @@ -181,17 +178,17 @@ CIrpQueue::AddMapping( Header->Data = MmGetSystemAddressForMdlSafe(Mdl, NormalPagePriority); if (!Header->Data) - { + { // insufficient resources ExFreePool(Irp->AssociatedIrp.SystemBuffer); Irp->AssociatedIrp.SystemBuffer = NULL; - // complete and forget request + // complete and forget request Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES; Irp->IoStatus.Information = 0; IoCompleteRequest(Irp, IO_NO_INCREMENT); return STATUS_INSUFFICIENT_RESOURCES; - } + } // increment num mappings InterlockedIncrement(&m_NumMappings); @@ -207,10 +204,10 @@ CIrpQueue::AddMapping( // move to next mdl Mdl = Mdl->Next; - } + } DPRINT("StreamHeaders %u NumData %u FrameSize %u NumDataAvailable %u\n", NumHeaders, NumData, m_MaxFrameSize, m_NumDataAvailable); - + *Data = NumData; // mark irp as pending IoMarkIrpPending(Irp); @@ -330,7 +327,7 @@ CIrpQueue::UpdateMapping( if (m_CurrentOffset >= Size) { if (STREAMHEADER_INDEX(m_Irp) + 1 < STREAMHEADER_COUNT(m_Irp)) - { + { // the irp has at least one more stream header m_Irp->Tail.Overlay.DriverContext[OFFSET_HEADERINDEX] = UlongToPtr(STREAMHEADER_INDEX(m_Irp) + 1); @@ -345,7 +342,7 @@ CIrpQueue::UpdateMapping( // done return; - } + } // irp has been processed completly @@ -354,7 +351,7 @@ CIrpQueue::UpdateMapping( // loop all stream headers for(Index = 0; Index < STREAMHEADER_COUNT(m_Irp); Index++) - { + { PC_ASSERT(StreamHeader); // add size of buffer @@ -369,20 +366,30 @@ CIrpQueue::UpdateMapping( // get next stream header StreamHeader = (PKSSTREAM_HEADER)((ULONG_PTR)StreamHeader + StreamHeader->Size); - } + } + + if (m_ConnectDetails->Interface.Id == KSINTERFACE_STANDARD_LOOPED_STREAMING) + { + // looped streaming repeat the buffers untill + // the caller decides to stop the streams + + // reset stream header index + m_Irp->Tail.Overlay.DriverContext[OFFSET_HEADERINDEX] = UlongToPtr(0); + // re-insert irp + KsAddIrpToCancelableQueue(&m_IrpList, &m_IrpListLock, m_Irp, KsListEntryTail, NULL); + // clear current irp + m_Irp = NULL; + // reset offset + m_CurrentOffset = 0; + // increment available data + InterlockedExchangeAdd((PLONG)&m_NumDataAvailable, NumData); + // done + return; + } m_Irp->IoStatus.Status = STATUS_SUCCESS; m_Irp->IoStatus.Information = NumData; -#if 0 - PC_ASSERT_IRQL(DISPATCH_LEVEL); - MmUnlockPages(m_Irp->MdlAddress); - IoFreeMdl(m_Irp->MdlAddress); - m_Irp->MdlAddress = NULL; - ExFreePool(m_Irp->AssociatedIrp.SystemBuffer); - m_Irp->AssociatedIrp.SystemBuffer = NULL; -#endif - // complete the request IoCompleteRequest(m_Irp, IO_SOUND_INCREMENT); // remove irp as it is complete diff --git a/reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.cpp b/reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.cpp index 56f6217e107..759b261540c 100644 --- a/reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.cpp +++ b/reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.cpp @@ -59,7 +59,7 @@ protected: PMINIPORTWAVECYCLICSTREAM m_Stream; KSSTATE m_State; PKSDATAFORMAT m_Format; - KSPIN_CONNECT * m_ConnectDetails; + PKSPIN_CONNECT m_ConnectDetails; PVOID m_CommonBuffer; ULONG m_CommonBufferSize; @@ -187,6 +187,7 @@ PinWaveCyclicAudioPosition( { CPortPinWaveCyclic *Pin; PSUBDEVICE_DESCRIPTOR Descriptor; + PKSAUDIO_POSITION Position; // get sub device descriptor Descriptor = (PSUBDEVICE_DESCRIPTOR)KSPROPERTY_ITEM_IRP_STORAGE(Irp); @@ -206,9 +207,21 @@ PinWaveCyclicAudioPosition( { // FIXME non multithreading-safe // copy audio position - RtlMoveMemory(Data, &Pin->m_Position, sizeof(KSAUDIO_POSITION)); - DPRINT("Play %lu Record %lu\n", Pin->m_Position.PlayOffset, Pin->m_Position.WriteOffset); + Position = (PKSAUDIO_POSITION)Data; + + if (Pin->m_ConnectDetails->Interface.Id == KSINTERFACE_STANDARD_STREAMING) + { + RtlMoveMemory(Data, &Pin->m_Position, sizeof(KSAUDIO_POSITION)); + DPRINT("Play %lu Record %lu\n", Pin->m_Position.PlayOffset, Pin->m_Position.WriteOffset); + } + else if (Pin->m_ConnectDetails->Interface.Id == KSINTERFACE_STANDARD_LOOPED_STREAMING) + { + Position->PlayOffset = Pin->m_Position.PlayOffset % Pin->m_Position.WriteOffset; + Position->WriteOffset = Pin->m_IrpQueue->NumData(); + } + + Irp->IoStatus.Information = sizeof(KSAUDIO_POSITION); return STATUS_SUCCESS; } @@ -584,25 +597,21 @@ CPortPinWaveCyclic::HandleKsStream( IN PIRP Irp) { NTSTATUS Status; + ULONG Data = 0; InterlockedIncrement((PLONG)&m_TotalPackets); DPRINT("IPortPinWaveCyclic_HandleKsStream entered Total %u State %x MinData %u\n", m_TotalPackets, m_State, m_IrpQueue->NumData()); - Status = m_IrpQueue->AddMapping(NULL, 0, Irp); + Status = m_IrpQueue->AddMapping(Irp, &Data); if (NT_SUCCESS(Status)) { - - PKSSTREAM_HEADER Header = (PKSSTREAM_HEADER)Irp->AssociatedIrp.SystemBuffer; - PC_ASSERT(Header); - if (m_Capture) - m_Position.WriteOffset += Header->FrameExtent; + m_Position.WriteOffset += Data; else - m_Position.WriteOffset += Header->DataUsed; + m_Position.WriteOffset += Data; return STATUS_PENDING; - } return Status; diff --git a/reactos/drivers/wdm/audio/backpln/portcls/pin_wavepci.cpp b/reactos/drivers/wdm/audio/backpln/portcls/pin_wavepci.cpp index 79ff0a1b49b..273bfae6539 100644 --- a/reactos/drivers/wdm/audio/backpln/portcls/pin_wavepci.cpp +++ b/reactos/drivers/wdm/audio/backpln/portcls/pin_wavepci.cpp @@ -665,22 +665,19 @@ CPortPinWavePci::HandleKsStream( IN PIRP Irp) { NTSTATUS Status; + ULONG Data = 0; InterlockedIncrement((PLONG)&m_TotalPackets); DPRINT("IPortPinWaveCyclic_HandleKsStream entered Total %u State %x MinData %u\n", m_TotalPackets, m_State, m_IrpQueue->NumData()); - Status = m_IrpQueue->AddMapping(NULL, 0, Irp); + Status = m_IrpQueue->AddMapping(Irp, &Data); if (NT_SUCCESS(Status)) { - - PKSSTREAM_HEADER Header = (PKSSTREAM_HEADER)Irp->AssociatedIrp.SystemBuffer; - PC_ASSERT(Header); - if (m_Capture) - m_Position.WriteOffset += Header->FrameExtent; + m_Position.WriteOffset += Data; else - m_Position.WriteOffset += Header->DataUsed; + m_Position.WriteOffset += Data; return STATUS_PENDING; } diff --git a/reactos/drivers/wdm/audio/backpln/portcls/undoc.cpp b/reactos/drivers/wdm/audio/backpln/portcls/undoc.cpp index c0b1f85ac60..56c25973745 100644 --- a/reactos/drivers/wdm/audio/backpln/portcls/undoc.cpp +++ b/reactos/drivers/wdm/audio/backpln/portcls/undoc.cpp @@ -8,6 +8,22 @@ #include "private.hpp" + +KSPIN_INTERFACE PinInterfaces[] = +{ + { + {STATIC_KSINTERFACESETID_Standard}, + KSINTERFACE_STANDARD_STREAMING, + 0 + }, + { + {STATIC_KSINTERFACESETID_Standard}, + KSINTERFACE_STANDARD_LOOPED_STREAMING, + 0 + } +}; + + NTSTATUS NTAPI KsoDispatchCreateWithGenericFactory( @@ -450,6 +466,9 @@ PcCreateSubdeviceDescriptor( { RtlMoveMemory(&Descriptor->Factory.KsPinDescriptor[Index], &SrcDescriptor->KsPinDescriptor, sizeof(KSPIN_DESCRIPTOR)); + Descriptor->Factory.KsPinDescriptor[Index].Interfaces = PinInterfaces; + Descriptor->Factory.KsPinDescriptor[Index].InterfacesCount = sizeof(PinInterfaces) / sizeof(KSPIN_INTERFACE); + DPRINT("Index %u DataRangeCount %u\n", Index, SrcDescriptor->KsPinDescriptor.DataRangesCount); Descriptor->Factory.Instances[Index].CurrentPinInstanceCount = 0;