From db1d10a2c8112d4a37d4f0d41297daf4825dce35 Mon Sep 17 00:00:00 2001 From: Gary Scavone Date: Sun, 30 Mar 2014 11:33:30 -0400 Subject: [PATCH 01/45] Commented out some function arguments in test programs to avoid compiler warnings. --- tests/cmidiin.cpp | 4 ++-- tests/midiout.cpp | 2 +- tests/qmidiin.cpp | 2 +- tests/sysextest.cpp | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/cmidiin.cpp b/tests/cmidiin.cpp index 5aa4053c..be78dbbd 100644 --- a/tests/cmidiin.cpp +++ b/tests/cmidiin.cpp @@ -19,7 +19,7 @@ void usage( void ) { exit( 0 ); } -void mycallback( double deltatime, std::vector< unsigned char > *message, void *userData ) +void mycallback( double deltatime, std::vector< unsigned char > *message, void */*userData*/ ) { unsigned int nBytes = message->size(); for ( unsigned int i=0; i *message, void * // It returns false if there are no ports available. bool chooseMidiPort( RtMidiIn *rtmidi ); -int main( int argc, char *argv[] ) +int main( int argc, char ** /*argv[]*/ ) { RtMidiIn *midiin = 0; diff --git a/tests/midiout.cpp b/tests/midiout.cpp index 0a9b9fdf..05505cc6 100644 --- a/tests/midiout.cpp +++ b/tests/midiout.cpp @@ -24,7 +24,7 @@ // It returns false if there are no ports available. bool chooseMidiPort( RtMidiOut *rtmidi ); -int main( int argc, char *argv[] ) +int main( void ) { RtMidiOut *midiout = 0; std::vector message; diff --git a/tests/qmidiin.cpp b/tests/qmidiin.cpp index 2adc03de..afd112b0 100644 --- a/tests/qmidiin.cpp +++ b/tests/qmidiin.cpp @@ -22,7 +22,7 @@ #endif bool done; -static void finish( int ignore ){ done = true; } +static void finish( int /*ignore*/ ){ done = true; } void usage( void ) { // Error function in case of incorrect command-line diff --git a/tests/sysextest.cpp b/tests/sysextest.cpp index 96eaaa82..8402c74c 100644 --- a/tests/sysextest.cpp +++ b/tests/sysextest.cpp @@ -31,7 +31,7 @@ void usage( void ) { // It returns false if there are no ports available. bool chooseMidiPort( RtMidi *rtmidi ); -void mycallback( double deltatime, std::vector< unsigned char > *message, void *userData ) +void mycallback( double deltatime, std::vector< unsigned char > *message, void * /*userData*/ ) { unsigned int nBytes = message->size(); for ( unsigned int i=0; i Date: Sun, 30 Mar 2014 11:46:35 -0400 Subject: [PATCH 02/45] Removed Windows kernel streaming code because it was incomplete and uncompilable. The code still exists in the winks branch. --- RtMidi.cpp | 1045 -------------------------------------- RtMidi.h | 40 +- doc/doxygen/tutorial.txt | 13 +- doc/release.txt | 1 + readme | 2 +- 5 files changed, 6 insertions(+), 1095 deletions(-) diff --git a/RtMidi.cpp b/RtMidi.cpp index 2101c377..07e23168 100644 --- a/RtMidi.cpp +++ b/RtMidi.cpp @@ -78,9 +78,6 @@ void RtMidi :: getCompiledApi( std::vector &apis ) throw() #if defined(__WINDOWS_MM__) apis.push_back( WINDOWS_MM ); #endif -#if defined(__WINDOWS_KS__) - apis.push_back( WINDOWS_KS ); -#endif #if defined(__RTMIDI_DUMMY__) apis.push_back( RTMIDI_DUMMY ); #endif @@ -108,10 +105,6 @@ void RtMidiIn :: openMidiApi( RtMidi::Api api, const std::string clientName, uns if ( api == WINDOWS_MM ) rtapi_ = new MidiInWinMM( clientName, queueSizeLimit ); #endif -#if defined(__WINDOWS_KS__) - if ( api == WINDOWS_KS ) - rtapi_ = new MidiInWinKS( clientName, queueSizeLimit ); -#endif #if defined(__MACOSX_CORE__) if ( api == MACOSX_CORE ) rtapi_ = new MidiInCore( clientName, queueSizeLimit ); @@ -181,10 +174,6 @@ void RtMidiOut :: openMidiApi( RtMidi::Api api, const std::string clientName ) if ( api == WINDOWS_MM ) rtapi_ = new MidiOutWinMM( clientName ); #endif -#if defined(__WINDOWS_KS__) - if ( api == WINDOWS_KS ) - rtapi_ = new MidiOutWinKS( clientName ); -#endif #if defined(__MACOSX_CORE__) if ( api == MACOSX_CORE ) rtapi_ = new MidiOutCore( clientName ); @@ -2434,1040 +2423,6 @@ void MidiOutWinMM :: sendMessage( std::vector *message ) #endif // __WINDOWS_MM__ -// *********************************************************************// -// API: WINDOWS Kernel Streaming -// -// Written by Sebastien Alaiwan, 2012. -// -// NOTE BY GARY: much of the KS-specific code below probably should go in a separate file. -// -// *********************************************************************// - -#if defined(__WINDOWS_KS__) - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "ks.h" -#include "ksmedia.h" - -#define INSTANTIATE_GUID(a) GUID const a = { STATIC_ ## a } - -INSTANTIATE_GUID(GUID_NULL); -INSTANTIATE_GUID(KSPROPSETID_Pin); -INSTANTIATE_GUID(KSPROPSETID_Connection); -INSTANTIATE_GUID(KSPROPSETID_Topology); -INSTANTIATE_GUID(KSINTERFACESETID_Standard); -INSTANTIATE_GUID(KSMEDIUMSETID_Standard); -INSTANTIATE_GUID(KSDATAFORMAT_TYPE_MUSIC); -INSTANTIATE_GUID(KSDATAFORMAT_SUBTYPE_MIDI); -INSTANTIATE_GUID(KSDATAFORMAT_SPECIFIER_NONE); - -#undef INSTANTIATE_GUID - -typedef std::basic_string tstring; - -inline bool IsValid(HANDLE handle) -{ - return handle != NULL && handle != INVALID_HANDLE_VALUE; -} - -class ComException : public std::runtime_error -{ -private: - static std::string MakeString(std::string const& s, HRESULT hr) - { - std::stringstream ss; - ss << "(error 0x" << std::hex << hr << ")"; - return s + ss.str(); - } - -public: - ComException(std::string const& s, HRESULT hr) : - std::runtime_error(MakeString(s, hr)) - { - } -}; - -template -class CKsEnumFilters -{ -public: - ~CKsEnumFilters() - { - DestroyLists(); - } - - void EnumFilters(GUID const* categories, size_t numCategories) - { - DestroyLists(); - - if (categories == 0) - throw std::runtime_error("CKsEnumFilters: invalid argument"); - - // Get a handle to the device set specified by the guid - HDEVINFO hDevInfo = ::SetupDiGetClassDevs(&categories[0], NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); - if (!IsValid(hDevInfo)) - throw std::runtime_error("CKsEnumFilters: no devices found"); - - // Loop through members of the set and get details for each - for ( int iClassMember=0; iClassMember++ ) { - try { - SP_DEVICE_INTERFACE_DATA DID; - DID.cbSize = sizeof(DID); - DID.Reserved = 0; - - bool fRes = ::SetupDiEnumDeviceInterfaces(hDevInfo, NULL, &categories[0], iClassMember, &DID); - if (!fRes) - break; - - // Get filter friendly name - HKEY hRegKey = ::SetupDiOpenDeviceInterfaceRegKey(hDevInfo, &DID, 0, KEY_READ); - if (hRegKey == INVALID_HANDLE_VALUE) - throw std::runtime_error("CKsEnumFilters: interface has no registry"); - - char friendlyName[256]; - DWORD dwSize = sizeof friendlyName; - LONG lval = ::RegQueryValueEx(hRegKey, TEXT("FriendlyName"), NULL, NULL, (LPBYTE)friendlyName, &dwSize); - ::RegCloseKey(hRegKey); - if (lval != ERROR_SUCCESS) - throw std::runtime_error("CKsEnumFilters: interface has no friendly name"); - - // Get details for the device registered in this class - DWORD const cbItfDetails = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA) + MAX_PATH * sizeof(WCHAR); - std::vector buffer(cbItfDetails); - - SP_DEVICE_INTERFACE_DETAIL_DATA* pDevInterfaceDetails = reinterpret_cast(&buffer[0]); - pDevInterfaceDetails->cbSize = sizeof(*pDevInterfaceDetails); - - SP_DEVINFO_DATA DevInfoData; - DevInfoData.cbSize = sizeof(DevInfoData); - DevInfoData.Reserved = 0; - - fRes = ::SetupDiGetDeviceInterfaceDetail(hDevInfo, &DID, pDevInterfaceDetails, cbItfDetails, NULL, &DevInfoData); - if (!fRes) - throw std::runtime_error("CKsEnumFilters: could not get interface details"); - - // check additional category guids which may (or may not) have been supplied - for (size_t i=1; i < numCategories; ++i) { - SP_DEVICE_INTERFACE_DATA DIDAlias; - DIDAlias.cbSize = sizeof(DIDAlias); - DIDAlias.Reserved = 0; - - fRes = ::SetupDiGetDeviceInterfaceAlias(hDevInfo, &DID, &categories[i], &DIDAlias); - if (!fRes) - throw std::runtime_error("CKsEnumFilters: could not get interface alias"); - - // Check if the this interface alias is enabled. - if (!DIDAlias.Flags || (DIDAlias.Flags & SPINT_REMOVED)) - throw std::runtime_error("CKsEnumFilters: interface alias is not enabled"); - } - - std::auto_ptr pFilter(new TFilterType(pDevInterfaceDetails->DevicePath, friendlyName)); - - pFilter->Instantiate(); - pFilter->FindMidiPins(); - pFilter->Validate(); - - m_Filters.push_back(pFilter.release()); - } - catch (std::runtime_error const& e) { - } - } - - ::SetupDiDestroyDeviceInfoList(hDevInfo); - } - -private: - void DestroyLists() - { - for (size_t i=0;i < m_Filters.size();++i) - delete m_Filters[i]; - m_Filters.clear(); - } - -public: - // TODO: make this private. - std::vector m_Filters; -}; - -class CKsObject -{ -public: - CKsObject(HANDLE handle) : m_handle(handle) - { - } - -protected: - HANDLE m_handle; - - void SetProperty(REFGUID guidPropertySet, ULONG nProperty, void* pvValue, ULONG cbValue) - { - KSPROPERTY ksProperty; - memset(&ksProperty, 0, sizeof ksProperty); - ksProperty.Set = guidPropertySet; - ksProperty.Id = nProperty; - ksProperty.Flags = KSPROPERTY_TYPE_SET; - - HRESULT hr = DeviceIoControlKsProperty(ksProperty, pvValue, cbValue); - if (FAILED(hr)) - throw ComException("CKsObject::SetProperty: could not set property", hr); - } - -private: - - HRESULT DeviceIoControlKsProperty(KSPROPERTY& ksProperty, void* pvValue, ULONG cbValue) - { - ULONG ulReturned; - return ::DeviceIoControl( - m_handle, - IOCTL_KS_PROPERTY, - &ksProperty, - sizeof(ksProperty), - pvValue, - cbValue, - &ulReturned, - NULL); - } -}; - -class CKsPin; - -class CKsFilter : public CKsObject -{ - friend class CKsPin; - -public: - CKsFilter(tstring const& name, std::string const& sFriendlyName); - virtual ~CKsFilter(); - - virtual void Instantiate(); - - template - T GetPinProperty(ULONG nPinId, ULONG nProperty) - { - ULONG ulReturned = 0; - T value; - - KSP_PIN ksPProp; - ksPProp.Property.Set = KSPROPSETID_Pin; - ksPProp.Property.Id = nProperty; - ksPProp.Property.Flags = KSPROPERTY_TYPE_GET; - ksPProp.PinId = nPinId; - ksPProp.Reserved = 0; - - HRESULT hr = ::DeviceIoControl( - m_handle, - IOCTL_KS_PROPERTY, - &ksPProp, - sizeof(KSP_PIN), - &value, - sizeof(value), - &ulReturned, - NULL); - if (FAILED(hr)) - throw ComException("CKsFilter::GetPinProperty: failed to retrieve property", hr); - - return value; - } - - void GetPinPropertyMulti(ULONG nPinId, REFGUID guidPropertySet, ULONG nProperty, PKSMULTIPLE_ITEM* ppKsMultipleItem) - { - HRESULT hr; - - KSP_PIN ksPProp; - ksPProp.Property.Set = guidPropertySet; - ksPProp.Property.Id = nProperty; - ksPProp.Property.Flags = KSPROPERTY_TYPE_GET; - ksPProp.PinId = nPinId; - ksPProp.Reserved = 0; - - ULONG cbMultipleItem = 0; - hr = ::DeviceIoControl(m_handle, - IOCTL_KS_PROPERTY, - &ksPProp.Property, - sizeof(KSP_PIN), - NULL, - 0, - &cbMultipleItem, - NULL); - if (FAILED(hr)) - throw ComException("CKsFilter::GetPinPropertyMulti: cannot get property", hr); - - *ppKsMultipleItem = (PKSMULTIPLE_ITEM) new BYTE[cbMultipleItem]; - - ULONG ulReturned = 0; - hr = ::DeviceIoControl( - m_handle, - IOCTL_KS_PROPERTY, - &ksPProp, - sizeof(KSP_PIN), - (PVOID)*ppKsMultipleItem, - cbMultipleItem, - &ulReturned, - NULL); - if (FAILED(hr)) - throw ComException("CKsFilter::GetPinPropertyMulti: cannot get property", hr); - } - - std::string const& GetFriendlyName() const - { - return m_sFriendlyName; - } - -protected: - - std::vector m_Pins; // this list owns the pins. - - std::vector m_RenderPins; - std::vector m_CapturePins; - -private: - std::string const m_sFriendlyName; // friendly name eg "Virus TI Synth" - tstring const m_sName; // Filter path, eg "\\?\usb#vid_133e&pid_0815...\vtimidi02" -}; - -class CKsPin : public CKsObject -{ -public: - CKsPin(CKsFilter* pFilter, ULONG nId); - virtual ~CKsPin(); - - virtual void Instantiate(); - - void ClosePin(); - - void SetState(KSSTATE ksState); - - void WriteData(KSSTREAM_HEADER* pKSSTREAM_HEADER, OVERLAPPED* pOVERLAPPED); - void ReadData(KSSTREAM_HEADER* pKSSTREAM_HEADER, OVERLAPPED* pOVERLAPPED); - - KSPIN_DATAFLOW GetDataFlow() const - { - return m_DataFlow; - } - - bool IsSink() const - { - return m_Communication == KSPIN_COMMUNICATION_SINK - || m_Communication == KSPIN_COMMUNICATION_BOTH; - } - - -protected: - PKSPIN_CONNECT m_pKsPinConnect; // creation parameters of pin - CKsFilter* const m_pFilter; - - ULONG m_cInterfaces; - PKSIDENTIFIER m_pInterfaces; - PKSMULTIPLE_ITEM m_pmiInterfaces; - - ULONG m_cMediums; - PKSIDENTIFIER m_pMediums; - PKSMULTIPLE_ITEM m_pmiMediums; - - ULONG m_cDataRanges; - PKSDATARANGE m_pDataRanges; - PKSMULTIPLE_ITEM m_pmiDataRanges; - - KSPIN_DATAFLOW m_DataFlow; - KSPIN_COMMUNICATION m_Communication; -}; - -CKsFilter::CKsFilter(tstring const& sName, std::string const& sFriendlyName) : - CKsObject(INVALID_HANDLE_VALUE), - m_sFriendlyName(sFriendlyName), - m_sName(sName) -{ - if (sName.empty()) - throw std::runtime_error("CKsFilter::CKsFilter: name can't be empty"); -} - -CKsFilter::~CKsFilter() -{ - for (size_t i=0;i < m_Pins.size();++i) - delete m_Pins[i]; - - if (IsValid(m_handle)) - ::CloseHandle(m_handle); -} - -void CKsFilter::Instantiate() -{ - m_handle = CreateFile( - m_sName.c_str(), - GENERIC_READ | GENERIC_WRITE, - 0, - NULL, - OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, - NULL); - - if (!IsValid(m_handle)) - { - DWORD const dwError = GetLastError(); - throw ComException("CKsFilter::Instantiate: can't open driver", HRESULT_FROM_WIN32(dwError)); - } -} - -CKsPin::CKsPin(CKsFilter* pFilter, ULONG PinId) : - CKsObject(INVALID_HANDLE_VALUE), - m_pKsPinConnect(NULL), - m_pFilter(pFilter) -{ - m_Communication = m_pFilter->GetPinProperty(PinId, KSPROPERTY_PIN_COMMUNICATION); - m_DataFlow = m_pFilter->GetPinProperty(PinId, KSPROPERTY_PIN_DATAFLOW); - - // Interfaces - m_pFilter->GetPinPropertyMulti( - PinId, - KSPROPSETID_Pin, - KSPROPERTY_PIN_INTERFACES, - &m_pmiInterfaces); - - m_cInterfaces = m_pmiInterfaces->Count; - m_pInterfaces = (PKSPIN_INTERFACE)(m_pmiInterfaces + 1); - - // Mediums - m_pFilter->GetPinPropertyMulti( - PinId, - KSPROPSETID_Pin, - KSPROPERTY_PIN_MEDIUMS, - &m_pmiMediums); - - m_cMediums = m_pmiMediums->Count; - m_pMediums = (PKSPIN_MEDIUM)(m_pmiMediums + 1); - - // Data ranges - m_pFilter->GetPinPropertyMulti( - PinId, - KSPROPSETID_Pin, - KSPROPERTY_PIN_DATARANGES, - &m_pmiDataRanges); - - m_cDataRanges = m_pmiDataRanges->Count; - m_pDataRanges = (PKSDATARANGE)(m_pmiDataRanges + 1); -} - -CKsPin::~CKsPin() -{ - ClosePin(); - - delete[] (BYTE*)m_pKsPinConnect; - delete[] (BYTE*)m_pmiDataRanges; - delete[] (BYTE*)m_pmiInterfaces; - delete[] (BYTE*)m_pmiMediums; -} - -void CKsPin::ClosePin() -{ - if (IsValid(m_handle)) { - SetState(KSSTATE_STOP); - ::CloseHandle(m_handle); - } - m_handle = INVALID_HANDLE_VALUE; -} - -void CKsPin::SetState(KSSTATE ksState) -{ - SetProperty(KSPROPSETID_Connection, KSPROPERTY_CONNECTION_STATE, &ksState, sizeof(ksState)); -} - -void CKsPin::Instantiate() -{ - if (!m_pKsPinConnect) - throw std::runtime_error("CKsPin::Instanciate: abstract pin"); - - DWORD const dwResult = KsCreatePin(m_pFilter->m_handle, m_pKsPinConnect, GENERIC_WRITE | GENERIC_READ, &m_handle); - if (dwResult != ERROR_SUCCESS) - throw ComException("CKsMidiCapFilter::CreateRenderPin: Pin instanciation failed", HRESULT_FROM_WIN32(dwResult)); -} - -void CKsPin::WriteData(KSSTREAM_HEADER* pKSSTREAM_HEADER, OVERLAPPED* pOVERLAPPED) -{ - DWORD cbWritten; - BOOL fRes = ::DeviceIoControl( - m_handle, - IOCTL_KS_WRITE_STREAM, - NULL, - 0, - pKSSTREAM_HEADER, - pKSSTREAM_HEADER->Size, - &cbWritten, - pOVERLAPPED); - if (!fRes) { - DWORD const dwError = GetLastError(); - if (dwError != ERROR_IO_PENDING) - throw ComException("CKsPin::WriteData: DeviceIoControl failed", HRESULT_FROM_WIN32(dwError)); - } -} - -void CKsPin::ReadData(KSSTREAM_HEADER* pKSSTREAM_HEADER, OVERLAPPED* pOVERLAPPED) -{ - DWORD cbReturned; - BOOL fRes = ::DeviceIoControl( - m_handle, - IOCTL_KS_READ_STREAM, - NULL, - 0, - pKSSTREAM_HEADER, - pKSSTREAM_HEADER->Size, - &cbReturned, - pOVERLAPPED); - if (!fRes) { - DWORD const dwError = GetLastError(); - if (dwError != ERROR_IO_PENDING) - throw ComException("CKsPin::ReadData: DeviceIoControl failed", HRESULT_FROM_WIN32(dwError)); - } -} - -class CKsMidiFilter : public CKsFilter -{ -public: - void FindMidiPins(); - -protected: - CKsMidiFilter(tstring const& sPath, std::string const& sFriendlyName); -}; - -class CKsMidiPin : public CKsPin -{ -public: - CKsMidiPin(CKsFilter* pFilter, ULONG nId); -}; - -class CKsMidiRenFilter : public CKsMidiFilter -{ -public: - CKsMidiRenFilter(tstring const& sPath, std::string const& sFriendlyName); - CKsMidiPin* CreateRenderPin(); - - void Validate() - { - if (m_RenderPins.empty()) - throw std::runtime_error("Could not find a MIDI render pin"); - } -}; - -class CKsMidiCapFilter : public CKsMidiFilter -{ -public: - CKsMidiCapFilter(tstring const& sPath, std::string const& sFriendlyName); - CKsMidiPin* CreateCapturePin(); - - void Validate() - { - if (m_CapturePins.empty()) - throw std::runtime_error("Could not find a MIDI capture pin"); - } -}; - -CKsMidiFilter::CKsMidiFilter(tstring const& sPath, std::string const& sFriendlyName) : - CKsFilter(sPath, sFriendlyName) -{ -} - -void CKsMidiFilter::FindMidiPins() -{ - ULONG numPins = GetPinProperty(0, KSPROPERTY_PIN_CTYPES); - - for (ULONG iPin = 0; iPin < numPins; ++iPin) { - try { - KSPIN_COMMUNICATION com = GetPinProperty(iPin, KSPROPERTY_PIN_COMMUNICATION); - if (com != KSPIN_COMMUNICATION_SINK && com != KSPIN_COMMUNICATION_BOTH) - throw std::runtime_error("Unknown pin communication value"); - - m_Pins.push_back(new CKsMidiPin(this, iPin)); - } - catch (std::runtime_error const&) { - // pin instanciation has failed, continue to the next pin. - } - } - - m_RenderPins.clear(); - m_CapturePins.clear(); - - for (size_t i = 0; i < m_Pins.size(); ++i) { - CKsPin* const pPin = m_Pins[i]; - - if (pPin->IsSink()) { - if (pPin->GetDataFlow() == KSPIN_DATAFLOW_IN) - m_RenderPins.push_back(pPin); - else - m_CapturePins.push_back(pPin); - } - } - - if (m_RenderPins.empty() && m_CapturePins.empty()) - throw std::runtime_error("No valid pins found on the filter."); -} - -CKsMidiRenFilter::CKsMidiRenFilter(tstring const& sPath, std::string const& sFriendlyName) : - CKsMidiFilter(sPath, sFriendlyName) -{ -} - -CKsMidiPin* CKsMidiRenFilter::CreateRenderPin() -{ - if (m_RenderPins.empty()) - throw std::runtime_error("Could not find a MIDI render pin"); - - CKsMidiPin* pPin = (CKsMidiPin*)m_RenderPins[0]; - pPin->Instantiate(); - return pPin; -} - -CKsMidiCapFilter::CKsMidiCapFilter(tstring const& sPath, std::string const& sFriendlyName) : - CKsMidiFilter(sPath, sFriendlyName) -{ -} - -CKsMidiPin* CKsMidiCapFilter::CreateCapturePin() -{ - if (m_CapturePins.empty()) - throw std::runtime_error("Could not find a MIDI capture pin"); - - CKsMidiPin* pPin = (CKsMidiPin*)m_CapturePins[0]; - pPin->Instantiate(); - return pPin; -} - -CKsMidiPin::CKsMidiPin(CKsFilter* pFilter, ULONG nId) : - CKsPin(pFilter, nId) -{ - DWORD const cbPinCreateSize = sizeof(KSPIN_CONNECT) + sizeof(KSDATAFORMAT); - m_pKsPinConnect = (PKSPIN_CONNECT) new BYTE[cbPinCreateSize]; - - m_pKsPinConnect->Interface.Set = KSINTERFACESETID_Standard; - m_pKsPinConnect->Interface.Id = KSINTERFACE_STANDARD_STREAMING; - m_pKsPinConnect->Interface.Flags = 0; - m_pKsPinConnect->Medium.Set = KSMEDIUMSETID_Standard; - m_pKsPinConnect->Medium.Id = KSMEDIUM_TYPE_ANYINSTANCE; - m_pKsPinConnect->Medium.Flags = 0; - m_pKsPinConnect->PinId = nId; - m_pKsPinConnect->PinToHandle = NULL; - m_pKsPinConnect->Priority.PriorityClass = KSPRIORITY_NORMAL; - m_pKsPinConnect->Priority.PrioritySubClass = 1; - - // point m_pDataFormat to just after the pConnect struct - KSDATAFORMAT* m_pDataFormat = (KSDATAFORMAT*)(m_pKsPinConnect + 1); - m_pDataFormat->FormatSize = sizeof(KSDATAFORMAT); - m_pDataFormat->Flags = 0; - m_pDataFormat->SampleSize = 0; - m_pDataFormat->Reserved = 0; - m_pDataFormat->MajorFormat = GUID(KSDATAFORMAT_TYPE_MUSIC); - m_pDataFormat->SubFormat = GUID(KSDATAFORMAT_SUBTYPE_MIDI); - m_pDataFormat->Specifier = GUID(KSDATAFORMAT_SPECIFIER_NONE); - - bool hasStdStreamingInterface = false; - bool hasStdStreamingMedium = false; - - for ( ULONG i = 0; i < m_cInterfaces; i++ ) { - if (m_pInterfaces[i].Set == KSINTERFACESETID_Standard - && m_pInterfaces[i].Id == KSINTERFACE_STANDARD_STREAMING) - hasStdStreamingInterface = true; - } - - for (ULONG i = 0; i < m_cMediums; i++) { - if (m_pMediums[i].Set == KSMEDIUMSETID_Standard - && m_pMediums[i].Id == KSMEDIUM_STANDARD_DEVIO) - hasStdStreamingMedium = true; - } - - if (!hasStdStreamingInterface) // No standard streaming interfaces on the pin - throw std::runtime_error("CKsMidiPin::CKsMidiPin: no standard streaming interface"); - - if (!hasStdStreamingMedium) // No standard streaming mediums on the pin - throw std::runtime_error("CKsMidiPin::CKsMidiPin: no standard streaming medium"); - - bool hasMidiDataRange = false; - - BYTE const* pDataRangePtr = reinterpret_cast(m_pDataRanges); - - for (ULONG i = 0; i < m_cDataRanges; ++i) { - KSDATARANGE const* pDataRange = reinterpret_cast(pDataRangePtr); - - if (pDataRange->SubFormat == KSDATAFORMAT_SUBTYPE_MIDI) { - hasMidiDataRange = true; - break; - } - - pDataRangePtr += pDataRange->FormatSize; - } - - if (!hasMidiDataRange) // No MIDI dataranges on the pin - throw std::runtime_error("CKsMidiPin::CKsMidiPin: no MIDI datarange"); -} - - -struct WindowsKsData -{ - WindowsKsData() : m_pPin(NULL), m_Buffer(1024), m_hInputThread(NULL) - { - memset(&overlapped, 0, sizeof(OVERLAPPED)); - m_hExitEvent = ::CreateEvent(NULL, FALSE, FALSE, NULL); - overlapped.hEvent = ::CreateEvent(NULL, FALSE, FALSE, NULL); - m_hInputThread = NULL; - } - - ~WindowsKsData() - { - ::CloseHandle(overlapped.hEvent); - ::CloseHandle(m_hExitEvent); - } - - OVERLAPPED overlapped; - CKsPin* m_pPin; - std::vector m_Buffer; - std::auto_ptr > m_pCaptureEnum; - std::auto_ptr > m_pRenderEnum; - HANDLE m_hInputThread; - HANDLE m_hExitEvent; -}; - -// *********************************************************************// -// API: WINDOWS Kernel Streaming -// Class Definitions: MidiInWinKS -// *********************************************************************// - -static DWORD WINAPI midiKsInputThread(VOID* pUser) -{ - MidiInApi::RtMidiInData* data = static_cast(pUser); - WindowsKsData* apiData = static_cast(data->apiData); - - HANDLE hEvents[] = { apiData->overlapped.hEvent, apiData->m_hExitEvent }; - - while ( true ) { - KSSTREAM_HEADER packet; - memset(&packet, 0, sizeof packet); - packet.Size = sizeof(KSSTREAM_HEADER); - packet.PresentationTime.Time = 0; - packet.PresentationTime.Numerator = 1; - packet.PresentationTime.Denominator = 1; - packet.Data = &apiData->m_Buffer[0]; - packet.DataUsed = 0; - packet.FrameExtent = apiData->m_Buffer.size(); - apiData->m_pPin->ReadData(&packet, &apiData->overlapped); - - DWORD dwRet = ::WaitForMultipleObjects(2, hEvents, FALSE, INFINITE); - - if ( dwRet == WAIT_OBJECT_0 ) { - // parse packet - unsigned char* pData = (unsigned char*)packet.Data; - unsigned int iOffset = 0; - - while ( iOffset < packet.DataUsed ) { - KSMUSICFORMAT* pMusic = (KSMUSICFORMAT*)&pData[iOffset]; - iOffset += sizeof(KSMUSICFORMAT); - - MidiInApi::MidiMessage message; - message.timeStamp = 0; - for(size_t i=0;i < pMusic->ByteCount;++i) - message.bytes.push_back(pData[iOffset+i]); - - if ( data->usingCallback ) { - RtMidiIn::RtMidiCallback callback = (RtMidiIn::RtMidiCallback)data->userCallback; - callback(message.timeStamp, &message.bytes, data->userData); - } - else { - // As long as we haven't reached our queue size limit, push the message. - if ( data->queue.size < data->queue.ringSize ) { - data->queue.ring[data->queue.back++] = message; - if(data->queue.back == data->queue.ringSize) - data->queue.back = 0; - data->queue.size++; - } - else - std::cerr << "\nRtMidiIn: message queue limit reached!!\n\n"; - } - - iOffset += pMusic->ByteCount; - - // re-align on 32 bits - if ( iOffset % 4 != 0 ) - iOffset += (4 - iOffset % 4); - } - } - else - break; - } - return 0; -} - -MidiInWinKS :: MidiInWinKS( const std::string clientName, unsigned int queueSizeLimit ) : MidiInApi( queueSizeLimit ) -{ - initialize( clientName ); -} - -void MidiInWinKS :: initialize( const std::string& clientName ) -{ - WindowsKsData* data = new WindowsKsData; - apiData_ = (void*)data; - inputData_.apiData = data; - - GUID const aguidEnumCats[] = - { - { STATIC_KSCATEGORY_AUDIO }, { STATIC_KSCATEGORY_CAPTURE } - }; - data->m_pCaptureEnum.reset(new CKsEnumFilters ); - data->m_pCaptureEnum->EnumFilters(aguidEnumCats, 2); -} - -MidiInWinKS :: ~MidiInWinKS() -{ - WindowsKsData* data = static_cast(apiData_); - try { - if ( data->m_pPin ) - closePort(); - } - catch(...) { - } - - delete data; -} - -void MidiInWinKS :: openPort( unsigned int portNumber, const std::string portName ) -{ - WindowsKsData* data = static_cast(apiData_); - - if ( portNumber < 0 || portNumber >= data->m_pCaptureEnum->m_Filters.size() ) { - std::stringstream ost; - ost << "MidiInWinKS::openPort: the 'portNumber' argument (" << portNumber << ") is invalid."; - errorString_ = ost.str(); - error( RtMidiError::WARNING, errorString_ ); - return; - } - - CKsMidiCapFilter* pFilter = data->m_pCaptureEnum->m_Filters[portNumber]; - data->m_pPin = pFilter->CreateCapturePin(); - - if ( data->m_pPin == NULL ) { - std::stringstream ost; - ost << "MidiInWinKS::openPort: KS error opening port (could not create pin)"; - errorString_ = ost.str(); - error( RtMidiError::WARNING, errorString_ ); - return; - } - - data->m_pPin->SetState(KSSTATE_RUN); - - DWORD threadId; - data->m_hInputThread = ::CreateThread(NULL, 0, &midiKsInputThread, &inputData_, 0, &threadId); - if ( data->m_hInputThread == NULL ) { - std::stringstream ost; - ost << "MidiInWinKS::openPort: Could not create input thread : Windows error " << GetLastError() << std::endl;; - errorString_ = ost.str(); - error( RtMidiError::WARNING, errorString_ ); - return; - } - - connected_ = true; -} - -void MidiInWinKS :: openVirtualPort( const std::string portName ) -{ - // This function cannot be implemented for the Windows KS MIDI API. - errorString_ = "MidiInWinKS::openVirtualPort: cannot be implemented in Windows KS MIDI API!"; - error( RtMidiError::WARNING, errorString_ ); -} - -unsigned int MidiInWinKS :: getPortCount() -{ - WindowsKsData* data = static_cast(apiData_); - return (unsigned int)data->m_pCaptureEnum->m_Filters.size(); -} - -std::string MidiInWinKS :: getPortName(unsigned int portNumber) -{ - WindowsKsData* data = static_cast(apiData_); - - if (portNumber < 0 || portNumber >= data->m_pCaptureEnum->m_Filters.size()) { - std::stringstream ost; - ost << "MidiInWinKS::getPortName: the 'portNumber' argument (" << portNumber << ") is invalid."; - errorString_ = ost.str(); - error( RtMidiError::WARNING, errorString_ ); - return; - } - - CKsMidiCapFilter* pFilter = data->m_pCaptureEnum->m_Filters[portNumber]; - return pFilter->GetFriendlyName(); -} - -void MidiInWinKS :: closePort() -{ - WindowsKsData* data = static_cast(apiData_); - connected_ = false; - - if (data->m_hInputThread) { - ::SignalObjectAndWait(data->m_hExitEvent, data->m_hInputThread, INFINITE, FALSE); - ::CloseHandle(data->m_hInputThread); - } - - if (data->m_pPin) { - data->m_pPin->SetState(KSSTATE_PAUSE); - data->m_pPin->SetState(KSSTATE_STOP); - data->m_pPin->ClosePin(); - data->m_pPin = NULL; - } -} - -// *********************************************************************// -// API: WINDOWS Kernel Streaming -// Class Definitions: MidiOutWinKS -// *********************************************************************// - -MidiOutWinKS :: MidiOutWinKS( const std::string clientName ) : MidiOutApi() -{ - initialize( clientName ); -} - -void MidiOutWinKS :: initialize( const std::string& clientName ) -{ - WindowsKsData* data = new WindowsKsData; - - data->m_pPin = NULL; - data->m_pRenderEnum.reset(new CKsEnumFilters ); - GUID const aguidEnumCats[] = - { - { STATIC_KSCATEGORY_AUDIO }, { STATIC_KSCATEGORY_RENDER } - }; - data->m_pRenderEnum->EnumFilters(aguidEnumCats, 2); - - apiData_ = (void*)data; -} - -MidiOutWinKS :: ~MidiOutWinKS() -{ - // Close a connection if it exists. - closePort(); - - // Cleanup. - WindowsKsData* data = static_cast(apiData_); - delete data; -} - -void MidiOutWinKS :: openPort( unsigned int portNumber, const std::string portName ) -{ - WindowsKsData* data = static_cast(apiData_); - - if (portNumber < 0 || portNumber >= data->m_pRenderEnum->m_Filters.size()) { - std::stringstream ost; - ost << "MidiOutWinKS::openPort: the 'portNumber' argument (" << portNumber << ") is invalid."; - errorString_ = ost.str(); - error( RtMidiError::WARNING, errorString_ ); - return; - } - - CKsMidiRenFilter* pFilter = data->m_pRenderEnum->m_Filters[portNumber]; - data->m_pPin = pFilter->CreateRenderPin(); - - if (data->m_pPin == NULL) { - std::stringstream ost; - ost << "MidiOutWinKS::openPort: KS error opening port (could not create pin)"; - errorString_ = ost.str(); - error( RtMidiError::WARNING, errorString_ ); - return; - } - - data->m_pPin->SetState(KSSTATE_RUN); - connected_ = true; -} - -void MidiOutWinKS :: openVirtualPort( const std::string portName ) -{ - // This function cannot be implemented for the Windows KS MIDI API. - errorString_ = "MidiOutWinKS::openVirtualPort: cannot be implemented in Windows KS MIDI API!"; - error( RtMidiError::WARNING, errorString_ ); -} - -unsigned int MidiOutWinKS :: getPortCount() -{ - WindowsKsData* data = static_cast(apiData_); - return (unsigned int)data->m_pRenderEnum->m_Filters.size(); -} - -std::string MidiOutWinKS :: getPortName( unsigned int portNumber ) -{ - WindowsKsData* data = static_cast(apiData_); - - if ( portNumber < 0 || portNumber >= data->m_pRenderEnum->m_Filters.size() ) { - std::stringstream ost; - ost << "MidiOutWinKS::getPortName: the 'portNumber' argument (" << portNumber << ") is invalid."; - errorString_ = ost.str(); - error( RtMidiError::WARNING, errorString_ ); - return; - } - - CKsMidiRenFilter* pFilter = data->m_pRenderEnum->m_Filters[portNumber]; - return pFilter->GetFriendlyName(); -} - -void MidiOutWinKS :: closePort() -{ - WindowsKsData* data = static_cast(apiData_); - connected_ = false; - - if ( data->m_pPin ) { - data->m_pPin->SetState(KSSTATE_PAUSE); - data->m_pPin->SetState(KSSTATE_STOP); - data->m_pPin->ClosePin(); - data->m_pPin = NULL; - } -} - -void MidiOutWinKS :: sendMessage(std::vector* pMessage) -{ - std::vector const& msg = *pMessage; - WindowsKsData* data = static_cast(apiData_); - size_t iNumMidiBytes = msg.size(); - size_t pos = 0; - - // write header - KSMUSICFORMAT* pKsMusicFormat = reinterpret_cast(&data->m_Buffer[pos]); - pKsMusicFormat->TimeDeltaMs = 0; - pKsMusicFormat->ByteCount = iNumMidiBytes; - pos += sizeof(KSMUSICFORMAT); - - // write MIDI bytes - if ( pos + iNumMidiBytes > data->m_Buffer.size() ) { - std::stringstream ost; - ost << "KsMidiInput::Write: MIDI buffer too small. Required " << pos + iNumMidiBytes << " bytes, only has " << data->m_Buffer.size(); - errorString_ = ost.str(); - error( RtMidiError::WARNING, errorString_ ); - return; - } - - if ( data->m_pPin == NULL ) { - std::stringstream ost; - ost << "MidiOutWinKS::sendMessage: port is not open"; - errorString_ = ost.str(); - error( RtMidiError::WARNING, errorString_ ); - return; - } - - memcpy(&data->m_Buffer[pos], &msg[0], iNumMidiBytes); - pos += iNumMidiBytes; - - KSSTREAM_HEADER packet; - memset(&packet, 0, sizeof packet); - packet.Size = sizeof(packet); - packet.PresentationTime.Time = 0; - packet.PresentationTime.Numerator = 1; - packet.PresentationTime.Denominator = 1; - packet.Data = const_cast(&data->m_Buffer[0]); - packet.DataUsed = ((pos+3)/4)*4; - packet.FrameExtent = data->m_Buffer.size(); - - data->m_pPin->WriteData(&packet, NULL); -} - -#endif // __WINDOWS_KS__ //*********************************************************************// // API: UNIX JACK diff --git a/RtMidi.h b/RtMidi.h index 99dc38c1..61418350 100644 --- a/RtMidi.h +++ b/RtMidi.h @@ -124,7 +124,6 @@ class RtMidi LINUX_ALSA, /*!< The Advanced Linux Sound Architecture API. */ UNIX_JACK, /*!< The JACK Low-Latency MIDI Server API. */ WINDOWS_MM, /*!< The Microsoft Multimedia MIDI API. */ - WINDOWS_KS, /*!< The Microsoft Kernel Streaming MIDI API. */ RTMIDI_DUMMY /*!< A compilable but non-functional API. */ }; @@ -566,7 +565,7 @@ inline void RtMidiOut :: setErrorCallback( RtMidiErrorCallback errorCallback ) { // // **************************************************************** // -#if !defined(__LINUX_ALSA__) && !defined(__UNIX_JACK__) && !defined(__MACOSX_CORE__) && !defined(__WINDOWS_MM__) && !defined(__WINDOWS_KS__) +#if !defined(__LINUX_ALSA__) && !defined(__UNIX_JACK__) && !defined(__MACOSX_CORE__) && !defined(__WINDOWS_MM__) #define __RTMIDI_DUMMY__ #endif @@ -724,43 +723,6 @@ class MidiOutWinMM: public MidiOutApi #endif -#if defined(__WINDOWS_KS__) - -class MidiInWinKS: public MidiInApi -{ - public: - MidiInWinKS( const std::string clientName, unsigned int queueSizeLimit ); - ~MidiInWinKS( void ); - RtMidi::Api getCurrentApi( void ) { return RtMidi::WINDOWS_KS; }; - void openPort( unsigned int portNumber, const std::string portName ); - void openVirtualPort( const std::string portName ); - void closePort( void ); - unsigned int getPortCount( void ); - std::string getPortName( unsigned int portNumber ); - - protected: - void initialize( const std::string& clientName ); -}; - -class MidiOutWinKS: public MidiOutApi -{ - public: - MidiOutWinKS( const std::string clientName ); - ~MidiOutWinKS( void ); - RtMidi::Api getCurrentApi( void ) { return RtMidi::WINDOWS_KS; }; - void openPort( unsigned int portNumber, const std::string portName ); - void openVirtualPort( const std::string portName ); - void closePort( void ); - unsigned int getPortCount( void ); - std::string getPortName( unsigned int portNumber ); - void sendMessage( std::vector *message ); - - protected: - void initialize( const std::string& clientName ); -}; - -#endif - #if defined(__RTMIDI_DUMMY__) class MidiInDummy: public MidiInApi diff --git a/doc/doxygen/tutorial.txt b/doc/doxygen/tutorial.txt index d6dc8266..aba7f3bd 100644 --- a/doc/doxygen/tutorial.txt +++ b/doc/doxygen/tutorial.txt @@ -4,7 +4,7 @@ \section intro Introduction -RtMidi is a set of C++ classes (RtMidiIn, RtMidiOut and API-specific classes) that provides a common API (Application Programming Interface) for realtime MIDI input/output across Linux (ALSA & JACK), Macintosh OS X (CoreMIDI & JACK), and Windows (Multimedia Library & Kernel Streaming) operating systems. RtMidi significantly simplifies the process of interacting with computer MIDI hardware and software. It was designed with the following goals: +RtMidi is a set of C++ classes (RtMidiIn, RtMidiOut and API-specific classes) that provides a common API (Application Programming Interface) for realtime MIDI input/output across Linux (ALSA & JACK), Macintosh OS X (CoreMIDI & JACK), and Windows (Multimedia Library) operating systems. RtMidi significantly simplifies the process of interacting with computer MIDI hardware and software. It was designed with the following goals:
  • object oriented C++ design
  • @@ -19,7 +19,7 @@ MIDI input and output functionality are separated into two classes, RtMidiIn and \section whatsnew What's New (Version 2.1) -A minor API change was made. The RtError class was renamed RtMidiError and embedded directly in RtMidi.h. Thus, all references to RtError should be renamed to RtMidiError and the RtError.h file should be deleted. +A minor API change was made. The RtError class was renamed RtMidiError and embedded directly in RtMidi.h. Thus, all references to RtError should be renamed to RtMidiError and the RtError.h file should be deleted. The Windows Kernel Streaming support was removed because it was uncompilable and incomplete. \section download Download @@ -375,13 +375,6 @@ In order to compile RtMidi for a specific OS and API, it is necessary to supply winmm.lib, multithreaded compiler specific - - Windows - Kernel Streaming - __WINDOWS_KS__ - ks.h, ksmedia.h, setupapi.lib, ksuser.lib, multithreaded - compiler specific -

    @@ -393,7 +386,7 @@ If you are having problems getting RtMidi to run on your system, try passing the \section multi Using Simultaneous Multiple APIs -Support for each MIDI API is encapsulated in specific MidiInApi or MidiOutApi subclasses, making it possible to compile and instantiate multiple API-specific subclasses on a given operating system. For example, one can compile both CoreMIDI and JACK support on the OS-X operating system by providing the appropriate preprocessor definitions for each. In a run-time situation, one might first attempt to determine whether any JACK ports are available. This can be done by specifying the api argument RtMidi::UNIX_JACK when attempting to create an instance of RtMidiIn or RtMidiOut. If no available ports are found, then an instance of RtMidi with the api argument RtMidi::MACOSX_CORE can be created. Alternately, if no api argument is specified, RtMidi will first look for JACK ports and if none are found, then CoreMIDI ports (in linux, the search order is JACK and then ALSA; in Windows, the search order is WinMM and then WinKS). In theory, it should also be possible to have separate instances of RtMidi open at the same time with different underlying API support, though this has not been tested. +Support for each MIDI API is encapsulated in specific MidiInApi or MidiOutApi subclasses, making it possible to compile and instantiate multiple API-specific subclasses on a given operating system. For example, one can compile both CoreMIDI and JACK support on the OS-X operating system by providing the appropriate preprocessor definitions for each. In a run-time situation, one might first attempt to determine whether any JACK ports are available. This can be done by specifying the api argument RtMidi::UNIX_JACK when attempting to create an instance of RtMidiIn or RtMidiOut. If no available ports are found, then an instance of RtMidi with the api argument RtMidi::MACOSX_CORE can be created. Alternately, if no api argument is specified, RtMidi will first look for JACK ports and if none are found, then CoreMIDI ports (in linux, the search order is JACK and then ALSA. In theory, it should also be possible to have separate instances of RtMidi open at the same time with different underlying API support, though this has not been tested. The static function RtMidi::getCompiledApi() is provided to determine the available compiled API support. The function RtMidi::getCurrentApi() indicates the API selected for a given RtMidi instance. diff --git a/doc/release.txt b/doc/release.txt index 83debcc9..d08f706e 100644 --- a/doc/release.txt +++ b/doc/release.txt @@ -16,6 +16,7 @@ v2.1.0: (30 March 2014) - Windows update to avoid lockups when shutting down while sending/receiving sysex messages (ptarabbia) - OS-X fix to avoid empty messages in callbacks when ignoring sysex messages and split sysexes are received (codepainters) - ALSA openPort fix to better distinguish sender and receiver (Russell Smyth) +- Windows Kernel Streaming support removed because it was uncompilable and incomplete v2.0.1: (26 July 2012) - small fixes for problems reported by Chris Arndt (scoping, preprocessor, and include) diff --git a/readme b/readme index 69f095b0..4d56ed58 100644 --- a/readme +++ b/readme @@ -1,4 +1,4 @@ -RtMidi - a set of C++ classes that provide a common API for realtime MIDI input/output across Linux (ALSA & JACK), Macintosh OS X (CoreMidi & JACK) and Windows (Multimedia & Kernel Streaming). +RtMidi - a set of C++ classes that provide a common API for realtime MIDI input/output across Linux (ALSA & JACK), Macintosh OS X (CoreMidi & JACK) and Windows (Multimedia). By Gary P. Scavone, 2003-2014. From 290db6cd3ead705fd117a72d589426d22ba23f8e Mon Sep 17 00:00:00 2001 From: Gary Scavone Date: Sun, 30 Mar 2014 13:02:08 -0400 Subject: [PATCH 03/45] Deleted include directory with kernel streaming files. --- include/ks.h | 3577 --------------------------------- include/ksmedia.h | 4824 --------------------------------------------- 2 files changed, 8401 deletions(-) delete mode 100644 include/ks.h delete mode 100644 include/ksmedia.h diff --git a/include/ks.h b/include/ks.h deleted file mode 100644 index 1f8b8b45..00000000 --- a/include/ks.h +++ /dev/null @@ -1,3577 +0,0 @@ -/** - * This file has no copyright assigned and is placed in the Public Domain. - * This file is part of the w64 mingw-runtime package. - * No warranty is given. - */ -#ifndef _KS_ -#define _KS_ - -#include - -#if __GNUC__ >= 3 - # pragma GCC system_header -#endif - -#ifndef __MINGW_EXTENSION - # if defined(__GNUC__) || defined(__GNUG__) - # define __MINGW_EXTENSION __extension__ - # else - # define __MINGW_EXTENSION - # endif -#endif - -#ifdef __TCS__ - # define _KS_NO_ANONYMOUS_STRUCTURES_ 1 -#endif - -#ifdef _KS_NO_ANONYMOUS_STRUCTURES_ - # define _KS_ANON_STRUCT(X) struct X -#else - # define _KS_ANON_STRUCT(X) __MINGW_EXTENSION struct -#endif - -#ifndef _NTRTL_ - # ifndef DEFINE_GUIDEX - # define DEFINE_GUIDEX(name) EXTERN_C const GUID name - # endif - # ifndef STATICGUIDOF - # define STATICGUIDOF(guid) STATIC_ ## guid - # endif -#endif /* _NTRTL_ */ - -#ifndef SIZEOF_ARRAY - # define SIZEOF_ARRAY(ar) (sizeof(ar) / sizeof((ar)[0])) -#endif - -#define DEFINE_GUIDSTRUCT(g, n) DEFINE_GUIDEX(n) -#define DEFINE_GUIDNAMED(n) n - -#define STATIC_GUID_NULL \ - 0x00000000L, 0x0000, 0x0000, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } - -DEFINE_GUIDSTRUCT("00000000-0000-0000-0000-000000000000", GUID_NULL); -#define GUID_NULL DEFINE_GUIDNAMED(GUID_NULL) - -#define IOCTL_KS_PROPERTY CTL_CODE(FILE_DEVICE_KS, 0x000, METHOD_NEITHER, FILE_ANY_ACCESS) -#define IOCTL_KS_ENABLE_EVENT CTL_CODE(FILE_DEVICE_KS, 0x001, METHOD_NEITHER, FILE_ANY_ACCESS) -#define IOCTL_KS_DISABLE_EVENT CTL_CODE(FILE_DEVICE_KS, 0x002, METHOD_NEITHER, FILE_ANY_ACCESS) -#define IOCTL_KS_METHOD CTL_CODE(FILE_DEVICE_KS, 0x003, METHOD_NEITHER, FILE_ANY_ACCESS) -#define IOCTL_KS_WRITE_STREAM CTL_CODE(FILE_DEVICE_KS, 0x004, METHOD_NEITHER, FILE_WRITE_ACCESS) -#define IOCTL_KS_READ_STREAM CTL_CODE(FILE_DEVICE_KS, 0x005, METHOD_NEITHER, FILE_READ_ACCESS) -#define IOCTL_KS_RESET_STATE CTL_CODE(FILE_DEVICE_KS, 0x006, METHOD_NEITHER, FILE_ANY_ACCESS) - -typedef enum -{ - KSRESET_BEGIN, - KSRESET_END -}KSRESET; - -typedef enum -{ - KSSTATE_STOP, - KSSTATE_ACQUIRE, - KSSTATE_PAUSE, - KSSTATE_RUN -}KSSTATE, * PKSSTATE; - -#define KSPRIORITY_LOW 0x00000001 -#define KSPRIORITY_NORMAL 0x40000000 -#define KSPRIORITY_HIGH 0x80000000 -#define KSPRIORITY_EXCLUSIVE 0xFFFFFFFF - -typedef struct -{ - ULONG PriorityClass; - ULONG PrioritySubClass; -}KSPRIORITY, * PKSPRIORITY; - -typedef struct -{ - __MINGW_EXTENSION union - { - _KS_ANON_STRUCT(_IDENTIFIER) - { - GUID Set; - ULONG Id; - ULONG Flags; - }; - LONGLONG Alignment; - }; -}KSIDENTIFIER, * PKSIDENTIFIER; - -typedef KSIDENTIFIER KSPROPERTY, * PKSPROPERTY, KSMETHOD, * PKSMETHOD, KSEVENT, * PKSEVENT; - -#define KSMETHOD_TYPE_NONE 0x00000000 -#define KSMETHOD_TYPE_READ 0x00000001 -#define KSMETHOD_TYPE_WRITE 0x00000002 -#define KSMETHOD_TYPE_MODIFY 0x00000003 -#define KSMETHOD_TYPE_SOURCE 0x00000004 - -#define KSMETHOD_TYPE_SEND 0x00000001 -#define KSMETHOD_TYPE_SETSUPPORT 0x00000100 -#define KSMETHOD_TYPE_BASICSUPPORT 0x00000200 - -#define KSMETHOD_TYPE_TOPOLOGY 0x10000000 - -#define KSPROPERTY_TYPE_GET 0x00000001 -#define KSPROPERTY_TYPE_SET 0x00000002 -#define KSPROPERTY_TYPE_SETSUPPORT 0x00000100 -#define KSPROPERTY_TYPE_BASICSUPPORT 0x00000200 -#define KSPROPERTY_TYPE_RELATIONS 0x00000400 -#define KSPROPERTY_TYPE_SERIALIZESET 0x00000800 -#define KSPROPERTY_TYPE_UNSERIALIZESET 0x00001000 -#define KSPROPERTY_TYPE_SERIALIZERAW 0x00002000 -#define KSPROPERTY_TYPE_UNSERIALIZERAW 0x00004000 -#define KSPROPERTY_TYPE_SERIALIZESIZE 0x00008000 -#define KSPROPERTY_TYPE_DEFAULTVALUES 0x00010000 - -#define KSPROPERTY_TYPE_TOPOLOGY 0x10000000 - -typedef struct -{ - KSPROPERTY Property; - ULONG NodeId; - ULONG Reserved; -}KSP_NODE, * PKSP_NODE; - -typedef struct -{ - KSMETHOD Method; - ULONG NodeId; - ULONG Reserved; -}KSM_NODE, * PKSM_NODE; - -typedef struct -{ - KSEVENT Event; - ULONG NodeId; - ULONG Reserved; -}KSE_NODE, * PKSE_NODE; - -#define STATIC_KSPROPTYPESETID_General \ - 0x97E99BA0L, 0xBDEA, 0x11CF, 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00 -DEFINE_GUIDSTRUCT("97E99BA0-BDEA-11CF-A5D6-28DB04C10000", KSPROPTYPESETID_General); -#define KSPROPTYPESETID_General DEFINE_GUIDNAMED(KSPROPTYPESETID_General) - -typedef struct -{ - ULONG Size; - ULONG Count; -}KSMULTIPLE_ITEM, * PKSMULTIPLE_ITEM; - -typedef struct -{ - ULONG AccessFlags; - ULONG DescriptionSize; - KSIDENTIFIER PropTypeSet; - ULONG MembersListCount; - ULONG Reserved; -}KSPROPERTY_DESCRIPTION, * PKSPROPERTY_DESCRIPTION; - -#define KSPROPERTY_MEMBER_RANGES 0x00000001 -#define KSPROPERTY_MEMBER_STEPPEDRANGES 0x00000002 -#define KSPROPERTY_MEMBER_VALUES 0x00000003 - -#define KSPROPERTY_MEMBER_FLAG_DEFAULT 0x00000001 -#define KSPROPERTY_MEMBER_FLAG_BASICSUPPORT_MULTICHANNEL 0x00000002 -#define KSPROPERTY_MEMBER_FLAG_BASICSUPPORT_UNIFORM 0x00000004 - -typedef struct -{ - ULONG MembersFlags; - ULONG MembersSize; - ULONG MembersCount; - ULONG Flags; -}KSPROPERTY_MEMBERSHEADER, * PKSPROPERTY_MEMBERSHEADER; - -typedef union -{ - _KS_ANON_STRUCT(_SIGNED) - { - LONG SignedMinimum; - LONG SignedMaximum; - }; - _KS_ANON_STRUCT(_UNSIGNED) - { - ULONG UnsignedMinimum; - ULONG UnsignedMaximum; - }; -}KSPROPERTY_BOUNDS_LONG, * PKSPROPERTY_BOUNDS_LONG; - -typedef union -{ - _KS_ANON_STRUCT(_SIGNED64) - { - LONGLONG SignedMinimum; - LONGLONG SignedMaximum; - }; - _KS_ANON_STRUCT(_UNSIGNED64) - { - DWORDLONG UnsignedMinimum; - DWORDLONG UnsignedMaximum; - }; -}KSPROPERTY_BOUNDS_LONGLONG, * PKSPROPERTY_BOUNDS_LONGLONG; - -typedef struct -{ - ULONG SteppingDelta; - ULONG Reserved; - KSPROPERTY_BOUNDS_LONG Bounds; -}KSPROPERTY_STEPPING_LONG, * PKSPROPERTY_STEPPING_LONG; - -typedef struct -{ - DWORDLONG SteppingDelta; - KSPROPERTY_BOUNDS_LONGLONG Bounds; -}KSPROPERTY_STEPPING_LONGLONG, * PKSPROPERTY_STEPPING_LONGLONG; - -#if defined(_NTDDK_) -typedef struct _KSDEVICE_DESCRIPTOR KSDEVICE_DESCRIPTOR, * PKSDEVICE_DESCRIPTOR; -typedef struct _KSDEVICE_DISPATCH KSDEVICE_DISPATCH, * PKSDEVICE_DISPATCH; -typedef struct _KSDEVICE KSDEVICE, * PKSDEVICE; -typedef struct _KSFILTERFACTORY KSFILTERFACTORY, * PKSFILTERFACTORY; -typedef struct _KSFILTER_DESCRIPTOR KSFILTER_DESCRIPTOR, * PKSFILTER_DESCRIPTOR; -typedef struct _KSFILTER_DISPATCH KSFILTER_DISPATCH, * PKSFILTER_DISPATCH; -typedef struct _KSFILTER KSFILTER, * PKSFILTER; -typedef struct _KSPIN_DESCRIPTOR_EX KSPIN_DESCRIPTOR_EX, * PKSPIN_DESCRIPTOR_EX; -typedef struct _KSPIN_DISPATCH KSPIN_DISPATCH, * PKSPIN_DISPATCH; -typedef struct _KSCLOCK_DISPATCH KSCLOCK_DISPATCH, * PKSCLOCK_DISPATCH; -typedef struct _KSALLOCATOR_DISPATCH KSALLOCATOR_DISPATCH, * PKSALLOCATOR_DISPATCH; -typedef struct _KSPIN KSPIN, * PKSPIN; -typedef struct _KSNODE_DESCRIPTOR KSNODE_DESCRIPTOR, * PKSNODE_DESCRIPTOR; -typedef struct _KSSTREAM_POINTER_OFFSET KSSTREAM_POINTER_OFFSET, * PKSSTREAM_POINTER_OFFSET; -typedef struct _KSSTREAM_POINTER KSSTREAM_POINTER, * PKSSTREAM_POINTER; -typedef struct _KSMAPPING KSMAPPING, * PKSMAPPING; -typedef struct _KSPROCESSPIN KSPROCESSPIN, * PKSPROCESSPIN; -typedef struct _KSPROCESSPIN_INDEXENTRY KSPROCESSPIN_INDEXENTRY, * PKSPROCESSPIN_INDEXENTRY; -#endif /* _NTDDK_ */ - -typedef PVOID PKSWORKER; - -typedef struct -{ - ULONG NotificationType; - __MINGW_EXTENSION union - { - struct - { - HANDLE Event; - ULONG_PTR Reserved[2]; - }EventHandle; - struct - { - HANDLE Semaphore; - ULONG Reserved; - LONG Adjustment; - }SemaphoreHandle; -#if defined(_NTDDK_) - struct - { - PVOID Event; - KPRIORITY Increment; - ULONG_PTR Reserved; - }EventObject; - struct - { - PVOID Semaphore; - KPRIORITY Increment; - LONG Adjustment; - }SemaphoreObject; - struct - { - PKDPC Dpc; - ULONG ReferenceCount; - ULONG_PTR Reserved; - }Dpc; - struct - { - PWORK_QUEUE_ITEM WorkQueueItem; - WORK_QUEUE_TYPE WorkQueueType; - ULONG_PTR Reserved; - }WorkItem; - struct - { - PWORK_QUEUE_ITEM WorkQueueItem; - PKSWORKER KsWorkerObject; - ULONG_PTR Reserved; - }KsWorkItem; -#endif /* _NTDDK_ */ - struct - { - PVOID Unused; - LONG_PTR Alignment[2]; - }Alignment; - }; -}KSEVENTDATA, * PKSEVENTDATA; - -#define KSEVENTF_EVENT_HANDLE 0x00000001 -#define KSEVENTF_SEMAPHORE_HANDLE 0x00000002 -#if defined(_NTDDK_) - # define KSEVENTF_EVENT_OBJECT 0x00000004 - # define KSEVENTF_SEMAPHORE_OBJECT 0x00000008 - # define KSEVENTF_DPC 0x00000010 - # define KSEVENTF_WORKITEM 0x00000020 - # define KSEVENTF_KSWORKITEM 0x00000080 -#endif /* _NTDDK_ */ - -#define KSEVENT_TYPE_ENABLE 0x00000001 -#define KSEVENT_TYPE_ONESHOT 0x00000002 -#define KSEVENT_TYPE_ENABLEBUFFERED 0x00000004 -#define KSEVENT_TYPE_SETSUPPORT 0x00000100 -#define KSEVENT_TYPE_BASICSUPPORT 0x00000200 -#define KSEVENT_TYPE_QUERYBUFFER 0x00000400 - -#define KSEVENT_TYPE_TOPOLOGY 0x10000000 - -typedef struct -{ - KSEVENT Event; - PKSEVENTDATA EventData; - PVOID Reserved; -}KSQUERYBUFFER, * PKSQUERYBUFFER; - -typedef struct -{ - ULONG Size; - ULONG Flags; - __MINGW_EXTENSION union - { - HANDLE ObjectHandle; - PVOID ObjectPointer; - }; - PVOID Reserved; - KSEVENT Event; - KSEVENTDATA EventData; -}KSRELATIVEEVENT; - -#define KSRELATIVEEVENT_FLAG_HANDLE 0x00000001 -#define KSRELATIVEEVENT_FLAG_POINTER 0x00000002 - -typedef struct -{ - KSEVENTDATA EventData; - LONGLONG MarkTime; -}KSEVENT_TIME_MARK, * PKSEVENT_TIME_MARK; - -typedef struct -{ - KSEVENTDATA EventData; - LONGLONG TimeBase; - LONGLONG Interval; -}KSEVENT_TIME_INTERVAL, * PKSEVENT_TIME_INTERVAL; - -typedef struct -{ - LONGLONG TimeBase; - LONGLONG Interval; -}KSINTERVAL, * PKSINTERVAL; - -#define STATIC_KSPROPSETID_General \ - 0x1464EDA5L, 0x6A8F, 0x11D1, 0x9A, 0xA7, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96 -DEFINE_GUIDSTRUCT("1464EDA5-6A8F-11D1-9AA7-00A0C9223196", KSPROPSETID_General); -#define KSPROPSETID_General DEFINE_GUIDNAMED(KSPROPSETID_General) - -typedef enum -{ - KSPROPERTY_GENERAL_COMPONENTID -}KSPROPERTY_GENERAL; - -typedef struct -{ - GUID Manufacturer; - GUID Product; - GUID Component; - GUID Name; - ULONG Version; - ULONG Revision; -}KSCOMPONENTID, * PKSCOMPONENTID; - -#define DEFINE_KSPROPERTY_ITEM_GENERAL_COMPONENTID(Handler) \ - DEFINE_KSPROPERTY_ITEM( \ - KSPROPERTY_GENERAL_COMPONENTID, \ - (Handler), \ - sizeof(KSPROPERTY), \ - sizeof(KSCOMPONENTID), \ - NULL, NULL, 0, NULL, NULL, 0) - -#define STATIC_KSMETHODSETID_StreamIo \ - 0x65D003CAL, 0x1523, 0x11D2, 0xB2, 0x7A, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96 -DEFINE_GUIDSTRUCT("65D003CA-1523-11D2-B27A-00A0C9223196", KSMETHODSETID_StreamIo); -#define KSMETHODSETID_StreamIo DEFINE_GUIDNAMED(KSMETHODSETID_StreamIo) - -typedef enum -{ - KSMETHOD_STREAMIO_READ, - KSMETHOD_STREAMIO_WRITE -}KSMETHOD_STREAMIO; - -#define DEFINE_KSMETHOD_ITEM_STREAMIO_READ(Handler) \ - DEFINE_KSMETHOD_ITEM( \ - KSMETHOD_STREAMIO_READ, \ - KSMETHOD_TYPE_WRITE, \ - (Handler), \ - sizeof(KSMETHOD), \ - 0, \ - NULL) - -#define DEFINE_KSMETHOD_ITEM_STREAMIO_WRITE(Handler) \ - DEFINE_KSMETHOD_ITEM( \ - KSMETHOD_STREAMIO_WRITE, \ - KSMETHOD_TYPE_READ, \ - (Handler), \ - sizeof(KSMETHOD), \ - 0, \ - NULL) - -#define STATIC_KSPROPSETID_MediaSeeking \ - 0xEE904F0CL, 0xD09B, 0x11D0, 0xAB, 0xE9, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96 -DEFINE_GUIDSTRUCT("EE904F0C-D09B-11D0-ABE9-00A0C9223196", KSPROPSETID_MediaSeeking); -#define KSPROPSETID_MediaSeeking DEFINE_GUIDNAMED(KSPROPSETID_MediaSeeking) - -typedef enum -{ - KSPROPERTY_MEDIASEEKING_CAPABILITIES, - KSPROPERTY_MEDIASEEKING_FORMATS, - KSPROPERTY_MEDIASEEKING_TIMEFORMAT, - KSPROPERTY_MEDIASEEKING_POSITION, - KSPROPERTY_MEDIASEEKING_STOPPOSITION, - KSPROPERTY_MEDIASEEKING_POSITIONS, - KSPROPERTY_MEDIASEEKING_DURATION, - KSPROPERTY_MEDIASEEKING_AVAILABLE, - KSPROPERTY_MEDIASEEKING_PREROLL, - KSPROPERTY_MEDIASEEKING_CONVERTTIMEFORMAT -}KSPROPERTY_MEDIASEEKING; - -typedef enum -{ - KS_SEEKING_NoPositioning, - KS_SEEKING_AbsolutePositioning, - KS_SEEKING_RelativePositioning, - KS_SEEKING_IncrementalPositioning, - KS_SEEKING_PositioningBitsMask = 0x3, - KS_SEEKING_SeekToKeyFrame, - KS_SEEKING_ReturnTime = 0x8 -}KS_SEEKING_FLAGS; - -typedef enum -{ - KS_SEEKING_CanSeekAbsolute = 0x1, - KS_SEEKING_CanSeekForwards = 0x2, - KS_SEEKING_CanSeekBackwards = 0x4, - KS_SEEKING_CanGetCurrentPos = 0x8, - KS_SEEKING_CanGetStopPos = 0x10, - KS_SEEKING_CanGetDuration = 0x20, - KS_SEEKING_CanPlayBackwards = 0x40 -}KS_SEEKING_CAPABILITIES; - -typedef struct -{ - LONGLONG Current; - LONGLONG Stop; - KS_SEEKING_FLAGS CurrentFlags; - KS_SEEKING_FLAGS StopFlags; -}KSPROPERTY_POSITIONS, * PKSPROPERTY_POSITIONS; - -typedef struct -{ - LONGLONG Earliest; - LONGLONG Latest; -}KSPROPERTY_MEDIAAVAILABLE, * PKSPROPERTY_MEDIAAVAILABLE; - -typedef struct -{ - KSPROPERTY Property; - GUID SourceFormat; - GUID TargetFormat; - LONGLONG Time; -}KSP_TIMEFORMAT, * PKSP_TIMEFORMAT; - -#define DEFINE_KSPROPERTY_ITEM_MEDIASEEKING_CAPABILITIES(Handler) \ - DEFINE_KSPROPERTY_ITEM( \ - KSPROPERTY_MEDIASEEKING_CAPABILITIES, \ - (Handler), \ - sizeof(KSPROPERTY), \ - sizeof(KS_SEEKING_CAPABILITIES), \ - NULL, NULL, 0, NULL, NULL, 0) - -#define DEFINE_KSPROPERTY_ITEM_MEDIASEEKING_FORMATS(Handler) \ - DEFINE_KSPROPERTY_ITEM( \ - KSPROPERTY_MEDIASEEKING_FORMATS, \ - (Handler), \ - sizeof(KSPROPERTY), \ - 0, \ - NULL, NULL, 0, NULL, NULL, 0) - -#define DEFINE_KSPROPERTY_ITEM_MEDIASEEKING_TIMEFORMAT(GetHandler, SetHandler) \ - DEFINE_KSPROPERTY_ITEM( \ - KSPROPERTY_MEDIASEEKING_TIMEFORMAT, \ - (GetHandler), \ - sizeof(KSPROPERTY), \ - sizeof(GUID), \ - (SetHandler), \ - NULL, 0, NULL, NULL, 0) - -#define DEFINE_KSPROPERTY_ITEM_MEDIASEEKING_POSITION(Handler) \ - DEFINE_KSPROPERTY_ITEM( \ - KSPROPERTY_MEDIASEEKING_POSITION, \ - (Handler), \ - sizeof(KSPROPERTY), \ - sizeof(LONGLONG), \ - NULL, NULL, 0, NULL, NULL, 0) - -#define DEFINE_KSPROPERTY_ITEM_MEDIASEEKING_STOPPOSITION(Handler) \ - DEFINE_KSPROPERTY_ITEM( \ - KSPROPERTY_MEDIASEEKING_STOPPOSITION, \ - (Handler), \ - sizeof(KSPROPERTY), \ - sizeof(LONGLONG), \ - NULL, NULL, 0, NULL, NULL, 0) - -#define DEFINE_KSPROPERTY_ITEM_MEDIASEEKING_POSITIONS(Handler) \ - DEFINE_KSPROPERTY_ITEM( \ - KSPROPERTY_MEDIASEEKING_POSITIONS, \ - NULL, \ - sizeof(KSPROPERTY), \ - sizeof(KSPROPERTY_POSITIONS), \ - (Handler), \ - NULL, 0, NULL, NULL, 0) - -#define DEFINE_KSPROPERTY_ITEM_MEDIASEEKING_DURATION(Handler) \ - DEFINE_KSPROPERTY_ITEM( \ - KSPROPERTY_MEDIASEEKING_DURATION, \ - (Handler), \ - sizeof(KSPROPERTY), \ - sizeof(LONGLONG), \ - NULL, NULL, 0, NULL, NULL, 0) - -#define DEFINE_KSPROPERTY_ITEM_MEDIASEEKING_AVAILABLE(Handler) \ - DEFINE_KSPROPERTY_ITEM( \ - KSPROPERTY_MEDIASEEKING_AVAILABLE, \ - (Handler), \ - sizeof(KSPROPERTY), \ - sizeof(KSPROPERTY_MEDIAAVAILABLE), \ - NULL, NULL, 0, NULL, NULL, 0) - -#define DEFINE_KSPROPERTY_ITEM_MEDIASEEKING_PREROLL(Handler) \ - DEFINE_KSPROPERTY_ITEM( \ - KSPROPERTY_MEDIASEEKING_PREROLL, \ - (Handler), \ - sizeof(KSPROPERTY), \ - sizeof(LONGLONG), \ - NULL, NULL, 0, NULL, NULL, 0) - -#define DEFINE_KSPROPERTY_ITEM_MEDIASEEKING_CONVERTTIMEFORMAT(Handler) \ - DEFINE_KSPROPERTY_ITEM( \ - KSPROPERTY_MEDIASEEKING_CONVERTTIMEFORMAT, \ - (Handler), \ - sizeof(KSP_TIMEFORMAT), \ - sizeof(LONGLONG), \ - NULL, NULL, 0, NULL, NULL, 0) - -#define STATIC_KSPROPSETID_Topology \ - 0x720D4AC0L, 0x7533, 0x11D0, { 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00 } -DEFINE_GUIDSTRUCT("720D4AC0-7533-11D0-A5D6-28DB04C10000", KSPROPSETID_Topology); -#define KSPROPSETID_Topology DEFINE_GUIDNAMED(KSPROPSETID_Topology) - -typedef enum -{ - KSPROPERTY_TOPOLOGY_CATEGORIES, - KSPROPERTY_TOPOLOGY_NODES, - KSPROPERTY_TOPOLOGY_CONNECTIONS, - KSPROPERTY_TOPOLOGY_NAME -}KSPROPERTY_TOPOLOGY; - -#define DEFINE_KSPROPERTY_ITEM_TOPOLOGY_CATEGORIES(Handler) \ - DEFINE_KSPROPERTY_ITEM( \ - KSPROPERTY_TOPOLOGY_CATEGORIES, \ - (Handler), \ - sizeof(KSPROPERTY), \ - 0, \ - NULL, NULL, 0, NULL, NULL, 0) - -#define DEFINE_KSPROPERTY_ITEM_TOPOLOGY_NODES(Handler) \ - DEFINE_KSPROPERTY_ITEM( \ - KSPROPERTY_TOPOLOGY_NODES, \ - (Handler), \ - sizeof(KSPROPERTY), \ - 0, \ - NULL, NULL, 0, NULL, NULL, 0) - -#define DEFINE_KSPROPERTY_ITEM_TOPOLOGY_CONNECTIONS(Handler) \ - DEFINE_KSPROPERTY_ITEM( \ - KSPROPERTY_TOPOLOGY_CONNECTIONS, \ - (Handler), \ - sizeof(KSPROPERTY), \ - 0, \ - NULL, NULL, 0, NULL, NULL, 0) - -#define DEFINE_KSPROPERTY_ITEM_TOPOLOGY_NAME(Handler) \ - DEFINE_KSPROPERTY_ITEM( \ - KSPROPERTY_TOPOLOGY_NAME, \ - (Handler), \ - sizeof(KSP_NODE), \ - 0, \ - NULL, NULL, 0, NULL, NULL, 0) - -#define DEFINE_KSPROPERTY_TOPOLOGYSET(TopologySet, Handler) \ - DEFINE_KSPROPERTY_TABLE(TopologySet) { \ - DEFINE_KSPROPERTY_ITEM_TOPOLOGY_CATEGORIES(Handler), \ - DEFINE_KSPROPERTY_ITEM_TOPOLOGY_NODES(Handler), \ - DEFINE_KSPROPERTY_ITEM_TOPOLOGY_CONNECTIONS(Handler), \ - DEFINE_KSPROPERTY_ITEM_TOPOLOGY_NAME(Handler) \ - } - -#define STATIC_KSCATEGORY_BRIDGE \ - 0x085AFF00L, 0x62CE, 0x11CF, 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00 -DEFINE_GUIDSTRUCT("085AFF00-62CE-11CF-A5D6-28DB04C10000", KSCATEGORY_BRIDGE); -#define KSCATEGORY_BRIDGE DEFINE_GUIDNAMED(KSCATEGORY_BRIDGE) - -#define STATIC_KSCATEGORY_CAPTURE \ - 0x65E8773DL, 0x8F56, 0x11D0, { 0xA3, 0xB9, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96 } -DEFINE_GUIDSTRUCT("65E8773D-8F56-11D0-A3B9-00A0C9223196", KSCATEGORY_CAPTURE); -#define KSCATEGORY_CAPTURE DEFINE_GUIDNAMED(KSCATEGORY_CAPTURE) - -#define STATIC_KSCATEGORY_RENDER \ - 0x65E8773EL, 0x8F56, 0x11D0, { 0xA3, 0xB9, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96 } -DEFINE_GUIDSTRUCT("65E8773E-8F56-11D0-A3B9-00A0C9223196", KSCATEGORY_RENDER); -#define KSCATEGORY_RENDER DEFINE_GUIDNAMED(KSCATEGORY_RENDER) - -#define STATIC_KSCATEGORY_MIXER \ - 0xAD809C00L, 0x7B88, 0x11D0, 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00 -DEFINE_GUIDSTRUCT("AD809C00-7B88-11D0-A5D6-28DB04C10000", KSCATEGORY_MIXER); -#define KSCATEGORY_MIXER DEFINE_GUIDNAMED(KSCATEGORY_MIXER) - -#define STATIC_KSCATEGORY_SPLITTER \ - 0x0A4252A0L, 0x7E70, 0x11D0, 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00 -DEFINE_GUIDSTRUCT("0A4252A0-7E70-11D0-A5D6-28DB04C10000", KSCATEGORY_SPLITTER); -#define KSCATEGORY_SPLITTER DEFINE_GUIDNAMED(KSCATEGORY_SPLITTER) - -#define STATIC_KSCATEGORY_DATACOMPRESSOR \ - 0x1E84C900L, 0x7E70, 0x11D0, 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00 -DEFINE_GUIDSTRUCT("1E84C900-7E70-11D0-A5D6-28DB04C10000", KSCATEGORY_DATACOMPRESSOR); -#define KSCATEGORY_DATACOMPRESSOR DEFINE_GUIDNAMED(KSCATEGORY_DATACOMPRESSOR) - -#define STATIC_KSCATEGORY_DATADECOMPRESSOR \ - 0x2721AE20L, 0x7E70, 0x11D0, 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00 -DEFINE_GUIDSTRUCT("2721AE20-7E70-11D0-A5D6-28DB04C10000", KSCATEGORY_DATADECOMPRESSOR); -#define KSCATEGORY_DATADECOMPRESSOR DEFINE_GUIDNAMED(KSCATEGORY_DATADECOMPRESSOR) - -#define STATIC_KSCATEGORY_DATATRANSFORM \ - 0x2EB07EA0L, 0x7E70, 0x11D0, 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00 -DEFINE_GUIDSTRUCT("2EB07EA0-7E70-11D0-A5D6-28DB04C10000", KSCATEGORY_DATATRANSFORM); -#define KSCATEGORY_DATATRANSFORM DEFINE_GUIDNAMED(KSCATEGORY_DATATRANSFORM) - -#define STATIC_KSCATEGORY_COMMUNICATIONSTRANSFORM \ - 0xCF1DDA2CL, 0x9743, 0x11D0, 0xA3, 0xEE, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96 -DEFINE_GUIDSTRUCT("CF1DDA2C-9743-11D0-A3EE-00A0C9223196", KSCATEGORY_COMMUNICATIONSTRANSFORM); -#define KSCATEGORY_COMMUNICATIONSTRANSFORM DEFINE_GUIDNAMED(KSCATEGORY_COMMUNICATIONSTRANSFORM) - -#define STATIC_KSCATEGORY_INTERFACETRANSFORM \ - 0xCF1DDA2DL, 0x9743, 0x11D0, 0xA3, 0xEE, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96 -DEFINE_GUIDSTRUCT("CF1DDA2D-9743-11D0-A3EE-00A0C9223196", KSCATEGORY_INTERFACETRANSFORM); -#define KSCATEGORY_INTERFACETRANSFORM DEFINE_GUIDNAMED(KSCATEGORY_INTERFACETRANSFORM) - -#define STATIC_KSCATEGORY_MEDIUMTRANSFORM \ - 0xCF1DDA2EL, 0x9743, 0x11D0, 0xA3, 0xEE, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96 -DEFINE_GUIDSTRUCT("CF1DDA2E-9743-11D0-A3EE-00A0C9223196", KSCATEGORY_MEDIUMTRANSFORM); -#define KSCATEGORY_MEDIUMTRANSFORM DEFINE_GUIDNAMED(KSCATEGORY_MEDIUMTRANSFORM) - -#define STATIC_KSCATEGORY_FILESYSTEM \ - 0x760FED5EL, 0x9357, 0x11D0, 0xA3, 0xCC, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96 -DEFINE_GUIDSTRUCT("760FED5E-9357-11D0-A3CC-00A0C9223196", KSCATEGORY_FILESYSTEM); -#define KSCATEGORY_FILESYSTEM DEFINE_GUIDNAMED(KSCATEGORY_FILESYSTEM) - -#define STATIC_KSCATEGORY_CLOCK \ - 0x53172480L, 0x4791, 0x11D0, 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00 -DEFINE_GUIDSTRUCT("53172480-4791-11D0-A5D6-28DB04C10000", KSCATEGORY_CLOCK); -#define KSCATEGORY_CLOCK DEFINE_GUIDNAMED(KSCATEGORY_CLOCK) - -#define STATIC_KSCATEGORY_PROXY \ - 0x97EBAACAL, 0x95BD, 0x11D0, 0xA3, 0xEA, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96 -DEFINE_GUIDSTRUCT("97EBAACA-95BD-11D0-A3EA-00A0C9223196", KSCATEGORY_PROXY); -#define KSCATEGORY_PROXY DEFINE_GUIDNAMED(KSCATEGORY_PROXY) - -#define STATIC_KSCATEGORY_QUALITY \ - 0x97EBAACBL, 0x95BD, 0x11D0, 0xA3, 0xEA, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96 -DEFINE_GUIDSTRUCT("97EBAACB-95BD-11D0-A3EA-00A0C9223196", KSCATEGORY_QUALITY); -#define KSCATEGORY_QUALITY DEFINE_GUIDNAMED(KSCATEGORY_QUALITY) - -typedef struct -{ - ULONG FromNode; - ULONG FromNodePin; - ULONG ToNode; - ULONG ToNodePin; -}KSTOPOLOGY_CONNECTION, * PKSTOPOLOGY_CONNECTION; - -typedef struct -{ - ULONG CategoriesCount; - const GUID* Categories; - ULONG TopologyNodesCount; - const GUID* TopologyNodes; - ULONG TopologyConnectionsCount; - const KSTOPOLOGY_CONNECTION* TopologyConnections; - const GUID* TopologyNodesNames; - ULONG Reserved; -}KSTOPOLOGY, * PKSTOPOLOGY; - -#define KSFILTER_NODE ((ULONG)-1) -#define KSALL_NODES ((ULONG)-1) - -typedef struct -{ - ULONG CreateFlags; - ULONG Node; -}KSNODE_CREATE, * PKSNODE_CREATE; - -#define STATIC_KSTIME_FORMAT_NONE STATIC_GUID_NULL -#define KSTIME_FORMAT_NONE GUID_NULL - -#define STATIC_KSTIME_FORMAT_FRAME \ - 0x7b785570L, 0x8c82, 0x11cf, 0xbc, 0x0c, 0x00, 0xaa, 0x00, 0xac, 0x74, 0xf6 -DEFINE_GUIDSTRUCT("7b785570-8c82-11cf-bc0c-00aa00ac74f6", KSTIME_FORMAT_FRAME); -#define KSTIME_FORMAT_FRAME DEFINE_GUIDNAMED(KSTIME_FORMAT_FRAME) - -#define STATIC_KSTIME_FORMAT_BYTE \ - 0x7b785571L, 0x8c82, 0x11cf, 0xbc, 0x0c, 0x00, 0xaa, 0x00, 0xac, 0x74, 0xf6 -DEFINE_GUIDSTRUCT("7b785571-8c82-11cf-bc0c-00aa00ac74f6", KSTIME_FORMAT_BYTE); -#define KSTIME_FORMAT_BYTE DEFINE_GUIDNAMED(KSTIME_FORMAT_BYTE) - -#define STATIC_KSTIME_FORMAT_SAMPLE \ - 0x7b785572L, 0x8c82, 0x11cf, 0xbc, 0x0c, 0x00, 0xaa, 0x00, 0xac, 0x74, 0xf6 -DEFINE_GUIDSTRUCT("7b785572-8c82-11cf-bc0c-00aa00ac74f6", KSTIME_FORMAT_SAMPLE); -#define KSTIME_FORMAT_SAMPLE DEFINE_GUIDNAMED(KSTIME_FORMAT_SAMPLE) - -#define STATIC_KSTIME_FORMAT_FIELD \ - 0x7b785573L, 0x8c82, 0x11cf, 0xbc, 0x0c, 0x00, 0xaa, 0x00, 0xac, 0x74, 0xf6 -DEFINE_GUIDSTRUCT("7b785573-8c82-11cf-bc0c-00aa00ac74f6", KSTIME_FORMAT_FIELD); -#define KSTIME_FORMAT_FIELD DEFINE_GUIDNAMED(KSTIME_FORMAT_FIELD) - -#define STATIC_KSTIME_FORMAT_MEDIA_TIME \ - 0x7b785574L, 0x8c82, 0x11cf, 0xbc, 0x0c, 0x00, 0xaa, 0x00, 0xac, 0x74, 0xf6 -DEFINE_GUIDSTRUCT("7b785574-8c82-11cf-bc0c-00aa00ac74f6", KSTIME_FORMAT_MEDIA_TIME); -#define KSTIME_FORMAT_MEDIA_TIME DEFINE_GUIDNAMED(KSTIME_FORMAT_MEDIA_TIME) - -typedef KSIDENTIFIER KSPIN_INTERFACE, * PKSPIN_INTERFACE; - -#define STATIC_KSINTERFACESETID_Standard \ - 0x1A8766A0L, 0x62CE, 0x11CF, { 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00 } -DEFINE_GUIDSTRUCT("1A8766A0-62CE-11CF-A5D6-28DB04C10000", KSINTERFACESETID_Standard); -#define KSINTERFACESETID_Standard DEFINE_GUIDNAMED(KSINTERFACESETID_Standard) - -typedef enum -{ - KSINTERFACE_STANDARD_STREAMING, - KSINTERFACE_STANDARD_LOOPED_STREAMING, - KSINTERFACE_STANDARD_CONTROL -}KSINTERFACE_STANDARD; - -#define STATIC_KSINTERFACESETID_FileIo \ - 0x8C6F932CL, 0xE771, 0x11D0, 0xB8, 0xFF, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96 -DEFINE_GUIDSTRUCT("8C6F932C-E771-11D0-B8FF-00A0C9223196", KSINTERFACESETID_FileIo); -#define KSINTERFACESETID_FileIo DEFINE_GUIDNAMED(KSINTERFACESETID_FileIo) - -typedef enum -{ - KSINTERFACE_FILEIO_STREAMING -}KSINTERFACE_FILEIO; - -#define KSMEDIUM_TYPE_ANYINSTANCE 0 - -#define STATIC_KSMEDIUMSETID_Standard \ - 0x4747B320L, 0x62CE, 0x11CF, { 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00 } -DEFINE_GUIDSTRUCT("4747B320-62CE-11CF-A5D6-28DB04C10000", KSMEDIUMSETID_Standard); -#define KSMEDIUMSETID_Standard DEFINE_GUIDNAMED(KSMEDIUMSETID_Standard) - -#define KSMEDIUM_STANDARD_DEVIO KSMEDIUM_TYPE_ANYINSTANCE - -#define STATIC_KSPROPSETID_Pin \ - 0x8C134960L, 0x51AD, 0x11CF, { 0x87, 0x8A, 0x94, 0xF8, 0x01, 0xC1, 0x00, 0x00 } -DEFINE_GUIDSTRUCT("8C134960-51AD-11CF-878A-94F801C10000", KSPROPSETID_Pin); -#define KSPROPSETID_Pin DEFINE_GUIDNAMED(KSPROPSETID_Pin) - -typedef enum -{ - KSPROPERTY_PIN_CINSTANCES, - KSPROPERTY_PIN_CTYPES, - KSPROPERTY_PIN_DATAFLOW, - KSPROPERTY_PIN_DATARANGES, - KSPROPERTY_PIN_DATAINTERSECTION, - KSPROPERTY_PIN_INTERFACES, - KSPROPERTY_PIN_MEDIUMS, - KSPROPERTY_PIN_COMMUNICATION, - KSPROPERTY_PIN_GLOBALCINSTANCES, - KSPROPERTY_PIN_NECESSARYINSTANCES, - KSPROPERTY_PIN_PHYSICALCONNECTION, - KSPROPERTY_PIN_CATEGORY, - KSPROPERTY_PIN_NAME, - KSPROPERTY_PIN_CONSTRAINEDDATARANGES, - KSPROPERTY_PIN_PROPOSEDATAFORMAT -}KSPROPERTY_PIN; - -typedef struct -{ - KSPROPERTY Property; - ULONG PinId; - ULONG Reserved; -}KSP_PIN, * PKSP_PIN; - -#define KSINSTANCE_INDETERMINATE ((ULONG)-1) - -typedef struct -{ - ULONG PossibleCount; - ULONG CurrentCount; -}KSPIN_CINSTANCES, * PKSPIN_CINSTANCES; - -typedef enum -{ - KSPIN_DATAFLOW_IN = 1, - KSPIN_DATAFLOW_OUT -}KSPIN_DATAFLOW, * PKSPIN_DATAFLOW; - -#define KSDATAFORMAT_BIT_TEMPORAL_COMPRESSION 0 -#define KSDATAFORMAT_TEMPORAL_COMPRESSION (1 << KSDATAFORMAT_BIT_TEMPORAL_COMPRESSION) -#define KSDATAFORMAT_BIT_ATTRIBUTES 1 -#define KSDATAFORMAT_ATTRIBUTES (1 << KSDATAFORMAT_BIT_ATTRIBUTES) - -#define KSDATARANGE_BIT_ATTRIBUTES 1 -#define KSDATARANGE_ATTRIBUTES (1 << KSDATARANGE_BIT_ATTRIBUTES) -#define KSDATARANGE_BIT_REQUIRED_ATTRIBUTES 2 -#define KSDATARANGE_REQUIRED_ATTRIBUTES (1 << KSDATARANGE_BIT_REQUIRED_ATTRIBUTES) - -typedef union -{ - __MINGW_EXTENSION struct - { - ULONG FormatSize; - ULONG Flags; - ULONG SampleSize; - ULONG Reserved; - GUID MajorFormat; - GUID SubFormat; - GUID Specifier; - }; - LONGLONG Alignment; -}KSDATAFORMAT, * PKSDATAFORMAT, KSDATARANGE, * PKSDATARANGE; - -#define KSATTRIBUTE_REQUIRED 0x00000001 - -typedef struct -{ - ULONG Size; - ULONG Flags; - GUID Attribute; -}KSATTRIBUTE, * PKSATTRIBUTE; - -#if defined(_NTDDK_) -typedef struct -{ - ULONG Count; - PKSATTRIBUTE* Attributes; -}KSATTRIBUTE_LIST, * PKSATTRIBUTE_LIST; -#endif /* _NTDDK_ */ - -typedef enum -{ - KSPIN_COMMUNICATION_NONE, - KSPIN_COMMUNICATION_SINK, - KSPIN_COMMUNICATION_SOURCE, - KSPIN_COMMUNICATION_BOTH, - KSPIN_COMMUNICATION_BRIDGE -}KSPIN_COMMUNICATION, * PKSPIN_COMMUNICATION; - -typedef KSIDENTIFIER KSPIN_MEDIUM, * PKSPIN_MEDIUM; - -typedef struct -{ - KSPIN_INTERFACE Interface; - KSPIN_MEDIUM Medium; - ULONG PinId; - HANDLE PinToHandle; - KSPRIORITY Priority; -}KSPIN_CONNECT, * PKSPIN_CONNECT; - -typedef struct -{ - ULONG Size; - ULONG Pin; - WCHAR SymbolicLinkName[1]; -}KSPIN_PHYSICALCONNECTION, * PKSPIN_PHYSICALCONNECTION; - -#if defined(_NTDDK_) -typedef NTSTATUS (*PFNKSINTERSECTHANDLER)(PIRP Irp, PKSP_PIN Pin, - PKSDATARANGE DataRange, - PVOID Data); -typedef NTSTATUS (*PFNKSINTERSECTHANDLEREX)(PVOID Context, PIRP Irp, - PKSP_PIN Pin, - PKSDATARANGE DataRange, - PKSDATARANGE MatchingDataRange, - ULONG DataBufferSize, - PVOID Data, - PULONG DataSize); -#endif /* _NTDDK_ */ - -#define DEFINE_KSPIN_INTERFACE_TABLE(tablename) \ - const KSPIN_INTERFACE tablename[] = - -#define DEFINE_KSPIN_INTERFACE_ITEM(guid, _interFace) \ - { \ - STATICGUIDOF(guid), \ - (_interFace), \ - 0 \ - } - -#define DEFINE_KSPIN_MEDIUM_TABLE(tablename) \ - const KSPIN_MEDIUM tablename[] = - -#define DEFINE_KSPIN_MEDIUM_ITEM(guid, medium) \ - DEFINE_KSPIN_INTERFACE_ITEM(guid, medium) - -#define DEFINE_KSPROPERTY_ITEM_PIN_CINSTANCES(Handler) \ - DEFINE_KSPROPERTY_ITEM( \ - KSPROPERTY_PIN_CINSTANCES, \ - (Handler), \ - sizeof(KSP_PIN), \ - sizeof(KSPIN_CINSTANCES), \ - NULL, NULL, 0, NULL, NULL, 0) - -#define DEFINE_KSPROPERTY_ITEM_PIN_CTYPES(Handler) \ - DEFINE_KSPROPERTY_ITEM( \ - KSPROPERTY_PIN_CTYPES, \ - (Handler), \ - sizeof(KSPROPERTY), \ - sizeof(ULONG), \ - NULL, NULL, 0, NULL, NULL, 0) - -#define DEFINE_KSPROPERTY_ITEM_PIN_DATAFLOW(Handler) \ - DEFINE_KSPROPERTY_ITEM( \ - KSPROPERTY_PIN_DATAFLOW, \ - (Handler), \ - sizeof(KSP_PIN), \ - sizeof(KSPIN_DATAFLOW), \ - NULL, NULL, 0, NULL, NULL, 0) - -#define DEFINE_KSPROPERTY_ITEM_PIN_DATARANGES(Handler) \ - DEFINE_KSPROPERTY_ITEM( \ - KSPROPERTY_PIN_DATARANGES, \ - (Handler), \ - sizeof(KSP_PIN), \ - 0, \ - NULL, NULL, 0, NULL, NULL, 0) - -#define DEFINE_KSPROPERTY_ITEM_PIN_DATAINTERSECTION(Handler) \ - DEFINE_KSPROPERTY_ITEM( \ - KSPROPERTY_PIN_DATAINTERSECTION, \ - (Handler), \ - sizeof(KSP_PIN) + sizeof(KSMULTIPLE_ITEM), \ - 0, \ - NULL, NULL, 0, NULL, NULL, 0) - -#define DEFINE_KSPROPERTY_ITEM_PIN_INTERFACES(Handler) \ - DEFINE_KSPROPERTY_ITEM( \ - KSPROPERTY_PIN_INTERFACES, \ - (Handler), \ - sizeof(KSP_PIN), \ - 0, \ - NULL, NULL, 0, NULL, NULL, 0) - -#define DEFINE_KSPROPERTY_ITEM_PIN_MEDIUMS(Handler) \ - DEFINE_KSPROPERTY_ITEM( \ - KSPROPERTY_PIN_MEDIUMS, \ - (Handler), \ - sizeof(KSP_PIN), \ - 0, \ - NULL, NULL, 0, NULL, NULL, 0) - -#define DEFINE_KSPROPERTY_ITEM_PIN_COMMUNICATION(Handler) \ - DEFINE_KSPROPERTY_ITEM( \ - KSPROPERTY_PIN_COMMUNICATION, \ - (Handler), \ - sizeof(KSP_PIN), \ - sizeof(KSPIN_COMMUNICATION), \ - NULL, NULL, 0, NULL, NULL, 0) - -#define DEFINE_KSPROPERTY_ITEM_PIN_GLOBALCINSTANCES(Handler) \ - DEFINE_KSPROPERTY_ITEM( \ - KSPROPERTY_PIN_GLOBALCINSTANCES, \ - (Handler), \ - sizeof(KSP_PIN), \ - sizeof(KSPIN_CINSTANCES), \ - NULL, NULL, 0, NULL, NULL, 0) - -#define DEFINE_KSPROPERTY_ITEM_PIN_NECESSARYINSTANCES(Handler) \ - DEFINE_KSPROPERTY_ITEM( \ - KSPROPERTY_PIN_NECESSARYINSTANCES, \ - (Handler), \ - sizeof(KSP_PIN), \ - sizeof(ULONG), \ - NULL, NULL, 0, NULL, NULL, 0) - -#define DEFINE_KSPROPERTY_ITEM_PIN_PHYSICALCONNECTION(Handler) \ - DEFINE_KSPROPERTY_ITEM( \ - KSPROPERTY_PIN_PHYSICALCONNECTION, \ - (Handler), \ - sizeof(KSP_PIN), \ - 0, \ - NULL, NULL, 0, NULL, NULL, 0) - -#define DEFINE_KSPROPERTY_ITEM_PIN_CATEGORY(Handler) \ - DEFINE_KSPROPERTY_ITEM( \ - KSPROPERTY_PIN_CATEGORY, \ - (Handler), \ - sizeof(KSP_PIN), \ - sizeof(GUID), \ - NULL, NULL, 0, NULL, NULL, 0) - -#define DEFINE_KSPROPERTY_ITEM_PIN_NAME(Handler) \ - DEFINE_KSPROPERTY_ITEM( \ - KSPROPERTY_PIN_NAME, \ - (Handler), \ - sizeof(KSP_PIN), \ - 0, \ - NULL, NULL, 0, NULL, NULL, 0) - -#define DEFINE_KSPROPERTY_ITEM_PIN_CONSTRAINEDDATARANGES(Handler) \ - DEFINE_KSPROPERTY_ITEM( \ - KSPROPERTY_PIN_CONSTRAINEDDATARANGES, \ - (Handler), \ - sizeof(KSP_PIN), \ - 0, \ - NULL, NULL, 0, NULL, NULL, 0) - -#define DEFINE_KSPROPERTY_ITEM_PIN_PROPOSEDATAFORMAT(Handler) \ - DEFINE_KSPROPERTY_ITEM( \ - KSPROPERTY_PIN_PROPOSEDATAFORMAT, \ - NULL, \ - sizeof(KSP_PIN), \ - sizeof(KSDATAFORMAT), \ - (Handler), NULL, 0, NULL, NULL, 0) - -#define DEFINE_KSPROPERTY_PINSET(PinSet, PropGeneral, PropInstances, PropIntersection) \ - DEFINE_KSPROPERTY_TABLE(PinSet) { \ - DEFINE_KSPROPERTY_ITEM_PIN_CINSTANCES(PropInstances), \ - DEFINE_KSPROPERTY_ITEM_PIN_CTYPES(PropGeneral), \ - DEFINE_KSPROPERTY_ITEM_PIN_DATAFLOW(PropGeneral), \ - DEFINE_KSPROPERTY_ITEM_PIN_DATARANGES(PropGeneral), \ - DEFINE_KSPROPERTY_ITEM_PIN_DATAINTERSECTION(PropIntersection), \ - DEFINE_KSPROPERTY_ITEM_PIN_INTERFACES(PropGeneral), \ - DEFINE_KSPROPERTY_ITEM_PIN_MEDIUMS(PropGeneral), \ - DEFINE_KSPROPERTY_ITEM_PIN_COMMUNICATION(PropGeneral), \ - DEFINE_KSPROPERTY_ITEM_PIN_CATEGORY(PropGeneral), \ - DEFINE_KSPROPERTY_ITEM_PIN_NAME(PropGeneral) \ - } - -#define DEFINE_KSPROPERTY_PINSETCONSTRAINED(PinSet, PropGeneral, PropInstances, PropIntersection) \ - DEFINE_KSPROPERTY_TABLE(PinSet) { \ - DEFINE_KSPROPERTY_ITEM_PIN_CINSTANCES(PropInstances), \ - DEFINE_KSPROPERTY_ITEM_PIN_CTYPES(PropGeneral), \ - DEFINE_KSPROPERTY_ITEM_PIN_DATAFLOW(PropGeneral), \ - DEFINE_KSPROPERTY_ITEM_PIN_DATARANGES(PropGeneral), \ - DEFINE_KSPROPERTY_ITEM_PIN_DATAINTERSECTION(PropIntersection), \ - DEFINE_KSPROPERTY_ITEM_PIN_INTERFACES(PropGeneral), \ - DEFINE_KSPROPERTY_ITEM_PIN_MEDIUMS(PropGeneral), \ - DEFINE_KSPROPERTY_ITEM_PIN_COMMUNICATION(PropGeneral), \ - DEFINE_KSPROPERTY_ITEM_PIN_CATEGORY(PropGeneral), \ - DEFINE_KSPROPERTY_ITEM_PIN_NAME(PropGeneral), \ - DEFINE_KSPROPERTY_ITEM_PIN_CONSTRAINEDDATARANGES(PropGeneral) \ - } - -#define STATIC_KSNAME_Filter \ - 0x9b365890L, 0x165f, 0x11d0, 0xa1, 0x95, 0x00, 0x20, 0xaf, 0xd1, 0x56, 0xe4 -DEFINE_GUIDSTRUCT("9b365890-165f-11d0-a195-0020afd156e4", KSNAME_Filter); -#define KSNAME_Filter DEFINE_GUIDNAMED(KSNAME_Filter) - -#define KSSTRING_Filter L"{9B365890-165F-11D0-A195-0020AFD156E4}" - -#define STATIC_KSNAME_Pin \ - 0x146F1A80L, 0x4791, 0x11D0, 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00 -DEFINE_GUIDSTRUCT("146F1A80-4791-11D0-A5D6-28DB04C10000", KSNAME_Pin); -#define KSNAME_Pin DEFINE_GUIDNAMED(KSNAME_Pin) - -#define KSSTRING_Pin L"{146F1A80-4791-11D0-A5D6-28DB04C10000}" - -#define STATIC_KSNAME_Clock \ - 0x53172480L, 0x4791, 0x11D0, 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00 -DEFINE_GUIDSTRUCT("53172480-4791-11D0-A5D6-28DB04C10000", KSNAME_Clock); -#define KSNAME_Clock DEFINE_GUIDNAMED(KSNAME_Clock) - -#define KSSTRING_Clock L"{53172480-4791-11D0-A5D6-28DB04C10000}" - -#define STATIC_KSNAME_Allocator \ - 0x642F5D00L, 0x4791, 0x11D0, 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00 -DEFINE_GUIDSTRUCT("642F5D00-4791-11D0-A5D6-28DB04C10000", KSNAME_Allocator); -#define KSNAME_Allocator DEFINE_GUIDNAMED(KSNAME_Allocator) - -#define KSSTRING_Allocator L"{642F5D00-4791-11D0-A5D6-28DB04C10000}" - -#define KSSTRING_AllocatorEx L"{091BB63B-603F-11D1-B067-00A0C9062802}" - -#define STATIC_KSNAME_TopologyNode \ - 0x0621061AL, 0xEE75, 0x11D0, 0xB9, 0x15, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96 -DEFINE_GUIDSTRUCT("0621061A-EE75-11D0-B915-00A0C9223196", KSNAME_TopologyNode); -#define KSNAME_TopologyNode DEFINE_GUIDNAMED(KSNAME_TopologyNode) - -#define KSSTRING_TopologyNode L"{0621061A-EE75-11D0-B915-00A0C9223196}" - -#if defined(_NTDDK_) -typedef struct -{ - ULONG InterfacesCount; - const KSPIN_INTERFACE* Interfaces; - ULONG MediumsCount; - const KSPIN_MEDIUM* Mediums; - ULONG DataRangesCount; - const PKSDATARANGE* DataRanges; - KSPIN_DATAFLOW DataFlow; - KSPIN_COMMUNICATION Communication; - const GUID* Category; - const GUID* Name; - __MINGW_EXTENSION union - { - LONGLONG Reserved; - __MINGW_EXTENSION struct - { - ULONG ConstrainedDataRangesCount; - PKSDATARANGE* ConstrainedDataRanges; - }; - }; -}KSPIN_DESCRIPTOR, * PKSPIN_DESCRIPTOR; -typedef const KSPIN_DESCRIPTOR* PCKSPIN_DESCRIPTOR; - - # define DEFINE_KSPIN_DESCRIPTOR_TABLE(tablename) \ - const KSPIN_DESCRIPTOR tablename[] = - - # define DEFINE_KSPIN_DESCRIPTOR_ITEM(InterfacesCount, Interfaces, MediumsCount, Mediums, DataRangesCount, DataRanges, DataFlow, Communication) \ - { \ - InterfacesCount, Interfaces, MediumsCount, Mediums, \ - DataRangesCount, DataRanges, DataFlow, Communication, \ - NULL, NULL, 0 \ - } - - # define DEFINE_KSPIN_DESCRIPTOR_ITEMEX(InterfacesCount, Interfaces, MediumsCount, Mediums, DataRangesCount, DataRanges, DataFlow, Communication, Category, Name) \ - { \ - InterfacesCount, Interfaces, MediumsCount, Mediums, \ - DataRangesCount, DataRanges, DataFlow, Communication, \ - Category, Name, 0 \ - } -#endif /* _NTDDK_ */ - -#define STATIC_KSDATAFORMAT_TYPE_WILDCARD STATIC_GUID_NULL -#define KSDATAFORMAT_TYPE_WILDCARD GUID_NULL - -#define STATIC_KSDATAFORMAT_SUBTYPE_WILDCARD STATIC_GUID_NULL -#define KSDATAFORMAT_SUBTYPE_WILDCARD GUID_NULL - -#define STATIC_KSDATAFORMAT_TYPE_STREAM \ - 0xE436EB83L, 0x524F, 0x11CE, 0x9F, 0x53, 0x00, 0x20, 0xAF, 0x0B, 0xA7, 0x70 -DEFINE_GUIDSTRUCT("E436EB83-524F-11CE-9F53-0020AF0BA770", KSDATAFORMAT_TYPE_STREAM); -#define KSDATAFORMAT_TYPE_STREAM DEFINE_GUIDNAMED(KSDATAFORMAT_TYPE_STREAM) - -#define STATIC_KSDATAFORMAT_SUBTYPE_NONE \ - 0xE436EB8EL, 0x524F, 0x11CE, 0x9F, 0x53, 0x00, 0x20, 0xAF, 0x0B, 0xA7, 0x70 -DEFINE_GUIDSTRUCT("E436EB8E-524F-11CE-9F53-0020AF0BA770", KSDATAFORMAT_SUBTYPE_NONE); -#define KSDATAFORMAT_SUBTYPE_NONE DEFINE_GUIDNAMED(KSDATAFORMAT_SUBTYPE_NONE) - -#define STATIC_KSDATAFORMAT_SPECIFIER_WILDCARD STATIC_GUID_NULL -#define KSDATAFORMAT_SPECIFIER_WILDCARD GUID_NULL - -#define STATIC_KSDATAFORMAT_SPECIFIER_FILENAME \ - 0xAA797B40L, 0xE974, 0x11CF, 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00 -DEFINE_GUIDSTRUCT("AA797B40-E974-11CF-A5D6-28DB04C10000", KSDATAFORMAT_SPECIFIER_FILENAME); -#define KSDATAFORMAT_SPECIFIER_FILENAME DEFINE_GUIDNAMED(KSDATAFORMAT_SPECIFIER_FILENAME) - -#define STATIC_KSDATAFORMAT_SPECIFIER_FILEHANDLE \ - 0x65E8773CL, 0x8F56, 0x11D0, 0xA3, 0xB9, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96 -DEFINE_GUIDSTRUCT("65E8773C-8F56-11D0-A3B9-00A0C9223196", KSDATAFORMAT_SPECIFIER_FILEHANDLE); -#define KSDATAFORMAT_SPECIFIER_FILEHANDLE DEFINE_GUIDNAMED(KSDATAFORMAT_SPECIFIER_FILEHANDLE) - -#define STATIC_KSDATAFORMAT_SPECIFIER_NONE \ - 0x0F6417D6L, 0xC318, 0x11D0, { 0xA4, 0x3F, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96 } -DEFINE_GUIDSTRUCT("0F6417D6-C318-11D0-A43F-00A0C9223196", KSDATAFORMAT_SPECIFIER_NONE); -#define KSDATAFORMAT_SPECIFIER_NONE DEFINE_GUIDNAMED(KSDATAFORMAT_SPECIFIER_NONE) - -#define STATIC_KSPROPSETID_Quality \ - 0xD16AD380L, 0xAC1A, 0x11CF, 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00 -DEFINE_GUIDSTRUCT("D16AD380-AC1A-11CF-A5D6-28DB04C10000", KSPROPSETID_Quality); -#define KSPROPSETID_Quality DEFINE_GUIDNAMED(KSPROPSETID_Quality) - -typedef enum -{ - KSPROPERTY_QUALITY_REPORT, - KSPROPERTY_QUALITY_ERROR -}KSPROPERTY_QUALITY; - -#define DEFINE_KSPROPERTY_ITEM_QUALITY_REPORT(GetHandler, SetHandler) \ - DEFINE_KSPROPERTY_ITEM( \ - KSPROPERTY_QUALITY_REPORT, \ - (GetHandler), \ - sizeof(KSPROPERTY), \ - sizeof(KSQUALITY), \ - (SetHandler), \ - NULL, 0, NULL, NULL, 0) - -#define DEFINE_KSPROPERTY_ITEM_QUALITY_ERROR(GetHandler, SetHandler) \ - DEFINE_KSPROPERTY_ITEM( \ - KSPROPERTY_QUALITY_ERROR, \ - (GetHandler), \ - sizeof(KSPROPERTY), \ - sizeof(KSERROR), \ - (SetHandler), \ - NULL, 0, NULL, NULL, 0) - -#define STATIC_KSPROPSETID_Connection \ - 0x1D58C920L, 0xAC9B, 0x11CF, { 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00 } -DEFINE_GUIDSTRUCT("1D58C920-AC9B-11CF-A5D6-28DB04C10000", KSPROPSETID_Connection); -#define KSPROPSETID_Connection DEFINE_GUIDNAMED(KSPROPSETID_Connection) - -typedef enum -{ - KSPROPERTY_CONNECTION_STATE, - KSPROPERTY_CONNECTION_PRIORITY, - KSPROPERTY_CONNECTION_DATAFORMAT, - KSPROPERTY_CONNECTION_ALLOCATORFRAMING, - KSPROPERTY_CONNECTION_PROPOSEDATAFORMAT, - KSPROPERTY_CONNECTION_ACQUIREORDERING, - KSPROPERTY_CONNECTION_ALLOCATORFRAMING_EX, - KSPROPERTY_CONNECTION_STARTAT -}KSPROPERTY_CONNECTION; - -#define DEFINE_KSPROPERTY_ITEM_CONNECTION_STATE(GetHandler, SetHandler) \ - DEFINE_KSPROPERTY_ITEM( \ - KSPROPERTY_CONNECTION_STATE, \ - (GetHandler), \ - sizeof(KSPROPERTY), \ - sizeof(KSSTATE), \ - (SetHandler), \ - NULL, 0, NULL, NULL, 0) - -#define DEFINE_KSPROPERTY_ITEM_CONNECTION_PRIORITY(GetHandler, SetHandler) \ - DEFINE_KSPROPERTY_ITEM( \ - KSPROPERTY_CONNECTION_PRIORITY, \ - (GetHandler), \ - sizeof(KSPROPERTY), \ - sizeof(KSPRIORITY), \ - (SetHandler), \ - NULL, 0, NULL, NULL, 0) - -#define DEFINE_KSPROPERTY_ITEM_CONNECTION_DATAFORMAT(GetHandler, SetHandler) \ - DEFINE_KSPROPERTY_ITEM( \ - KSPROPERTY_CONNECTION_DATAFORMAT, \ - (GetHandler), \ - sizeof(KSPROPERTY), \ - 0, \ - (SetHandler), \ - NULL, 0, NULL, NULL, 0) - -#define DEFINE_KSPROPERTY_ITEM_CONNECTION_ALLOCATORFRAMING(Handler) \ - DEFINE_KSPROPERTY_ITEM( \ - KSPROPERTY_CONNECTION_ALLOCATORFRAMING, \ - (Handler), \ - sizeof(KSPROPERTY), \ - sizeof(KSALLOCATOR_FRAMING), \ - NULL, NULL, 0, NULL, NULL, 0) - -#define DEFINE_KSPROPERTY_ITEM_CONNECTION_ALLOCATORFRAMING_EX(Handler) \ - DEFINE_KSPROPERTY_ITEM( \ - KSPROPERTY_CONNECTION_ALLOCATORFRAMING_EX, \ - (Handler), \ - sizeof(KSPROPERTY), \ - 0, \ - NULL, NULL, 0, NULL, NULL, 0) - -#define DEFINE_KSPROPERTY_ITEM_CONNECTION_PROPOSEDATAFORMAT(Handler) \ - DEFINE_KSPROPERTY_ITEM( \ - KSPROPERTY_CONNECTION_PROPOSEDATAFORMAT, \ - NULL, \ - sizeof(KSPROPERTY), \ - sizeof(KSDATAFORMAT), \ - (Handler), \ - NULL, 0, NULL, NULL, 0) - -#define DEFINE_KSPROPERTY_ITEM_CONNECTION_ACQUIREORDERING(Handler) \ - DEFINE_KSPROPERTY_ITEM( \ - KSPROPERTY_CONNECTION_ACQUIREORDERING, \ - (Handler), \ - sizeof(KSPROPERTY), \ - sizeof(int), \ - NULL, NULL, 0, NULL, NULL, 0) - -#define DEFINE_KSPROPERTY_ITEM_CONNECTION_STARTAT(Handler) \ - DEFINE_KSPROPERTY_ITEM( \ - KSPROPERTY_CONNECTION_STARTAT, \ - NULL, \ - sizeof(KSPROPERTY), \ - sizeof(KSRELATIVEEVENT), \ - (Handler), \ - NULL, 0, NULL, NULL, 0) - -#define KSALLOCATOR_REQUIREMENTF_INPLACE_MODIFIER 0x00000001 -#define KSALLOCATOR_REQUIREMENTF_SYSTEM_MEMORY 0x00000002 -#define KSALLOCATOR_REQUIREMENTF_FRAME_INTEGRITY 0x00000004 -#define KSALLOCATOR_REQUIREMENTF_MUST_ALLOCATE 0x00000008 -#define KSALLOCATOR_REQUIREMENTF_PREFERENCES_ONLY 0x80000000 - -#define KSALLOCATOR_OPTIONF_COMPATIBLE 0x00000001 -#define KSALLOCATOR_OPTIONF_SYSTEM_MEMORY 0x00000002 -#define KSALLOCATOR_OPTIONF_VALID 0x00000003 - -#define KSALLOCATOR_FLAG_PARTIAL_READ_SUPPORT 0x00000010 -#define KSALLOCATOR_FLAG_DEVICE_SPECIFIC 0x00000020 -#define KSALLOCATOR_FLAG_CAN_ALLOCATE 0x00000040 -#define KSALLOCATOR_FLAG_INSIST_ON_FRAMESIZE_RATIO 0x00000080 -#define KSALLOCATOR_FLAG_NO_FRAME_INTEGRITY 0x00000100 -#define KSALLOCATOR_FLAG_MULTIPLE_OUTPUT 0x00000200 -#define KSALLOCATOR_FLAG_CYCLE 0x00000400 -#define KSALLOCATOR_FLAG_ALLOCATOR_EXISTS 0x00000800 -#define KSALLOCATOR_FLAG_INDEPENDENT_RANGES 0x00001000 -#define KSALLOCATOR_FLAG_ATTENTION_STEPPING 0x00002000 - -typedef struct -{ - __MINGW_EXTENSION union - { - ULONG OptionsFlags; - ULONG RequirementsFlags; - }; -#if defined(_NTDDK_) - POOL_TYPE PoolType; -#else - ULONG PoolType; -#endif /* _NTDDK_ */ - ULONG Frames; - ULONG FrameSize; - ULONG FileAlignment; - ULONG Reserved; -}KSALLOCATOR_FRAMING, * PKSALLOCATOR_FRAMING; - -#if defined(_NTDDK_) -typedef PVOID (*PFNKSDEFAULTALLOCATE)(PVOID Context); -typedef VOID (*PFNKSDEFAULTFREE)(PVOID Context, PVOID Buffer); -typedef NTSTATUS (*PFNKSINITIALIZEALLOCATOR)(PVOID InitialContext, - PKSALLOCATOR_FRAMING AllocatorFraming, - PVOID* Context); -typedef VOID (*PFNKSDELETEALLOCATOR)(PVOID Context); -#endif /* _NTDDK_ */ - -typedef struct -{ - ULONG MinFrameSize; - ULONG MaxFrameSize; - ULONG Stepping; -}KS_FRAMING_RANGE, * PKS_FRAMING_RANGE; - -typedef struct -{ - KS_FRAMING_RANGE Range; - ULONG InPlaceWeight; - ULONG NotInPlaceWeight; -}KS_FRAMING_RANGE_WEIGHTED, * PKS_FRAMING_RANGE_WEIGHTED; - -typedef struct -{ - ULONG RatioNumerator; - ULONG RatioDenominator; - ULONG RatioConstantMargin; -}KS_COMPRESSION, * PKS_COMPRESSION; - -typedef struct -{ - GUID MemoryType; - GUID BusType; - ULONG MemoryFlags; - ULONG BusFlags; - ULONG Flags; - ULONG Frames; - ULONG FileAlignment; - ULONG MemoryTypeWeight; - KS_FRAMING_RANGE PhysicalRange; - KS_FRAMING_RANGE_WEIGHTED FramingRange; -}KS_FRAMING_ITEM, * PKS_FRAMING_ITEM; - -typedef struct -{ - ULONG CountItems; - ULONG PinFlags; - KS_COMPRESSION OutputCompression; - ULONG PinWeight; - KS_FRAMING_ITEM FramingItem[1]; -}KSALLOCATOR_FRAMING_EX, * PKSALLOCATOR_FRAMING_EX; - -#define KSMEMORY_TYPE_WILDCARD GUID_NULL -#define STATIC_KSMEMORY_TYPE_WILDCARD STATIC_GUID_NULL - -#define KSMEMORY_TYPE_DONT_CARE GUID_NULL -#define STATIC_KSMEMORY_TYPE_DONT_CARE STATIC_GUID_NULL - -#define KS_TYPE_DONT_CARE GUID_NULL -#define STATIC_KS_TYPE_DONT_CARE STATIC_GUID_NULL - -#define STATIC_KSMEMORY_TYPE_SYSTEM \ - 0x091bb638L, 0x603f, 0x11d1, 0xb0, 0x67, 0x00, 0xa0, 0xc9, 0x06, 0x28, 0x02 -DEFINE_GUIDSTRUCT("091bb638-603f-11d1-b067-00a0c9062802", KSMEMORY_TYPE_SYSTEM); -#define KSMEMORY_TYPE_SYSTEM DEFINE_GUIDNAMED(KSMEMORY_TYPE_SYSTEM) - -#define STATIC_KSMEMORY_TYPE_USER \ - 0x8cb0fc28L, 0x7893, 0x11d1, 0xb0, 0x69, 0x00, 0xa0, 0xc9, 0x06, 0x28, 0x02 -DEFINE_GUIDSTRUCT("8cb0fc28-7893-11d1-b069-00a0c9062802", KSMEMORY_TYPE_USER); -#define KSMEMORY_TYPE_USER DEFINE_GUIDNAMED(KSMEMORY_TYPE_USER) - -#define STATIC_KSMEMORY_TYPE_KERNEL_PAGED \ - 0xd833f8f8L, 0x7894, 0x11d1, 0xb0, 0x69, 0x00, 0xa0, 0xc9, 0x06, 0x28, 0x02 -DEFINE_GUIDSTRUCT("d833f8f8-7894-11d1-b069-00a0c9062802", KSMEMORY_TYPE_KERNEL_PAGED); -#define KSMEMORY_TYPE_KERNEL_PAGED DEFINE_GUIDNAMED(KSMEMORY_TYPE_KERNEL_PAGED) - -#define STATIC_KSMEMORY_TYPE_KERNEL_NONPAGED \ - 0x4a6d5fc4L, 0x7895, 0x11d1, 0xb0, 0x69, 0x00, 0xa0, 0xc9, 0x06, 0x28, 0x02 -DEFINE_GUIDSTRUCT("4a6d5fc4-7895-11d1-b069-00a0c9062802", KSMEMORY_TYPE_KERNEL_NONPAGED); -#define KSMEMORY_TYPE_KERNEL_NONPAGED DEFINE_GUIDNAMED(KSMEMORY_TYPE_KERNEL_NONPAGED) - -#define STATIC_KSMEMORY_TYPE_DEVICE_UNKNOWN \ - 0x091bb639L, 0x603f, 0x11d1, 0xb0, 0x67, 0x00, 0xa0, 0xc9, 0x06, 0x28, 0x02 -DEFINE_GUIDSTRUCT("091bb639-603f-11d1-b067-00a0c9062802", KSMEMORY_TYPE_DEVICE_UNKNOWN); -#define KSMEMORY_TYPE_DEVICE_UNKNOWN DEFINE_GUIDNAMED(KSMEMORY_TYPE_DEVICE_UNKNOWN) - -#define DECLARE_SIMPLE_FRAMING_EX(FramingExName, MemoryType, Flags, Frames, Alignment, MinFrameSize, MaxFrameSize) \ - const KSALLOCATOR_FRAMING_EX FramingExName = \ - { \ - 1, \ - 0, \ - { \ - 1, \ - 1, \ - 0 \ - }, \ - 0, \ - { \ - { \ - MemoryType, \ - STATIC_KS_TYPE_DONT_CARE, \ - 0, \ - 0, \ - Flags, \ - Frames, \ - Alignment, \ - 0, \ - { \ - 0, \ - (ULONG)-1, \ - 1 \ - }, \ - { \ - { \ - MinFrameSize, \ - MaxFrameSize, \ - 1 \ - }, \ - 0, \ - 0 \ - } \ - } \ - } \ - } - -#define SetDefaultKsCompression(KsCompressionPointer) \ - { \ - KsCompressionPointer->RatioNumerator = 1; \ - KsCompressionPointer->RatioDenominator = 1; \ - KsCompressionPointer->RatioConstantMargin = 0; \ - } - -#define SetDontCareKsFramingRange(KsFramingRangePointer) \ - { \ - KsFramingRangePointer->MinFrameSize = 0; \ - KsFramingRangePointer->MaxFrameSize = (ULONG)-1; \ - KsFramingRangePointer->Stepping = 1; \ - } - -#define SetKsFramingRange(KsFramingRangePointer, P_MinFrameSize, P_MaxFrameSize) \ - { \ - KsFramingRangePointer->MinFrameSize = P_MinFrameSize; \ - KsFramingRangePointer->MaxFrameSize = P_MaxFrameSize; \ - KsFramingRangePointer->Stepping = 1; \ - } - -#define SetKsFramingRangeWeighted(KsFramingRangeWeightedPointer, P_MinFrameSize, P_MaxFrameSize) \ - { \ - KS_FRAMING_RANGE* KsFramingRange = \ - &KsFramingRangeWeightedPointer->Range; \ - SetKsFramingRange(KsFramingRange, P_MinFrameSize, P_MaxFrameSize); \ - KsFramingRangeWeightedPointer->InPlaceWeight = 0; \ - KsFramingRangeWeightedPointer->NotInPlaceWeight = 0; \ - } - -#define INITIALIZE_SIMPLE_FRAMING_EX(FramingExPointer, P_MemoryType, P_Flags, P_Frames, P_Alignment, P_MinFrameSize, P_MaxFrameSize) \ - { \ - KS_COMPRESSION* KsCompression = \ - &FramingExPointer->OutputCompression; \ - KS_FRAMING_RANGE* KsFramingRange = \ - &FramingExPointer->FramingItem[0].PhysicalRange; \ - KS_FRAMING_RANGE_WEIGHTED* KsFramingRangeWeighted = \ - &FramingExPointer->FramingItem[0].FramingRange; \ - FramingExPointer->CountItems = 1; \ - FramingExPointer->PinFlags = 0; \ - SetDefaultKsCompression(KsCompression); \ - FramingExPointer->PinWeight = 0; \ - FramingExPointer->FramingItem[0].MemoryType = P_MemoryType; \ - FramingExPointer->FramingItem[0].BusType = KS_TYPE_DONT_CARE; \ - FramingExPointer->FramingItem[0].MemoryFlags = 0; \ - FramingExPointer->FramingItem[0].BusFlags = 0; \ - FramingExPointer->FramingItem[0].Flags = P_Flags; \ - FramingExPointer->FramingItem[0].Frames = P_Frames; \ - FramingExPointer->FramingItem[0].FileAlignment = P_Alignment; \ - FramingExPointer->FramingItem[0].MemoryTypeWeight = 0; \ - SetDontCareKsFramingRange(KsFramingRange); \ - SetKsFramingRangeWeighted(KsFramingRangeWeighted, \ - P_MinFrameSize, P_MaxFrameSize); \ - } - -#define STATIC_KSEVENTSETID_StreamAllocator \ - 0x75d95571L, 0x073c, 0x11d0, 0xa1, 0x61, 0x00, 0x20, 0xaf, 0xd1, 0x56, 0xe4 -DEFINE_GUIDSTRUCT("75d95571-073c-11d0-a161-0020afd156e4", KSEVENTSETID_StreamAllocator); -#define KSEVENTSETID_StreamAllocator DEFINE_GUIDNAMED(KSEVENTSETID_StreamAllocator) - -typedef enum -{ - KSEVENT_STREAMALLOCATOR_INTERNAL_FREEFRAME, - KSEVENT_STREAMALLOCATOR_FREEFRAME -}KSEVENT_STREAMALLOCATOR; - -#define STATIC_KSMETHODSETID_StreamAllocator \ - 0xcf6e4341L, 0xec87, 0x11cf, 0xa1, 0x30, 0x00, 0x20, 0xaf, 0xd1, 0x56, 0xe4 -DEFINE_GUIDSTRUCT("cf6e4341-ec87-11cf-a130-0020afd156e4", KSMETHODSETID_StreamAllocator); -#define KSMETHODSETID_StreamAllocator DEFINE_GUIDNAMED(KSMETHODSETID_StreamAllocator) - -typedef enum -{ - KSMETHOD_STREAMALLOCATOR_ALLOC, - KSMETHOD_STREAMALLOCATOR_FREE -}KSMETHOD_STREAMALLOCATOR; - -#define DEFINE_KSMETHOD_ITEM_STREAMALLOCATOR_ALLOC(Handler) \ - DEFINE_KSMETHOD_ITEM( \ - KSMETHOD_STREAMALLOCATOR_ALLOC, \ - KSMETHOD_TYPE_WRITE, \ - (Handler), \ - sizeof(KSMETHOD), \ - sizeof(PVOID), \ - NULL) - -#define DEFINE_KSMETHOD_ITEM_STREAMALLOCATOR_FREE(Handler) \ - DEFINE_KSMETHOD_ITEM( \ - KSMETHOD_STREAMALLOCATOR_FREE, \ - KSMETHOD_TYPE_READ, \ - (Handler), \ - sizeof(KSMETHOD), \ - sizeof(PVOID), \ - NULL) - -#define DEFINE_KSMETHOD_ALLOCATORSET(AllocatorSet, MethodAlloc, MethodFree) \ - DEFINE_KSMETHOD_TABLE(AllocatorSet) { \ - DEFINE_KSMETHOD_ITEM_STREAMALLOCATOR_ALLOC(MethodAlloc), \ - DEFINE_KSMETHOD_ITEM_STREAMALLOCATOR_FREE(MethodFree) \ - } - -#define STATIC_KSPROPSETID_StreamAllocator \ - 0xcf6e4342L, 0xec87, 0x11cf, 0xa1, 0x30, 0x00, 0x20, 0xaf, 0xd1, 0x56, 0xe4 -DEFINE_GUIDSTRUCT("cf6e4342-ec87-11cf-a130-0020afd156e4", KSPROPSETID_StreamAllocator); -#define KSPROPSETID_StreamAllocator DEFINE_GUIDNAMED(KSPROPSETID_StreamAllocator) - -#if defined(_NTDDK_) -typedef enum -{ - KSPROPERTY_STREAMALLOCATOR_FUNCTIONTABLE, - KSPROPERTY_STREAMALLOCATOR_STATUS -}KSPROPERTY_STREAMALLOCATOR; - - # define DEFINE_KSPROPERTY_ITEM_STREAMALLOCATOR_FUNCTIONTABLE(Handler) \ - DEFINE_KSPROPERTY_ITEM( \ - KSPROPERTY_STREAMALLOCATOR_FUNCTIONTABLE, \ - (Handler), \ - sizeof(KSPROPERTY), \ - sizeof(KSSTREAMALLOCATOR_FUNCTIONTABLE), \ - NULL, NULL, 0, NULL, NULL, 0) - - # define DEFINE_KSPROPERTY_ITEM_STREAMALLOCATOR_STATUS(Handler) \ - DEFINE_KSPROPERTY_ITEM( \ - KSPROPERTY_STREAMALLOCATOR_STATUS, \ - (Handler), \ - sizeof(KSPROPERTY), \ - sizeof(KSSTREAMALLOCATOR_STATUS), \ - NULL, NULL, 0, NULL, NULL, 0) - - # define DEFINE_KSPROPERTY_ALLOCATORSET(AllocatorSet, PropFunctionTable, PropStatus) \ - DEFINE_KSPROPERTY_TABLE(AllocatorSet) { \ - DEFINE_KSPROPERTY_ITEM_STREAMALLOCATOR_STATUS(PropStatus), \ - DEFINE_KSPROPERTY_ITEM_STREAMALLOCATOR_FUNCTIONTABLE(PropFunctionTable) \ - } - -typedef NTSTATUS (*PFNALLOCATOR_ALLOCATEFRAME)(PFILE_OBJECT FileObject, - PVOID* Frame); -typedef VOID (*PFNALLOCATOR_FREEFRAME)(PFILE_OBJECT FileObject, PVOID Frame); - -typedef struct -{ - PFNALLOCATOR_ALLOCATEFRAME AllocateFrame; - PFNALLOCATOR_FREEFRAME FreeFrame; -}KSSTREAMALLOCATOR_FUNCTIONTABLE, * PKSSTREAMALLOCATOR_FUNCTIONTABLE; -#endif /* _NTDDK_ */ - -typedef struct -{ - KSALLOCATOR_FRAMING Framing; - ULONG AllocatedFrames; - ULONG Reserved; -}KSSTREAMALLOCATOR_STATUS, * PKSSTREAMALLOCATOR_STATUS; - -typedef struct -{ - KSALLOCATOR_FRAMING_EX Framing; - ULONG AllocatedFrames; - ULONG Reserved; -}KSSTREAMALLOCATOR_STATUS_EX, * PKSSTREAMALLOCATOR_STATUS_EX; - -#define KSSTREAM_HEADER_OPTIONSF_SPLICEPOINT 0x00000001 -#define KSSTREAM_HEADER_OPTIONSF_PREROLL 0x00000002 -#define KSSTREAM_HEADER_OPTIONSF_DATADISCONTINUITY 0x00000004 -#define KSSTREAM_HEADER_OPTIONSF_TYPECHANGED 0x00000008 -#define KSSTREAM_HEADER_OPTIONSF_TIMEVALID 0x00000010 -#define KSSTREAM_HEADER_OPTIONSF_TIMEDISCONTINUITY 0x00000040 -#define KSSTREAM_HEADER_OPTIONSF_FLUSHONPAUSE 0x00000080 -#define KSSTREAM_HEADER_OPTIONSF_DURATIONVALID 0x00000100 -#define KSSTREAM_HEADER_OPTIONSF_ENDOFSTREAM 0x00000200 -#define KSSTREAM_HEADER_OPTIONSF_LOOPEDDATA 0x80000000 - -typedef struct -{ - LONGLONG Time; - ULONG Numerator; - ULONG Denominator; -}KSTIME, * PKSTIME; - -typedef struct -{ - ULONG Size; - ULONG TypeSpecificFlags; - KSTIME PresentationTime; - LONGLONG Duration; - ULONG FrameExtent; - ULONG DataUsed; - PVOID Data; - ULONG OptionsFlags; -#ifdef _WIN64 - ULONG Reserved; -#endif -}KSSTREAM_HEADER, * PKSSTREAM_HEADER; - -#define STATIC_KSPROPSETID_StreamInterface \ - 0x1fdd8ee1L, 0x9cd3, 0x11d0, 0x82, 0xaa, 0x00, 0x00, 0xf8, 0x22, 0xfe, 0x8a -DEFINE_GUIDSTRUCT("1fdd8ee1-9cd3-11d0-82aa-0000f822fe8a", KSPROPSETID_StreamInterface); -#define KSPROPSETID_StreamInterface DEFINE_GUIDNAMED(KSPROPSETID_StreamInterface) - -typedef enum -{ - KSPROPERTY_STREAMINTERFACE_HEADERSIZE -}KSPROPERTY_STREAMINTERFACE; - -#define DEFINE_KSPROPERTY_ITEM_STREAMINTERFACE_HEADERSIZE(GetHandler) \ - DEFINE_KSPROPERTY_ITEM( \ - KSPROPERTY_STREAMINTERFACE_HEADERSIZE, \ - (GetHandler), \ - sizeof(KSPROPERTY), \ - sizeof(ULONG), \ - NULL, NULL, 0, NULL, NULL, 0) - -#define DEFINE_KSPROPERTY_STREAMINTERFACESET(StreamInterfaceSet, HeaderSizeHandler) \ - DEFINE_KSPROPERTY_TABLE(StreamInterfaceSet) { \ - DEFINE_KSPROPERTY_ITEM_STREAMINTERFACE_HEADERSIZE(HeaderSizeHandler) \ - } - -#define STATIC_KSPROPSETID_Stream \ - 0x65aaba60L, 0x98ae, 0x11cf, 0xa1, 0x0d, 0x00, 0x20, 0xaf, 0xd1, 0x56, 0xe4 -DEFINE_GUIDSTRUCT("65aaba60-98ae-11cf-a10d-0020afd156e4", KSPROPSETID_Stream); -#define KSPROPSETID_Stream DEFINE_GUIDNAMED(KSPROPSETID_Stream) - -typedef enum -{ - KSPROPERTY_STREAM_ALLOCATOR, - KSPROPERTY_STREAM_QUALITY, - KSPROPERTY_STREAM_DEGRADATION, - KSPROPERTY_STREAM_MASTERCLOCK, - KSPROPERTY_STREAM_TIMEFORMAT, - KSPROPERTY_STREAM_PRESENTATIONTIME, - KSPROPERTY_STREAM_PRESENTATIONEXTENT, - KSPROPERTY_STREAM_FRAMETIME, - KSPROPERTY_STREAM_RATECAPABILITY, - KSPROPERTY_STREAM_RATE, - KSPROPERTY_STREAM_PIPE_ID -}KSPROPERTY_STREAM; - -#define DEFINE_KSPROPERTY_ITEM_STREAM_ALLOCATOR(GetHandler, SetHandler) \ - DEFINE_KSPROPERTY_ITEM( \ - KSPROPERTY_STREAM_ALLOCATOR, \ - (GetHandler), \ - sizeof(KSPROPERTY), \ - sizeof(HANDLE), \ - (SetHandler), \ - NULL, 0, NULL, NULL, 0) - -#define DEFINE_KSPROPERTY_ITEM_STREAM_QUALITY(Handler) \ - DEFINE_KSPROPERTY_ITEM( \ - KSPROPERTY_STREAM_QUALITY, \ - (Handler), \ - sizeof(KSPROPERTY), \ - sizeof(KSQUALITY_MANAGER), \ - NULL, NULL, 0, NULL, NULL, 0) - -#define DEFINE_KSPROPERTY_ITEM_STREAM_DEGRADATION(GetHandler, SetHandler) \ - DEFINE_KSPROPERTY_ITEM( \ - KSPROPERTY_STREAM_DEGRADATION, \ - (GetHandler), \ - sizeof(KSPROPERTY), \ - 0, \ - (SetHandler), \ - NULL, 0, NULL, NULL, 0) - -#define DEFINE_KSPROPERTY_ITEM_STREAM_MASTERCLOCK(GetHandler, SetHandler) \ - DEFINE_KSPROPERTY_ITEM( \ - KSPROPERTY_STREAM_MASTERCLOCK, \ - (GetHandler), \ - sizeof(KSPROPERTY), \ - sizeof(HANDLE), \ - (SetHandler), \ - NULL, 0, NULL, NULL, 0) - -#define DEFINE_KSPROPERTY_ITEM_STREAM_TIMEFORMAT(Handler) \ - DEFINE_KSPROPERTY_ITEM( \ - KSPROPERTY_STREAM_TIMEFORMAT, \ - (Handler), \ - sizeof(KSPROPERTY), \ - sizeof(GUID), \ - NULL, NULL, 0, NULL, NULL, 0) - -#define DEFINE_KSPROPERTY_ITEM_STREAM_PRESENTATIONTIME(GetHandler, SetHandler) \ - DEFINE_KSPROPERTY_ITEM( \ - KSPROPERTY_STREAM_PRESENTATIONTIME, \ - (GetHandler), \ - sizeof(KSPROPERTY), \ - sizeof(KSTIME), \ - (SetHandler), \ - NULL, 0, NULL, NULL, 0) - -#define DEFINE_KSPROPERTY_ITEM_STREAM_PRESENTATIONEXTENT(Handler) \ - DEFINE_KSPROPERTY_ITEM( \ - KSPROPERTY_STREAM_PRESENTATIONEXTENT, \ - (Handler), \ - sizeof(KSPROPERTY), \ - sizeof(LONGLONG), \ - NULL, NULL, 0, NULL, NULL, 0) - -#define DEFINE_KSPROPERTY_ITEM_STREAM_FRAMETIME(Handler) \ - DEFINE_KSPROPERTY_ITEM( \ - KSPROPERTY_STREAM_FRAMETIME, \ - (Handler), \ - sizeof(KSPROPERTY), \ - sizeof(KSFRAMETIME), \ - NULL, NULL, 0, NULL, NULL, 0) - -#define DEFINE_KSPROPERTY_ITEM_STREAM_RATECAPABILITY(Handler) \ - DEFINE_KSPROPERTY_ITEM( \ - KSPROPERTY_STREAM_RATECAPABILITY, \ - (Handler), \ - sizeof(KSRATE_CAPABILITY), \ - sizeof(KSRATE), \ - NULL, NULL, 0, NULL, NULL, 0) - -#define DEFINE_KSPROPERTY_ITEM_STREAM_RATE(GetHandler, SetHandler) \ - DEFINE_KSPROPERTY_ITEM( \ - KSPROPERTY_STREAM_RATE, \ - (GetHandler), \ - sizeof(KSPROPERTY), \ - sizeof(KSRATE), \ - (SetHandler), \ - NULL, 0, NULL, NULL, 0) - -#define DEFINE_KSPROPERTY_ITEM_STREAM_PIPE_ID(GetHandler, SetHandler) \ - DEFINE_KSPROPERTY_ITEM( \ - KSPROPERTY_STREAM_PIPE_ID, \ - (GetHandler), \ - sizeof(KSPROPERTY), \ - sizeof(HANDLE), \ - (SetHandler), \ - NULL, 0, NULL, NULL, 0) - -typedef struct -{ - HANDLE QualityManager; - PVOID Context; -}KSQUALITY_MANAGER, * PKSQUALITY_MANAGER; - -typedef struct -{ - LONGLONG Duration; - ULONG FrameFlags; - ULONG Reserved; -}KSFRAMETIME, * PKSFRAMETIME; - -#define KSFRAMETIME_VARIABLESIZE 0x00000001 - -typedef struct -{ - LONGLONG PresentationStart; - LONGLONG Duration; - KSPIN_INTERFACE Interface; - LONG Rate; - ULONG Flags; -}KSRATE, * PKSRATE; - -#define KSRATE_NOPRESENTATIONSTART 0x00000001 -#define KSRATE_NOPRESENTATIONDURATION 0x00000002 - -typedef struct -{ - KSPROPERTY Property; - KSRATE Rate; -}KSRATE_CAPABILITY, * PKSRATE_CAPABILITY; - -#define STATIC_KSPROPSETID_Clock \ - 0xDF12A4C0L, 0xAC17, 0x11CF, 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00 -DEFINE_GUIDSTRUCT("DF12A4C0-AC17-11CF-A5D6-28DB04C10000", KSPROPSETID_Clock); -#define KSPROPSETID_Clock DEFINE_GUIDNAMED(KSPROPSETID_Clock) - -#define NANOSECONDS 10000000 -#define KSCONVERT_PERFORMANCE_TIME(Frequency, PerformanceTime) \ - ((((ULONGLONG)(ULONG)(PerformanceTime).HighPart * NANOSECONDS / (Frequency)) << 32) + \ - ((((((ULONGLONG)(ULONG)(PerformanceTime).HighPart * NANOSECONDS) % (Frequency)) << 32) + \ - ((ULONGLONG)(PerformanceTime).LowPart * NANOSECONDS)) / (Frequency))) - -typedef struct -{ - ULONG CreateFlags; -}KSCLOCK_CREATE, * PKSCLOCK_CREATE; - -typedef struct -{ - LONGLONG Time; - LONGLONG SystemTime; -}KSCORRELATED_TIME, * PKSCORRELATED_TIME; - -typedef struct -{ - LONGLONG Granularity; - LONGLONG Error; -}KSRESOLUTION, * PKSRESOLUTION; - -typedef enum -{ - KSPROPERTY_CLOCK_TIME, - KSPROPERTY_CLOCK_PHYSICALTIME, - KSPROPERTY_CLOCK_CORRELATEDTIME, - KSPROPERTY_CLOCK_CORRELATEDPHYSICALTIME, - KSPROPERTY_CLOCK_RESOLUTION, - KSPROPERTY_CLOCK_STATE, -#if defined(_NTDDK_) - KSPROPERTY_CLOCK_FUNCTIONTABLE -#endif /* _NTDDK_ */ -}KSPROPERTY_CLOCK; - -#if defined(_NTDDK_) -typedef LONGLONG (FASTCALL * PFNKSCLOCK_GETTIME)(PFILE_OBJECT FileObject); -typedef LONGLONG (FASTCALL * PFNKSCLOCK_CORRELATEDTIME)(PFILE_OBJECT FileObject, - PLONGLONG SystemTime); - -typedef struct -{ - PFNKSCLOCK_GETTIME GetTime; - PFNKSCLOCK_GETTIME GetPhysicalTime; - PFNKSCLOCK_CORRELATEDTIME GetCorrelatedTime; - PFNKSCLOCK_CORRELATEDTIME GetCorrelatedPhysicalTime; -}KSCLOCK_FUNCTIONTABLE, * PKSCLOCK_FUNCTIONTABLE; - -typedef BOOLEAN (*PFNKSSETTIMER)(PVOID Context, PKTIMER Timer, - LARGE_INTEGER DueTime, PKDPC Dpc); -typedef BOOLEAN (*PFNKSCANCELTIMER)(PVOID Context, PKTIMER Timer); -typedef LONGLONG (FASTCALL * PFNKSCORRELATEDTIME)(PVOID Context, - PLONGLONG SystemTime); - -typedef PVOID PKSDEFAULTCLOCK; - - # define DEFINE_KSPROPERTY_ITEM_CLOCK_TIME(Handler) \ - DEFINE_KSPROPERTY_ITEM( \ - KSPROPERTY_CLOCK_TIME, \ - (Handler), \ - sizeof(KSPROPERTY), sizeof(LONGLONG), \ - NULL, NULL, 0, NULL, NULL, 0) - - # define DEFINE_KSPROPERTY_ITEM_CLOCK_PHYSICALTIME(Handler) \ - DEFINE_KSPROPERTY_ITEM( \ - KSPROPERTY_CLOCK_PHYSICALTIME, \ - (Handler), \ - sizeof(KSPROPERTY), sizeof(LONGLONG), \ - NULL, NULL, 0, NULL, NULL, 0) - - # define DEFINE_KSPROPERTY_ITEM_CLOCK_CORRELATEDTIME(Handler) \ - DEFINE_KSPROPERTY_ITEM( \ - KSPROPERTY_CLOCK_CORRELATEDTIME, \ - (Handler), \ - sizeof(KSPROPERTY), \ - sizeof(KSCORRELATED_TIME), \ - NULL, NULL, 0, NULL, NULL, 0) - - # define DEFINE_KSPROPERTY_ITEM_CLOCK_CORRELATEDPHYSICALTIME(Handler) \ - DEFINE_KSPROPERTY_ITEM( \ - KSPROPERTY_CLOCK_CORRELATEDPHYSICALTIME, \ - (Handler), \ - sizeof(KSPROPERTY), \ - sizeof(KSCORRELATED_TIME), \ - NULL, NULL, 0, NULL, NULL, 0) - - # define DEFINE_KSPROPERTY_ITEM_CLOCK_RESOLUTION(Handler) \ - DEFINE_KSPROPERTY_ITEM( \ - KSPROPERTY_CLOCK_RESOLUTION, \ - (Handler), \ - sizeof(KSPROPERTY), sizeof(KSRESOLUTION), \ - NULL, NULL, 0, NULL, NULL, 0) - - # define DEFINE_KSPROPERTY_ITEM_CLOCK_STATE(Handler) \ - DEFINE_KSPROPERTY_ITEM( \ - KSPROPERTY_CLOCK_STATE, \ - (Handler), \ - sizeof(KSPROPERTY), sizeof(KSSTATE), \ - NULL, NULL, 0, NULL, NULL, 0) - - # define DEFINE_KSPROPERTY_ITEM_CLOCK_FUNCTIONTABLE(Handler) \ - DEFINE_KSPROPERTY_ITEM( \ - KSPROPERTY_CLOCK_FUNCTIONTABLE, \ - (Handler), \ - sizeof(KSPROPERTY), \ - sizeof(KSCLOCK_FUNCTIONTABLE), \ - NULL, NULL, 0, NULL, NULL, 0) - - # define DEFINE_KSPROPERTY_CLOCKSET(ClockSet, PropTime, PropPhysicalTime, PropCorrelatedTime, PropCorrelatedPhysicalTime, PropResolution, PropState, PropFunctionTable) \ - DEFINE_KSPROPERTY_TABLE(ClockSet) { \ - DEFINE_KSPROPERTY_ITEM_CLOCK_TIME(PropTime), \ - DEFINE_KSPROPERTY_ITEM_CLOCK_PHYSICALTIME(PropPhysicalTime), \ - DEFINE_KSPROPERTY_ITEM_CLOCK_CORRELATEDTIME(PropCorrelatedTime), \ - DEFINE_KSPROPERTY_ITEM_CLOCK_CORRELATEDPHYSICALTIME(PropCorrelatedPhysicalTime), \ - DEFINE_KSPROPERTY_ITEM_CLOCK_RESOLUTION(PropResolution), \ - DEFINE_KSPROPERTY_ITEM_CLOCK_STATE(PropState), \ - DEFINE_KSPROPERTY_ITEM_CLOCK_FUNCTIONTABLE(PropFunctionTable), \ - } -#endif /* _NTDDK_ */ - -#define STATIC_KSEVENTSETID_Clock \ - 0x364D8E20L, 0x62C7, 0x11CF, 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00 -DEFINE_GUIDSTRUCT("364D8E20-62C7-11CF-A5D6-28DB04C10000", KSEVENTSETID_Clock); -#define KSEVENTSETID_Clock DEFINE_GUIDNAMED(KSEVENTSETID_Clock) - -typedef enum -{ - KSEVENT_CLOCK_INTERVAL_MARK, - KSEVENT_CLOCK_POSITION_MARK -}KSEVENT_CLOCK_POSITION; - -#define STATIC_KSEVENTSETID_Connection \ - 0x7f4bcbe0L, 0x9ea5, 0x11cf, 0xa5, 0xd6, 0x28, 0xdb, 0x04, 0xc1, 0x00, 0x00 -DEFINE_GUIDSTRUCT("7f4bcbe0-9ea5-11cf-a5d6-28db04c10000", KSEVENTSETID_Connection); -#define KSEVENTSETID_Connection DEFINE_GUIDNAMED(KSEVENTSETID_Connection) - -typedef enum -{ - KSEVENT_CONNECTION_POSITIONUPDATE, - KSEVENT_CONNECTION_DATADISCONTINUITY, - KSEVENT_CONNECTION_TIMEDISCONTINUITY, - KSEVENT_CONNECTION_PRIORITY, - KSEVENT_CONNECTION_ENDOFSTREAM -}KSEVENT_CONNECTION; - -typedef struct -{ - PVOID Context; - ULONG Proportion; - LONGLONG DeltaTime; -}KSQUALITY, * PKSQUALITY; - -typedef struct -{ - PVOID Context; - ULONG Status; -}KSERROR, * PKSERROR; - -typedef KSIDENTIFIER KSDEGRADE, * PKSDEGRADE; - -#define STATIC_KSDEGRADESETID_Standard \ - 0x9F564180L, 0x704C, 0x11D0, 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00 -DEFINE_GUIDSTRUCT("9F564180-704C-11D0-A5D6-28DB04C10000", KSDEGRADESETID_Standard); -#define KSDEGRADESETID_Standard DEFINE_GUIDNAMED(KSDEGRADESETID_Standard) - -typedef enum -{ - KSDEGRADE_STANDARD_SAMPLE, - KSDEGRADE_STANDARD_QUALITY, - KSDEGRADE_STANDARD_COMPUTATION, - KSDEGRADE_STANDARD_SKIP -}KSDEGRADE_STANDARD; - -#if defined(_NTDDK_) - - # define KSPROBE_STREAMREAD 0x00000000 - # define KSPROBE_STREAMWRITE 0x00000001 - # define KSPROBE_ALLOCATEMDL 0x00000010 - # define KSPROBE_PROBEANDLOCK 0x00000020 - # define KSPROBE_SYSTEMADDRESS 0x00000040 - # define KSPROBE_MODIFY 0x00000200 - # define KSPROBE_STREAMWRITEMODIFY (KSPROBE_MODIFY | KSPROBE_STREAMWRITE) - # define KSPROBE_ALLOWFORMATCHANGE 0x00000080 - # define KSSTREAM_READ KSPROBE_STREAMREAD - # define KSSTREAM_WRITE KSPROBE_STREAMWRITE - # define KSSTREAM_PAGED_DATA 0x00000000 - # define KSSTREAM_NONPAGED_DATA 0x00000100 - # define KSSTREAM_SYNCHRONOUS 0x00001000 - # define KSSTREAM_FAILUREEXCEPTION 0x00002000 - -typedef NTSTATUS (*PFNKSCONTEXT_DISPATCH)(PVOID Context, PIRP Irp); -typedef NTSTATUS (*PFNKSHANDLER)(PIRP Irp, PKSIDENTIFIER Request, PVOID Data); -typedef BOOLEAN (*PFNKSFASTHANDLER)(PFILE_OBJECT FileObject, - PKSIDENTIFIER Request, - ULONG RequestLength, PVOID Data, - ULONG DataLength, - PIO_STATUS_BLOCK IoStatus); -typedef NTSTATUS (*PFNKSALLOCATOR)(PIRP Irp, ULONG BufferSize, - BOOLEAN InputOperation); - -typedef struct -{ - KSPROPERTY_MEMBERSHEADER MembersHeader; - const VOID* Members; -}KSPROPERTY_MEMBERSLIST, * PKSPROPERTY_MEMBERSLIST; - -typedef struct -{ - KSIDENTIFIER PropTypeSet; - ULONG MembersListCount; - const KSPROPERTY_MEMBERSLIST* MembersList; -}KSPROPERTY_VALUES, * PKSPROPERTY_VALUES; - - # define DEFINE_KSPROPERTY_TABLE(tablename) \ - const KSPROPERTY_ITEM tablename[] = - - # define DEFINE_KSPROPERTY_ITEM(PropertyId, GetHandler, MinProperty, MinData, SetHandler, Values, RelationsCount, Relations, SupportHandler, SerializedSize) \ - { \ - PropertyId, (PFNKSHANDLER)GetHandler, \ - MinProperty, MinData, \ - (PFNKSHANDLER)SetHandler, \ - (PKSPROPERTY_VALUES)Values, RelationsCount, \ - (PKSPROPERTY)Relations, \ - (PFNKSHANDLER)SupportHandler, \ - (ULONG)SerializedSize \ - } - -typedef struct -{ - ULONG PropertyId; - __MINGW_EXTENSION union - { - PFNKSHANDLER GetPropertyHandler; - BOOLEAN GetSupported; - }; - ULONG MinProperty; - ULONG MinData; - __MINGW_EXTENSION union - { - PFNKSHANDLER SetPropertyHandler; - BOOLEAN SetSupported; - }; - const KSPROPERTY_VALUES* Values; - ULONG RelationsCount; - const KSPROPERTY* Relations; - PFNKSHANDLER SupportHandler; - ULONG SerializedSize; -}KSPROPERTY_ITEM, * PKSPROPERTY_ITEM; - - # define DEFINE_KSFASTPROPERTY_ITEM(PropertyId, GetHandler, SetHandler) \ - { \ - PropertyId, (PFNKSFASTHANDLER)GetHandler, \ - (PFNKSFASTHANDLER)SetHandler, 0 \ - } - -typedef struct -{ - ULONG PropertyId; - __MINGW_EXTENSION union - { - PFNKSFASTHANDLER GetPropertyHandler; - BOOLEAN GetSupported; - }; - __MINGW_EXTENSION union - { - PFNKSFASTHANDLER SetPropertyHandler; - BOOLEAN SetSupported; - }; - ULONG Reserved; -}KSFASTPROPERTY_ITEM, * PKSFASTPROPERTY_ITEM; - - # define DEFINE_KSPROPERTY_SET(Set, PropertiesCount, PropertyItem, FastIoCount, FastIoTable) \ - { \ - Set, \ - PropertiesCount, PropertyItem, \ - FastIoCount, FastIoTable \ - } - - # define DEFINE_KSPROPERTY_SET_TABLE(tablename) \ - const KSPROPERTY_SET tablename[] = - -typedef struct -{ - const GUID* Set; - ULONG PropertiesCount; - const KSPROPERTY_ITEM* PropertyItem; - ULONG FastIoCount; - const KSFASTPROPERTY_ITEM* FastIoTable; -}KSPROPERTY_SET, * PKSPROPERTY_SET; - - # define DEFINE_KSMETHOD_TABLE(tablename) \ - const KSMETHOD_ITEM tablename[] = - - # define DEFINE_KSMETHOD_ITEM(MethodId, Flags, MethodHandler, MinMethod, MinData, SupportHandler) \ - { \ - MethodId, (PFNKSHANDLER)MethodHandler, \ - MinMethod, MinData, \ - SupportHandler, Flags \ - } - -typedef struct -{ - ULONG MethodId; - __MINGW_EXTENSION union - { - PFNKSHANDLER MethodHandler; - BOOLEAN MethodSupported; - }; - ULONG MinMethod; - ULONG MinData; - PFNKSHANDLER SupportHandler; - ULONG Flags; -}KSMETHOD_ITEM, * PKSMETHOD_ITEM; - - # define DEFINE_KSFASTMETHOD_ITEM(MethodId, MethodHandler) \ - { \ - MethodId, (PFNKSFASTHANDLER)MethodHandler \ - } - -typedef struct -{ - ULONG MethodId; - __MINGW_EXTENSION union - { - PFNKSFASTHANDLER MethodHandler; - BOOLEAN MethodSupported; - }; -}KSFASTMETHOD_ITEM, * PKSFASTMETHOD_ITEM; - - # define DEFINE_KSMETHOD_SET(Set, MethodsCount, MethodItem, FastIoCount, FastIoTable) \ - { \ - Set, \ - MethodsCount, MethodItem, \ - FastIoCount, FastIoTable \ - } - - # define DEFINE_KSMETHOD_SET_TABLE(tablename) \ - const KSMETHOD_SET tablename[] = - -typedef struct -{ - const GUID* Set; - ULONG MethodsCount; - const KSMETHOD_ITEM* MethodItem; - ULONG FastIoCount; - const KSFASTMETHOD_ITEM* FastIoTable; -}KSMETHOD_SET, * PKSMETHOD_SET; - -typedef struct _KSEVENT_ENTRY KSEVENT_ENTRY, * PKSEVENT_ENTRY; -typedef NTSTATUS (*PFNKSADDEVENT)(PIRP Irp, PKSEVENTDATA EventData, - struct _KSEVENT_ENTRY* EventEntry); -typedef VOID (*PFNKSREMOVEEVENT)(PFILE_OBJECT FileObject, - struct _KSEVENT_ENTRY* EventEntry); - - # define DEFINE_KSEVENT_TABLE(tablename) \ - const KSEVENT_ITEM tablename[] = - - # define DEFINE_KSEVENT_ITEM(EventId, DataInput, ExtraEntryData, AddHandler, RemoveHandler, SupportHandler) \ - { \ - EventId, DataInput, ExtraEntryData, \ - AddHandler, RemoveHandler, SupportHandler \ - } - -typedef struct -{ - ULONG EventId; - ULONG DataInput; - ULONG ExtraEntryData; - PFNKSADDEVENT AddHandler; - PFNKSREMOVEEVENT RemoveHandler; - PFNKSHANDLER SupportHandler; -}KSEVENT_ITEM, * PKSEVENT_ITEM; - - # define DEFINE_KSEVENT_SET(Set, EventsCount, EventItem) \ - { \ - Set, EventsCount, EventItem \ - } - - # define DEFINE_KSEVENT_SET_TABLE(tablename) \ - const KSEVENT_SET tablename[] = - -typedef struct -{ - const GUID* Set; - ULONG EventsCount; - const KSEVENT_ITEM* EventItem; -}KSEVENT_SET, * PKSEVENT_SET; - -typedef struct -{ - KDPC Dpc; - ULONG ReferenceCount; - KSPIN_LOCK AccessLock; -}KSDPC_ITEM, * PKSDPC_ITEM; - -typedef struct -{ - KSDPC_ITEM DpcItem; - LIST_ENTRY BufferList; -}KSBUFFER_ITEM, * PKSBUFFER_ITEM; - - # define KSEVENT_ENTRY_DELETED 1 - # define KSEVENT_ENTRY_ONESHOT 2 - # define KSEVENT_ENTRY_BUFFERED 4 - -struct _KSEVENT_ENTRY -{ - LIST_ENTRY ListEntry; - PVOID Object; - __MINGW_EXTENSION union - { - PKSDPC_ITEM DpcItem; - PKSBUFFER_ITEM BufferItem; - }; - PKSEVENTDATA EventData; - ULONG NotificationType; - const KSEVENT_SET* EventSet; - const KSEVENT_ITEM* EventItem; - PFILE_OBJECT FileObject; - ULONG SemaphoreAdjustment; - ULONG Reserved; - ULONG Flags; -}; - -typedef enum -{ - KSEVENTS_NONE, - KSEVENTS_SPINLOCK, - KSEVENTS_MUTEX, - KSEVENTS_FMUTEX, - KSEVENTS_FMUTEXUNSAFE, - KSEVENTS_INTERRUPT, - KSEVENTS_ERESOURCE -}KSEVENTS_LOCKTYPE; - - # define KSDISPATCH_FASTIO 0x80000000 - -typedef struct -{ - PDRIVER_DISPATCH Create; - PVOID Context; - UNICODE_STRING ObjectClass; - PSECURITY_DESCRIPTOR SecurityDescriptor; - ULONG Flags; -}KSOBJECT_CREATE_ITEM, * PKSOBJECT_CREATE_ITEM; - -typedef VOID (*PFNKSITEMFREECALLBACK)(PKSOBJECT_CREATE_ITEM CreateItem); - - # define KSCREATE_ITEM_SECURITYCHANGED 0x00000001 - # define KSCREATE_ITEM_WILDCARD 0x00000002 - # define KSCREATE_ITEM_NOPARAMETERS 0x00000004 - # define KSCREATE_ITEM_FREEONSTOP 0x00000008 - - # define DEFINE_KSCREATE_DISPATCH_TABLE(tablename) \ - KSOBJECT_CREATE_ITEM tablename[] = - - # define DEFINE_KSCREATE_ITEM(DispatchCreate, TypeName, Context) \ - { \ - (DispatchCreate), (PVOID)(Context), \ - { \ - sizeof(TypeName) - sizeof(UNICODE_NULL), \ - sizeof(TypeName), \ - (PWCHAR)(TypeName) \ - }, \ - NULL, 0 \ - } - - # define DEFINE_KSCREATE_ITEMEX(DispatchCreate, TypeName, Context, Flags) \ - { \ - (DispatchCreate), \ - (PVOID)(Context), \ - { \ - sizeof(TypeName) - sizeof(UNICODE_NULL), \ - sizeof(TypeName), \ - (PWCHAR)(TypeName) \ - }, \ - NULL, (Flags) \ - } - - # define DEFINE_KSCREATE_ITEMNULL(DispatchCreate, Context) \ - { \ - DispatchCreate, Context, \ - { \ - 0, 0, NULL, \ - }, \ - NULL, 0 \ - } - -typedef struct -{ - ULONG CreateItemsCount; - PKSOBJECT_CREATE_ITEM CreateItemsList; -}KSOBJECT_CREATE, * PKSOBJECT_CREATE; - -typedef struct -{ - PDRIVER_DISPATCH DeviceIoControl; - PDRIVER_DISPATCH Read; - PDRIVER_DISPATCH Write; - PDRIVER_DISPATCH Flush; - PDRIVER_DISPATCH Close; - PDRIVER_DISPATCH QuerySecurity; - PDRIVER_DISPATCH SetSecurity; - PFAST_IO_DEVICE_CONTROL FastDeviceIoControl; - PFAST_IO_READ FastRead; - PFAST_IO_WRITE FastWrite; -}KSDISPATCH_TABLE, * PKSDISPATCH_TABLE; - - # define DEFINE_KSDISPATCH_TABLE(tablename, DeviceIoControl, Read, Write, Flush, Close, QuerySecurity, SetSecurity, FastDeviceIoControl, FastRead, FastWrite) \ - const KSDISPATCH_TABLE tablename = \ - { \ - DeviceIoControl, \ - Read, \ - Write, \ - Flush, \ - Close, \ - QuerySecurity, \ - SetSecurity, \ - FastDeviceIoControl, \ - FastRead, \ - FastWrite, \ - } - - # define KSCREATE_ITEM_IRP_STORAGE(Irp) \ - (*(PKSOBJECT_CREATE_ITEM*)&(Irp)->Tail.Overlay.DriverContext[0]) - # define KSEVENT_SET_IRP_STORAGE(Irp) \ - (*(const KSEVENT_SET**)&(Irp)->Tail.Overlay.DriverContext[0]) - # define KSEVENT_ITEM_IRP_STORAGE(Irp) \ - (*(const KSEVENT_ITEM**)&(Irp)->Tail.Overlay.DriverContext[3]) - # define KSEVENT_ENTRY_IRP_STORAGE(Irp) \ - (*(PKSEVENT_ENTRY*)&(Irp)->Tail.Overlay.DriverContext[0]) - # define KSMETHOD_SET_IRP_STORAGE(Irp) \ - (*(const KSMETHOD_SET**)&(Irp)->Tail.Overlay.DriverContext[0]) - # define KSMETHOD_ITEM_IRP_STORAGE(Irp) \ - (*(const KSMETHOD_ITEM**)&(Irp)->Tail.Overlay.DriverContext[3]) - # define KSMETHOD_TYPE_IRP_STORAGE(Irp) \ - (*(ULONG_PTR*)(&(Irp)->Tail.Overlay.DriverContext[2])) - # define KSQUEUE_SPINLOCK_IRP_STORAGE(Irp) \ - (*(PKSPIN_LOCK*)&(Irp)->Tail.Overlay.DriverContext[1]) - # define KSPROPERTY_SET_IRP_STORAGE(Irp) \ - (*(const KSPROPERTY_SET**)&(Irp)->Tail.Overlay.DriverContext[0]) - # define KSPROPERTY_ITEM_IRP_STORAGE(Irp) \ - (*(const KSPROPERTY_ITEM**)&(Irp)->Tail.Overlay.DriverContext[3]) - # define KSPROPERTY_ATTRIBUTES_IRP_STORAGE(Irp) \ - (*(PKSATTRIBUTE_LIST*)&(Irp)->Tail.Overlay.DriverContext[2]) - -typedef PVOID KSDEVICE_HEADER, KSOBJECT_HEADER; - -typedef enum -{ - KsInvokeOnSuccess = 1, - KsInvokeOnError = 2, - KsInvokeOnCancel = 4 -}KSCOMPLETION_INVOCATION; - -typedef enum -{ - KsListEntryTail, - KsListEntryHead -}KSLIST_ENTRY_LOCATION; - -typedef enum -{ - KsAcquireOnly, - KsAcquireAndRemove, - KsAcquireOnlySingleItem, - KsAcquireAndRemoveOnlySingleItem -}KSIRP_REMOVAL_OPERATION; - -typedef enum -{ - KsStackCopyToNewLocation, - KsStackReuseCurrentLocation, - KsStackUseNewLocation -}KSSTACK_USE; - -typedef enum -{ - KSTARGET_STATE_DISABLED, - KSTARGET_STATE_ENABLED -}KSTARGET_STATE; - -typedef NTSTATUS (*PFNKSIRPLISTCALLBACK)(PIRP Irp, PVOID Context); -typedef VOID (*PFNREFERENCEDEVICEOBJECT)(PVOID Context); -typedef VOID (*PFNDEREFERENCEDEVICEOBJECT)(PVOID Context); -typedef NTSTATUS (*PFNQUERYREFERENCESTRING)(PVOID Context, PWCHAR* String); - - # define BUS_INTERFACE_REFERENCE_VERSION 0x100 - -typedef struct -{ - INTERFACE Interface; - - PFNREFERENCEDEVICEOBJECT ReferenceDeviceObject; - PFNDEREFERENCEDEVICEOBJECT DereferenceDeviceObject; - PFNQUERYREFERENCESTRING QueryReferenceString; -}BUS_INTERFACE_REFERENCE, * PBUS_INTERFACE_REFERENCE; - - # define STATIC_REFERENCE_BUS_INTERFACE STATIC_KSMEDIUMSETID_Standard - # define REFERENCE_BUS_INTERFACE KSMEDIUMSETID_Standard - -#endif /* _NTDDK_ */ - -#ifndef PACK_PRAGMAS_NOT_SUPPORTED - # include -#endif - -typedef struct -{ - GUID PropertySet; - ULONG Count; -}KSPROPERTY_SERIALHDR, * PKSPROPERTY_SERIALHDR; - -#ifndef PACK_PRAGMAS_NOT_SUPPORTED - # include -#endif - -typedef struct -{ - KSIDENTIFIER PropTypeSet; - ULONG Id; - ULONG PropertyLength; -}KSPROPERTY_SERIAL, * PKSPROPERTY_SERIAL; - -#if defined(_NTDDK_) - - # define IOCTL_KS_HANDSHAKE \ - CTL_CODE(FILE_DEVICE_KS, 0x007, METHOD_NEITHER, FILE_ANY_ACCESS) - -typedef struct -{ - GUID ProtocolId; - PVOID Argument1; - PVOID Argument2; -}KSHANDSHAKE, * PKSHANDSHAKE; - -typedef struct _KSGATE KSGATE, * PKSGATE; - -struct _KSGATE -{ - LONG Count; - PKSGATE NextGate; -}; - -typedef PVOID KSOBJECT_BAG; - -typedef BOOLEAN (*PFNKSGENERATEEVENTCALLBACK)(PVOID Context, - PKSEVENT_ENTRY EventEntry); - -typedef NTSTATUS (*PFNKSDEVICECREATE)(PKSDEVICE Device); - -typedef NTSTATUS (*PFNKSDEVICEPNPSTART)(PKSDEVICE Device, PIRP Irp, - PCM_RESOURCE_LIST TranslatedResourceList, - PCM_RESOURCE_LIST UntranslatedResourceList); - -typedef NTSTATUS (*PFNKSDEVICE)(PKSDEVICE Device); - -typedef NTSTATUS (*PFNKSDEVICEIRP)(PKSDEVICE Device, PIRP Irp); - -typedef void (*PFNKSDEVICEIRPVOID)(PKSDEVICE Device, PIRP Irp); - -typedef NTSTATUS (*PFNKSDEVICEQUERYCAPABILITIES)(PKSDEVICE Device, PIRP Irp, - PDEVICE_CAPABILITIES Capabilities); - -typedef NTSTATUS (*PFNKSDEVICEQUERYPOWER)(PKSDEVICE Device, PIRP Irp, - DEVICE_POWER_STATE DeviceTo, - DEVICE_POWER_STATE DeviceFrom, - SYSTEM_POWER_STATE SystemTo, - SYSTEM_POWER_STATE SystemFrom, - POWER_ACTION Action); - -typedef void (*PFNKSDEVICESETPOWER)(PKSDEVICE Device, PIRP Irp, - DEVICE_POWER_STATE To, - DEVICE_POWER_STATE From); - -typedef NTSTATUS (*PFNKSFILTERFACTORYVOID)(PKSFILTERFACTORY FilterFactory); - -typedef void (*PFNKSFILTERFACTORYPOWER)(PKSFILTERFACTORY FilterFactory, - DEVICE_POWER_STATE State); - -typedef NTSTATUS (*PFNKSFILTERIRP)(PKSFILTER Filter, PIRP Irp); - -typedef NTSTATUS (*PFNKSFILTERPROCESS)(PKSFILTER Filter, - PKSPROCESSPIN_INDEXENTRY Index); - -typedef NTSTATUS (*PFNKSFILTERVOID)(PKSFILTER Filter); - -typedef void (*PFNKSFILTERPOWER)(PKSFILTER Filter, DEVICE_POWER_STATE State); - -typedef NTSTATUS (*PFNKSPINIRP)(PKSPIN Pin, PIRP Irp); - -typedef NTSTATUS (*PFNKSPINSETDEVICESTATE)(PKSPIN Pin, KSSTATE ToState, - KSSTATE FromState); - -typedef NTSTATUS (*PFNKSPINSETDATAFORMAT)(PKSPIN Pin, PKSDATAFORMAT OldFormat, - PKSMULTIPLE_ITEM OldAttributeList, - const KSDATARANGE* DataRange, - const KSATTRIBUTE_LIST* AttributeRange); - -typedef NTSTATUS (*PFNKSPINHANDSHAKE)(PKSPIN Pin, PKSHANDSHAKE In, - PKSHANDSHAKE Out); - -typedef NTSTATUS (*PFNKSPIN)(PKSPIN Pin); - -typedef void (*PFNKSPINVOID)(PKSPIN Pin); - -typedef void (*PFNKSPINPOWER)(PKSPIN Pin, DEVICE_POWER_STATE State); - -typedef BOOLEAN (*PFNKSPINSETTIMER)(PKSPIN Pin, PKTIMER Timer, - LARGE_INTEGER DueTime, PKDPC Dpc); - -typedef BOOLEAN (*PFNKSPINCANCELTIMER)(PKSPIN Pin, PKTIMER Timer); - -typedef LONGLONG (FASTCALL * PFNKSPINCORRELATEDTIME)(PKSPIN Pin, - PLONGLONG SystemTime); - -typedef void (*PFNKSPINRESOLUTION)(PKSPIN Pin, PKSRESOLUTION Resolution); - -typedef NTSTATUS (*PFNKSPININITIALIZEALLOCATOR)(PKSPIN Pin, - PKSALLOCATOR_FRAMING AllocatorFraming, - PVOID* Context); - -typedef void (*PFNKSSTREAMPOINTER)(PKSSTREAM_POINTER StreamPointer); - -typedef struct KSAUTOMATION_TABLE_ KSAUTOMATION_TABLE, * PKSAUTOMATION_TABLE; - -struct KSAUTOMATION_TABLE_ -{ - ULONG PropertySetsCount; - ULONG PropertyItemSize; - const KSPROPERTY_SET* PropertySets; - ULONG MethodSetsCount; - ULONG MethodItemSize; - const KSMETHOD_SET* MethodSets; - ULONG EventSetsCount; - ULONG EventItemSize; - const KSEVENT_SET* EventSets; - # ifndef _WIN64 - PVOID Alignment; - # endif -}; - - # define DEFINE_KSAUTOMATION_TABLE(table) \ - const KSAUTOMATION_TABLE table = - - # define DEFINE_KSAUTOMATION_PROPERTIES(table) \ - SIZEOF_ARRAY(table), \ - sizeof(KSPROPERTY_ITEM), \ - table - - # define DEFINE_KSAUTOMATION_METHODS(table) \ - SIZEOF_ARRAY(table), \ - sizeof(KSMETHOD_ITEM), \ - table - - # define DEFINE_KSAUTOMATION_EVENTS(table) \ - SIZEOF_ARRAY(table), \ - sizeof(KSEVENT_ITEM), \ - table - - # define DEFINE_KSAUTOMATION_PROPERTIES_NULL \ - 0, \ - sizeof(KSPROPERTY_ITEM), \ - NULL - - # define DEFINE_KSAUTOMATION_METHODS_NULL \ - 0, \ - sizeof(KSMETHOD_ITEM), \ - NULL - - # define DEFINE_KSAUTOMATION_EVENTS_NULL \ - 0, \ - sizeof(KSEVENT_ITEM), \ - NULL - - # define MIN_DEV_VER_FOR_QI (0x100) - -struct _KSDEVICE_DISPATCH -{ - PFNKSDEVICECREATE Add; - PFNKSDEVICEPNPSTART Start; - PFNKSDEVICE PostStart; - PFNKSDEVICEIRP QueryStop; - PFNKSDEVICEIRPVOID CancelStop; - PFNKSDEVICEIRPVOID Stop; - PFNKSDEVICEIRP QueryRemove; - PFNKSDEVICEIRPVOID CancelRemove; - PFNKSDEVICEIRPVOID Remove; - PFNKSDEVICEQUERYCAPABILITIES QueryCapabilities; - PFNKSDEVICEIRPVOID SurpriseRemoval; - PFNKSDEVICEQUERYPOWER QueryPower; - PFNKSDEVICESETPOWER SetPower; - PFNKSDEVICEIRP QueryInterface; -}; - -struct _KSFILTER_DISPATCH -{ - PFNKSFILTERIRP Create; - PFNKSFILTERIRP Close; - PFNKSFILTERPROCESS Process; - PFNKSFILTERVOID Reset; -}; - -struct _KSPIN_DISPATCH -{ - PFNKSPINIRP Create; - PFNKSPINIRP Close; - PFNKSPIN Process; - PFNKSPINVOID Reset; - PFNKSPINSETDATAFORMAT SetDataFormat; - PFNKSPINSETDEVICESTATE SetDeviceState; - PFNKSPIN Connect; - PFNKSPINVOID Disconnect; - const KSCLOCK_DISPATCH* Clock; - const KSALLOCATOR_DISPATCH* Allocator; -}; - -struct _KSCLOCK_DISPATCH -{ - PFNKSPINSETTIMER SetTimer; - PFNKSPINCANCELTIMER CancelTimer; - PFNKSPINCORRELATEDTIME CorrelatedTime; - PFNKSPINRESOLUTION Resolution; -}; - -struct _KSALLOCATOR_DISPATCH -{ - PFNKSPININITIALIZEALLOCATOR InitializeAllocator; - PFNKSDELETEALLOCATOR DeleteAllocator; - PFNKSDEFAULTALLOCATE Allocate; - PFNKSDEFAULTFREE Free; -}; - - # define KSDEVICE_DESCRIPTOR_VERSION (0x100) - -struct _KSDEVICE_DESCRIPTOR -{ - const KSDEVICE_DISPATCH* Dispatch; - ULONG FilterDescriptorsCount; - const KSFILTER_DESCRIPTOR* const* FilterDescriptors; - ULONG Version; -}; - -struct _KSFILTER_DESCRIPTOR -{ - const KSFILTER_DISPATCH* Dispatch; - const KSAUTOMATION_TABLE* AutomationTable; - ULONG Version; - # define KSFILTER_DESCRIPTOR_VERSION ((ULONG)-1) - ULONG Flags; - # define KSFILTER_FLAG_DISPATCH_LEVEL_PROCESSING 0x00000001 - # define KSFILTER_FLAG_CRITICAL_PROCESSING 0x00000002 - # define KSFILTER_FLAG_HYPERCRITICAL_PROCESSING 0x00000004 - # define KSFILTER_FLAG_RECEIVE_ZERO_LENGTH_SAMPLES 0x00000008 - # define KSFILTER_FLAG_DENY_USERMODE_ACCESS 0x80000000 - const GUID* ReferenceGuid; - ULONG PinDescriptorsCount; - ULONG PinDescriptorSize; - const KSPIN_DESCRIPTOR_EX* PinDescriptors; - ULONG CategoriesCount; - const GUID* Categories; - ULONG NodeDescriptorsCount; - ULONG NodeDescriptorSize; - const KSNODE_DESCRIPTOR* NodeDescriptors; - ULONG ConnectionsCount; - const KSTOPOLOGY_CONNECTION* Connections; - const KSCOMPONENTID* ComponentId; -}; - - # define DEFINE_KSFILTER_DESCRIPTOR(descriptor) \ - const KSFILTER_DESCRIPTOR descriptor = - - # define DEFINE_KSFILTER_PIN_DESCRIPTORS(table) \ - SIZEOF_ARRAY(table), \ - sizeof(table[0]), \ - table - - # define DEFINE_KSFILTER_CATEGORIES(table) \ - SIZEOF_ARRAY(table), \ - table - - # define DEFINE_KSFILTER_CATEGORY(category) \ - 1, \ - &(category) - - # define DEFINE_KSFILTER_CATEGORIES_NULL \ - 0, \ - NULL - - # define DEFINE_KSFILTER_NODE_DESCRIPTORS(table) \ - SIZEOF_ARRAY(table), \ - sizeof(table[0]), \ - table - - # define DEFINE_KSFILTER_NODE_DESCRIPTORS_NULL \ - 0, \ - sizeof(KSNODE_DESCRIPTOR), \ - NULL - - # define DEFINE_KSFILTER_CONNECTIONS(table) \ - SIZEOF_ARRAY(table), \ - table - - # define DEFINE_KSFILTER_DEFAULT_CONNECTIONS \ - 0, \ - NULL - - # define DEFINE_KSFILTER_DESCRIPTOR_TABLE(table) \ - const KSFILTER_DESCRIPTOR * const table[] = - -struct _KSPIN_DESCRIPTOR_EX -{ - const KSPIN_DISPATCH* Dispatch; - const KSAUTOMATION_TABLE* AutomationTable; - KSPIN_DESCRIPTOR PinDescriptor; - ULONG Flags; - # define KSPIN_FLAG_DISPATCH_LEVEL_PROCESSING KSFILTER_FLAG_DISPATCH_LEVEL_PROCESSING - # define KSPIN_FLAG_CRITICAL_PROCESSING KSFILTER_FLAG_CRITICAL_PROCESSING - # define KSPIN_FLAG_HYPERCRITICAL_PROCESSING KSFILTER_FLAG_HYPERCRITICAL_PROCESSING - # define KSPIN_FLAG_ASYNCHRONOUS_PROCESSING 0x00000008 - # define KSPIN_FLAG_DO_NOT_INITIATE_PROCESSING 0x00000010 - # define KSPIN_FLAG_INITIATE_PROCESSING_ON_EVERY_ARRIVAL 0x00000020 - # define KSPIN_FLAG_FRAMES_NOT_REQUIRED_FOR_PROCESSING 0x00000040 - # define KSPIN_FLAG_ENFORCE_FIFO 0x00000080 - # define KSPIN_FLAG_GENERATE_MAPPINGS 0x00000100 - # define KSPIN_FLAG_DISTINCT_TRAILING_EDGE 0x00000200 - # define KSPIN_FLAG_PROCESS_IN_RUN_STATE_ONLY 0x00010000 - # define KSPIN_FLAG_SPLITTER 0x00020000 - # define KSPIN_FLAG_USE_STANDARD_TRANSPORT 0x00040000 - # define KSPIN_FLAG_DO_NOT_USE_STANDARD_TRANSPORT 0x00080000 - # define KSPIN_FLAG_FIXED_FORMAT 0x00100000 - # define KSPIN_FLAG_GENERATE_EOS_EVENTS 0x00200000 - # define KSPIN_FLAG_RENDERER (KSPIN_FLAG_PROCESS_IN_RUN_STATE_ONLY | KSPIN_FLAG_GENERATE_EOS_EVENTS) - # define KSPIN_FLAG_IMPLEMENT_CLOCK 0x00400000 - # define KSPIN_FLAG_SOME_FRAMES_REQUIRED_FOR_PROCESSING 0x00800000 - # define KSPIN_FLAG_PROCESS_IF_ANY_IN_RUN_STATE 0x01000000 - # define KSPIN_FLAG_DENY_USERMODE_ACCESS 0x80000000 - ULONG InstancesPossible; - ULONG InstancesNecessary; - const KSALLOCATOR_FRAMING_EX* AllocatorFraming; - PFNKSINTERSECTHANDLEREX IntersectHandler; -}; - - # define DEFINE_KSPIN_DEFAULT_INTERFACES \ - 0, \ - NULL - - # define DEFINE_KSPIN_DEFAULT_MEDIUMS \ - 0, \ - NULL - -struct _KSNODE_DESCRIPTOR -{ - const KSAUTOMATION_TABLE* AutomationTable; - const GUID* Type; - const GUID* Name; - # ifndef _WIN64 - PVOID Alignment; - # endif -}; - - # ifndef _WIN64 - # define DEFINE_NODE_DESCRIPTOR(automation, type, name) \ - { (automation), (type), (name), NULL } - # else - # define DEFINE_NODE_DESCRIPTOR(automation, type, name) \ - { (automation), (type), (name) } - # endif - -struct _KSDEVICE -{ - const KSDEVICE_DESCRIPTOR* Descriptor; - KSOBJECT_BAG Bag; - PVOID Context; - PDEVICE_OBJECT FunctionalDeviceObject; - PDEVICE_OBJECT PhysicalDeviceObject; - PDEVICE_OBJECT NextDeviceObject; - BOOLEAN Started; - SYSTEM_POWER_STATE SystemPowerState; - DEVICE_POWER_STATE DevicePowerState; -}; - -struct _KSFILTERFACTORY -{ - const KSFILTER_DESCRIPTOR* FilterDescriptor; - KSOBJECT_BAG Bag; - PVOID Context; -}; - -struct _KSFILTER -{ - const KSFILTER_DESCRIPTOR* Descriptor; - KSOBJECT_BAG Bag; - PVOID Context; -}; - -struct _KSPIN -{ - const KSPIN_DESCRIPTOR_EX* Descriptor; - KSOBJECT_BAG Bag; - PVOID Context; - ULONG Id; - KSPIN_COMMUNICATION Communication; - BOOLEAN ConnectionIsExternal; - KSPIN_INTERFACE ConnectionInterface; - KSPIN_MEDIUM ConnectionMedium; - KSPRIORITY ConnectionPriority; - PKSDATAFORMAT ConnectionFormat; - PKSMULTIPLE_ITEM AttributeList; - ULONG StreamHeaderSize; - KSPIN_DATAFLOW DataFlow; - KSSTATE DeviceState; - KSRESET ResetState; - KSSTATE ClientState; -}; - -struct _KSMAPPING -{ - PHYSICAL_ADDRESS PhysicalAddress; - ULONG ByteCount; - ULONG Alignment; -}; - -struct _KSSTREAM_POINTER_OFFSET -{ - # if defined(_NTDDK_) - __MINGW_EXTENSION union - { - PUCHAR Data; - PKSMAPPING Mappings; - }; - # else - PUCHAR Data; - # endif /* _NTDDK_ */ - # ifndef _WIN64 - PVOID Alignment; - # endif - ULONG Count; - ULONG Remaining; -}; - -struct _KSSTREAM_POINTER -{ - PVOID Context; - PKSPIN Pin; - PKSSTREAM_HEADER StreamHeader; - PKSSTREAM_POINTER_OFFSET Offset; - KSSTREAM_POINTER_OFFSET OffsetIn; - KSSTREAM_POINTER_OFFSET OffsetOut; -}; - -struct _KSPROCESSPIN -{ - PKSPIN Pin; - PKSSTREAM_POINTER StreamPointer; - PKSPROCESSPIN InPlaceCounterpart; - PKSPROCESSPIN DelegateBranch; - PKSPROCESSPIN CopySource; - PVOID Data; - ULONG BytesAvailable; - ULONG BytesUsed; - ULONG Flags; - BOOLEAN Terminate; -}; - -struct _KSPROCESSPIN_INDEXENTRY -{ - PKSPROCESSPIN* Pins; - ULONG Count; -}; - -typedef enum -{ - KsObjectTypeDevice, - KsObjectTypeFilterFactory, - KsObjectTypeFilter, - KsObjectTypePin -}KSOBJECTTYPE; - -typedef void (*PFNKSFREE)(PVOID Data); - -typedef void (*PFNKSPINFRAMERETURN)(PKSPIN Pin, PVOID Data, ULONG Size, PMDL Mdl, - PVOID Context, NTSTATUS Status); - -typedef void (*PFNKSPINIRPCOMPLETION)(PKSPIN Pin, PIRP Irp); - - # if defined(_UNKNOWN_H_) || defined(__IUnknown_INTERFACE_DEFINED__) - # ifndef _IKsControl_ - # define _IKsControl_ - -typedef struct IKsControl* PIKSCONTROL; - - # ifndef DEFINE_ABSTRACT_UNKNOWN - # define DEFINE_ABSTRACT_UNKNOWN() \ - STDMETHOD_(NTSTATUS, QueryInterface) (THIS_ \ - REFIID InterfaceId, \ - PVOID * Interface \ - )PURE; \ - STDMETHOD_(ULONG, AddRef) (THIS)PURE; \ - STDMETHOD_(ULONG, Release) (THIS)PURE; - # endif - - # undef INTERFACE - # define INTERFACE IKsControl -DECLARE_INTERFACE_(IKsControl, IUnknown) -{ - DEFINE_ABSTRACT_UNKNOWN() - STDMETHOD_(NTSTATUS, KsProperty) (THIS_ - PKSPROPERTY Property, - ULONG PropertyLength, - PVOID PropertyData, - ULONG DataLength, - ULONG * BytesReturned - ) PURE; - STDMETHOD_(NTSTATUS, KsMethod) (THIS_ - PKSMETHOD Method, - ULONG MethodLength, - PVOID MethodData, - ULONG DataLength, - ULONG * BytesReturned - ) PURE; - STDMETHOD_(NTSTATUS, KsEvent) (THIS_ - PKSEVENT Event, - ULONG EventLength, - PVOID EventData, - ULONG DataLength, - ULONG * BytesReturned - ) PURE; -}; -typedef struct IKsReferenceClock* PIKSREFERENCECLOCK; - - # undef INTERFACE - # define INTERFACE IKsReferenceClock -DECLARE_INTERFACE_(IKsReferenceClock, IUnknown) -{ - DEFINE_ABSTRACT_UNKNOWN() - STDMETHOD_(LONGLONG, GetTime) (THIS) PURE; - STDMETHOD_(LONGLONG, GetPhysicalTime) (THIS) PURE; - STDMETHOD_(LONGLONG, GetCorrelatedTime) (THIS_ - PLONGLONG SystemTime - ) PURE; - STDMETHOD_(LONGLONG, GetCorrelatedPhysicalTime) (THIS_ - PLONGLONG SystemTime - ) PURE; - STDMETHOD_(NTSTATUS, GetResolution) (THIS_ - PKSRESOLUTION Resolution - ) PURE; - STDMETHOD_(NTSTATUS, GetState) (THIS_ - PKSSTATE State - ) PURE; -}; - # undef INTERFACE - - # define INTERFACE IKsDeviceFunctions -DECLARE_INTERFACE_(IKsDeviceFunctions, IUnknown) -{ - DEFINE_ABSTRACT_UNKNOWN() - STDMETHOD_(NTSTATUS, RegisterAdapterObjectEx) (THIS_ - PADAPTER_OBJECT AdapterObject, - PDEVICE_DESCRIPTION DeviceDescription, - ULONG NumberOfMapRegisters, - ULONG MaxMappingsByteCount, - ULONG MappingTableStride - ) PURE; -}; - - # undef INTERFACE - # define STATIC_IID_IKsControl \ - 0x28F54685L, 0x06FD, 0x11D2, 0xB2, 0x7A, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96 -DEFINE_GUID(IID_IKsControl, - 0x28F54685L, 0x06FD, 0x11D2, 0xB2, 0x7A, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96); - # define STATIC_IID_IKsFastClock \ - 0xc9902485, 0xc180, 0x11d2, 0x84, 0x73, 0xd4, 0x23, 0x94, 0x45, 0x9e, 0x5e -DEFINE_GUID(IID_IKsFastClock, - 0xc9902485, 0xc180, 0x11d2, 0x84, 0x73, 0xd4, 0x23, 0x94, 0x45, 0x9e, 0x5e); - # define STATIC_IID_IKsDeviceFunctions \ - 0xe234f2e2, 0xbd69, 0x4f8c, 0xb3, 0xf2, 0x7c, 0xd7, 0x9e, 0xd4, 0x66, 0xbd -DEFINE_GUID(IID_IKsDeviceFunctions, - 0xe234f2e2, 0xbd69, 0x4f8c, 0xb3, 0xf2, 0x7c, 0xd7, 0x9e, 0xd4, 0x66, 0xbd); - # endif /* _IKsControl_ */ - # endif /* defined(_UNKNOWN_H_) || defined(__IUnknown_INTERFACE_DEFINED__) */ - -#endif /* _NTDDK_ */ - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef _KSDDK_ - # define KSDDKAPI -#else - # define KSDDKAPI DECLSPEC_IMPORT -#endif - -#if defined(_NTDDK_) - -KSDDKAPI NTSTATUS NTAPI KsEnableEvent(PIRP Irp, ULONG EventSetsCount, const KSEVENT_SET* EventSet, PLIST_ENTRY EventsList, KSEVENTS_LOCKTYPE EventsFlags, PVOID EventsLock); - -KSDDKAPI NTSTATUS NTAPI KsEnableEventWithAllocator(PIRP Irp, ULONG EventSetsCount, const KSEVENT_SET* EventSet, PLIST_ENTRY EventsList, KSEVENTS_LOCKTYPE EventsFlags, PVOID EventsLock, PFNKSALLOCATOR Allocator, ULONG EventItemSize); - -KSDDKAPI NTSTATUS NTAPI KsDisableEvent(PIRP Irp, PLIST_ENTRY EventsList, KSEVENTS_LOCKTYPE EventsFlags, PVOID EventsLock); - -KSDDKAPI VOID NTAPI KsDiscardEvent(PKSEVENT_ENTRY EventEntry); - -KSDDKAPI VOID NTAPI KsFreeEventList(PFILE_OBJECT FileObject, PLIST_ENTRY EventsList, KSEVENTS_LOCKTYPE EventsFlags, PVOID EventsLock); - -KSDDKAPI NTSTATUS NTAPI KsGenerateEvent(PKSEVENT_ENTRY EventEntry); - -KSDDKAPI NTSTATUS NTAPI KsGenerateDataEvent(PKSEVENT_ENTRY EventEntry, ULONG DataSize, PVOID Data); - -KSDDKAPI VOID NTAPI KsGenerateEventList(GUID* Set, ULONG EventId, PLIST_ENTRY EventsList, KSEVENTS_LOCKTYPE EventsFlags, PVOID EventsLock); - -KSDDKAPI NTSTATUS NTAPI KsPropertyHandler(PIRP Irp, ULONG PropertySetsCount, const KSPROPERTY_SET* PropertySet); - -KSDDKAPI NTSTATUS NTAPI KsPropertyHandlerWithAllocator(PIRP Irp, ULONG PropertySetsCount, const KSPROPERTY_SET* PropertySet, PFNKSALLOCATOR Allocator, ULONG PropertyItemSize); - -KSDDKAPI BOOLEAN NTAPI KsFastPropertyHandler(PFILE_OBJECT FileObject, PKSPROPERTY Property, ULONG PropertyLength, PVOID Data, ULONG DataLength, PIO_STATUS_BLOCK IoStatus, ULONG PropertySetsCount, const KSPROPERTY_SET* PropertySet); - -KSDDKAPI NTSTATUS NTAPI KsMethodHandler(PIRP Irp, ULONG MethodSetsCount, const KSMETHOD_SET* MethodSet); - -KSDDKAPI NTSTATUS NTAPI KsMethodHandlerWithAllocator(PIRP Irp, ULONG MethodSetsCount, const KSMETHOD_SET* MethodSet, PFNKSALLOCATOR Allocator, ULONG MethodItemSize); - -KSDDKAPI BOOLEAN NTAPI KsFastMethodHandler(PFILE_OBJECT FileObject, PKSMETHOD Method, ULONG MethodLength, PVOID Data, ULONG DataLength, PIO_STATUS_BLOCK IoStatus, ULONG MethodSetsCount, const KSMETHOD_SET* MethodSet); - -KSDDKAPI NTSTATUS NTAPI KsCreateDefaultAllocator(PIRP Irp); - -KSDDKAPI NTSTATUS NTAPI KsCreateDefaultAllocatorEx(PIRP Irp, PVOID InitializeContext, PFNKSDEFAULTALLOCATE DefaultAllocate, PFNKSDEFAULTFREE DefaultFree, PFNKSINITIALIZEALLOCATOR InitializeAllocator, PFNKSDELETEALLOCATOR DeleteAllocator); - -KSDDKAPI NTSTATUS NTAPI KsCreateAllocator(HANDLE ConnectionHandle, PKSALLOCATOR_FRAMING AllocatorFraming, PHANDLE AllocatorHandle); - -KSDDKAPI NTSTATUS NTAPI KsValidateAllocatorCreateRequest(PIRP Irp, PKSALLOCATOR_FRAMING* AllocatorFraming); - -KSDDKAPI NTSTATUS NTAPI KsValidateAllocatorFramingEx(PKSALLOCATOR_FRAMING_EX Framing, ULONG BufferSize, const KSALLOCATOR_FRAMING_EX* PinFraming); - -KSDDKAPI NTSTATUS NTAPI KsAllocateDefaultClock(PKSDEFAULTCLOCK* DefaultClock); - -KSDDKAPI NTSTATUS NTAPI KsAllocateDefaultClockEx(PKSDEFAULTCLOCK* DefaultClock, PVOID Context, PFNKSSETTIMER SetTimer, PFNKSCANCELTIMER CancelTimer, PFNKSCORRELATEDTIME CorrelatedTime, const KSRESOLUTION* Resolution, ULONG Flags); - -KSDDKAPI VOID NTAPI KsFreeDefaultClock(PKSDEFAULTCLOCK DefaultClock); -KSDDKAPI NTSTATUS NTAPI KsCreateDefaultClock(PIRP Irp, PKSDEFAULTCLOCK DefaultClock); - -KSDDKAPI NTSTATUS NTAPI KsCreateClock(HANDLE ConnectionHandle, PKSCLOCK_CREATE ClockCreate, PHANDLE ClockHandle); - -KSDDKAPI NTSTATUS NTAPI KsValidateClockCreateRequest(PIRP Irp, PKSCLOCK_CREATE* ClockCreate); - -KSDDKAPI KSSTATE NTAPI KsGetDefaultClockState(PKSDEFAULTCLOCK DefaultClock); -KSDDKAPI VOID NTAPI KsSetDefaultClockState(PKSDEFAULTCLOCK DefaultClock, KSSTATE State); -KSDDKAPI LONGLONG NTAPI KsGetDefaultClockTime(PKSDEFAULTCLOCK DefaultClock); -KSDDKAPI VOID NTAPI KsSetDefaultClockTime(PKSDEFAULTCLOCK DefaultClock, LONGLONG Time); - -KSDDKAPI NTSTATUS NTAPI KsCreatePin(HANDLE FilterHandle, PKSPIN_CONNECT Connect, ACCESS_MASK DesiredAccess, PHANDLE ConnectionHandle); - -KSDDKAPI NTSTATUS NTAPI KsValidateConnectRequest(PIRP Irp, ULONG DescriptorsCount, const KSPIN_DESCRIPTOR* Descriptor, PKSPIN_CONNECT* Connect); - -KSDDKAPI NTSTATUS NTAPI KsPinPropertyHandler(PIRP Irp, PKSPROPERTY Property, PVOID Data, ULONG DescriptorsCount, const KSPIN_DESCRIPTOR* Descriptor); - -KSDDKAPI NTSTATUS NTAPI KsPinDataIntersection(PIRP Irp, PKSP_PIN Pin, PVOID Data, ULONG DescriptorsCount, const KSPIN_DESCRIPTOR* Descriptor, PFNKSINTERSECTHANDLER IntersectHandler); - -KSDDKAPI NTSTATUS NTAPI KsPinDataIntersectionEx(PIRP Irp, PKSP_PIN Pin, PVOID Data, ULONG DescriptorsCount, const KSPIN_DESCRIPTOR* Descriptor, ULONG DescriptorSize, PFNKSINTERSECTHANDLEREX IntersectHandler, PVOID HandlerContext); - -KSDDKAPI NTSTATUS NTAPI KsHandleSizedListQuery(PIRP Irp, ULONG DataItemsCount, ULONG DataItemSize, const VOID* DataItems); - - # ifndef MAKEINTRESOURCE - # define MAKEINTRESOURCE(r) ((ULONG_PTR)(USHORT)r) - # endif - # ifndef RT_STRING - # define RT_STRING MAKEINTRESOURCE(6) - # define RT_RCDATA MAKEINTRESOURCE(10) - # endif - -KSDDKAPI NTSTATUS NTAPI KsLoadResource(PVOID ImageBase, POOL_TYPE PoolType, ULONG_PTR ResourceName, ULONG ResourceType, PVOID* Resource, PULONG ResourceSize); - -KSDDKAPI NTSTATUS NTAPI KsGetImageNameAndResourceId(HANDLE RegKey, PUNICODE_STRING ImageName, PULONG_PTR ResourceId, PULONG ValueType); - -KSDDKAPI NTSTATUS NTAPI KsMapModuleName(PDEVICE_OBJECT PhysicalDeviceObject, PUNICODE_STRING ModuleName, PUNICODE_STRING ImageName, PULONG_PTR ResourceId, PULONG ValueType); - -KSDDKAPI NTSTATUS NTAPI KsReferenceBusObject(KSDEVICE_HEADER Header); -KSDDKAPI VOID NTAPI KsDereferenceBusObject(KSDEVICE_HEADER Header); -KSDDKAPI NTSTATUS NTAPI KsDispatchQuerySecurity(PDEVICE_OBJECT DeviceObject, PIRP Irp); -KSDDKAPI NTSTATUS NTAPI KsDispatchSetSecurity(PDEVICE_OBJECT DeviceObject, PIRP Irp); -KSDDKAPI NTSTATUS NTAPI KsDispatchSpecificProperty(PIRP Irp, PFNKSHANDLER Handler); -KSDDKAPI NTSTATUS NTAPI KsDispatchSpecificMethod(PIRP Irp, PFNKSHANDLER Handler); - -KSDDKAPI NTSTATUS NTAPI KsReadFile(PFILE_OBJECT FileObject, PKEVENT Event, PVOID PortContext, PIO_STATUS_BLOCK IoStatusBlock, PVOID Buffer, ULONG Length, ULONG Key, KPROCESSOR_MODE RequestorMode); - -KSDDKAPI NTSTATUS NTAPI KsWriteFile(PFILE_OBJECT FileObject, PKEVENT Event, PVOID PortContext, PIO_STATUS_BLOCK IoStatusBlock, PVOID Buffer, ULONG Length, ULONG Key, KPROCESSOR_MODE RequestorMode); - -KSDDKAPI NTSTATUS NTAPI KsQueryInformationFile(PFILE_OBJECT FileObject, PVOID FileInformation, ULONG Length, FILE_INFORMATION_CLASS FileInformationClass); - -KSDDKAPI NTSTATUS NTAPI KsSetInformationFile(PFILE_OBJECT FileObject, PVOID FileInformation, ULONG Length, FILE_INFORMATION_CLASS FileInformationClass); - -KSDDKAPI NTSTATUS NTAPI KsStreamIo(PFILE_OBJECT FileObject, PKEVENT Event, PVOID PortContext, PIO_COMPLETION_ROUTINE CompletionRoutine, PVOID CompletionContext, KSCOMPLETION_INVOCATION CompletionInvocationFlags, PIO_STATUS_BLOCK IoStatusBlock, PVOID StreamHeaders, ULONG Length, ULONG Flags, KPROCESSOR_MODE RequestorMode); - -KSDDKAPI NTSTATUS NTAPI KsProbeStreamIrp(PIRP Irp, ULONG ProbeFlags, ULONG HeaderSize); -KSDDKAPI NTSTATUS NTAPI KsAllocateExtraData(PIRP Irp, ULONG ExtraSize, PVOID* ExtraBuffer); -KSDDKAPI VOID NTAPI KsNullDriverUnload(PDRIVER_OBJECT DriverObject); - -KSDDKAPI NTSTATUS NTAPI KsSetMajorFunctionHandler(PDRIVER_OBJECT DriverObject, ULONG MajorFunction); - -KSDDKAPI NTSTATUS NTAPI KsDispatchInvalidDeviceRequest(PDEVICE_OBJECT DeviceObject, PIRP Irp); - -KSDDKAPI NTSTATUS NTAPI KsDefaultDeviceIoCompletion(PDEVICE_OBJECT DeviceObject, PIRP Irp); - -KSDDKAPI NTSTATUS NTAPI KsDispatchIrp(PDEVICE_OBJECT DeviceObject, PIRP Irp); - -KSDDKAPI BOOLEAN NTAPI KsDispatchFastIoDeviceControlFailure(PFILE_OBJECT FileObject, BOOLEAN Wait, PVOID InputBuffer, ULONG InputBufferLength, PVOID OutputBuffer, ULONG OutputBufferLength, ULONG IoControlCode, PIO_STATUS_BLOCK IoStatus, PDEVICE_OBJECT DeviceObject); - -KSDDKAPI BOOLEAN NTAPI KsDispatchFastReadFailure(PFILE_OBJECT FileObject, PLARGE_INTEGER FileOffset, ULONG Length, BOOLEAN Wait, ULONG LockKey, PVOID Buffer, PIO_STATUS_BLOCK IoStatus, PDEVICE_OBJECT DeviceObject); - - # define KsDispatchFastWriteFailure KsDispatchFastReadFailure - -KSDDKAPI VOID NTAPI KsCancelRoutine(PDEVICE_OBJECT DeviceObject, PIRP Irp); -KSDDKAPI VOID NTAPI KsCancelIo(PLIST_ENTRY QueueHead, PKSPIN_LOCK SpinLock); -KSDDKAPI VOID NTAPI KsReleaseIrpOnCancelableQueue(PIRP Irp, PDRIVER_CANCEL DriverCancel); - -KSDDKAPI PIRP NTAPI KsRemoveIrpFromCancelableQueue(PLIST_ENTRY QueueHead, PKSPIN_LOCK SpinLock, KSLIST_ENTRY_LOCATION ListLocation, KSIRP_REMOVAL_OPERATION RemovalOperation); - -KSDDKAPI NTSTATUS NTAPI KsMoveIrpsOnCancelableQueue(PLIST_ENTRY SourceList, PKSPIN_LOCK SourceLock, PLIST_ENTRY DestinationList, PKSPIN_LOCK DestinationLock, KSLIST_ENTRY_LOCATION ListLocation, PFNKSIRPLISTCALLBACK ListCallback, PVOID Context); - -KSDDKAPI VOID NTAPI KsRemoveSpecificIrpFromCancelableQueue(PIRP Irp); - -KSDDKAPI VOID NTAPI KsAddIrpToCancelableQueue(PLIST_ENTRY QueueHead, PKSPIN_LOCK SpinLock, PIRP Irp, KSLIST_ENTRY_LOCATION ListLocation, PDRIVER_CANCEL DriverCancel); - -KSDDKAPI NTSTATUS NTAPI KsAcquireResetValue(PIRP Irp, KSRESET* ResetValue); - -KSDDKAPI NTSTATUS NTAPI KsTopologyPropertyHandler(PIRP Irp, PKSPROPERTY Property, PVOID Data, const KSTOPOLOGY* Topology); - -KSDDKAPI VOID NTAPI KsAcquireDeviceSecurityLock(KSDEVICE_HEADER Header, BOOLEAN Exclusive); -KSDDKAPI VOID NTAPI KsReleaseDeviceSecurityLock(KSDEVICE_HEADER Header); -KSDDKAPI NTSTATUS NTAPI KsDefaultDispatchPnp(PDEVICE_OBJECT DeviceObject, PIRP Irp); -KSDDKAPI NTSTATUS NTAPI KsDefaultDispatchPower(PDEVICE_OBJECT DeviceObject, PIRP Irp); -KSDDKAPI NTSTATUS NTAPI KsDefaultForwardIrp(PDEVICE_OBJECT DeviceObject, PIRP Irp); - -KSDDKAPI VOID NTAPI KsSetDevicePnpAndBaseObject(KSDEVICE_HEADER Header, PDEVICE_OBJECT PnpDeviceObject, PDEVICE_OBJECT BaseObject); - -KSDDKAPI PDEVICE_OBJECT NTAPI KsQueryDevicePnpObject(KSDEVICE_HEADER Header); -KSDDKAPI ACCESS_MASK NTAPI KsQueryObjectAccessMask(KSOBJECT_HEADER Header); - -KSDDKAPI VOID NTAPI KsRecalculateStackDepth(KSDEVICE_HEADER Header, BOOLEAN ReuseStackLocation); - -KSDDKAPI VOID NTAPI KsSetTargetState(KSOBJECT_HEADER Header, KSTARGET_STATE TargetState); - -KSDDKAPI VOID NTAPI KsSetTargetDeviceObject(KSOBJECT_HEADER Header, PDEVICE_OBJECT TargetDevice); - -KSDDKAPI VOID NTAPI KsSetPowerDispatch(KSOBJECT_HEADER Header, PFNKSCONTEXT_DISPATCH PowerDispatch, PVOID PowerContext); - -KSDDKAPI PKSOBJECT_CREATE_ITEM NTAPI KsQueryObjectCreateItem(KSOBJECT_HEADER Header); - -KSDDKAPI NTSTATUS NTAPI KsAllocateDeviceHeader(KSDEVICE_HEADER* Header, ULONG ItemsCount, PKSOBJECT_CREATE_ITEM ItemsList); - -KSDDKAPI VOID NTAPI KsFreeDeviceHeader(KSDEVICE_HEADER Header); - -KSDDKAPI NTSTATUS NTAPI KsAllocateObjectHeader(KSOBJECT_HEADER* Header, ULONG ItemsCount, PKSOBJECT_CREATE_ITEM ItemsList, PIRP Irp, const KSDISPATCH_TABLE* Table); - -KSDDKAPI VOID NTAPI KsFreeObjectHeader(KSOBJECT_HEADER Header); - -KSDDKAPI NTSTATUS NTAPI KsAddObjectCreateItemToDeviceHeader(KSDEVICE_HEADER Header, PDRIVER_DISPATCH Create, PVOID Context, PWSTR ObjectClass, PSECURITY_DESCRIPTOR SecurityDescriptor); - -KSDDKAPI NTSTATUS NTAPI KsAddObjectCreateItemToObjectHeader(KSOBJECT_HEADER Header, PDRIVER_DISPATCH Create, PVOID Context, PWSTR ObjectClass, PSECURITY_DESCRIPTOR SecurityDescriptor); - -KSDDKAPI NTSTATUS NTAPI KsAllocateObjectCreateItem(KSDEVICE_HEADER Header, PKSOBJECT_CREATE_ITEM CreateItem, BOOLEAN AllocateEntry, PFNKSITEMFREECALLBACK ItemFreeCallback); - -KSDDKAPI NTSTATUS NTAPI KsFreeObjectCreateItem(KSDEVICE_HEADER Header, PUNICODE_STRING CreateItem); - -KSDDKAPI NTSTATUS NTAPI KsFreeObjectCreateItemsByContext(KSDEVICE_HEADER Header, PVOID Context); - -KSDDKAPI NTSTATUS NTAPI KsCreateDefaultSecurity(PSECURITY_DESCRIPTOR ParentSecurity, PSECURITY_DESCRIPTOR* DefaultSecurity); - -KSDDKAPI NTSTATUS NTAPI KsForwardIrp(PIRP Irp, PFILE_OBJECT FileObject, BOOLEAN ReuseStackLocation); - -KSDDKAPI NTSTATUS NTAPI KsForwardAndCatchIrp(PDEVICE_OBJECT DeviceObject, PIRP Irp, PFILE_OBJECT FileObject, KSSTACK_USE StackUse); - -KSDDKAPI NTSTATUS NTAPI KsSynchronousIoControlDevice(PFILE_OBJECT FileObject, KPROCESSOR_MODE RequestorMode, ULONG IoControl, PVOID InBuffer, ULONG InSize, PVOID OutBuffer, ULONG OutSize, PULONG BytesReturned); - -KSDDKAPI NTSTATUS NTAPI KsUnserializeObjectPropertiesFromRegistry(PFILE_OBJECT FileObject, HANDLE ParentKey, PUNICODE_STRING RegistryPath); - -KSDDKAPI NTSTATUS NTAPI KsCacheMedium(PUNICODE_STRING SymbolicLink, PKSPIN_MEDIUM Medium, ULONG PinDirection); - -KSDDKAPI NTSTATUS NTAPI KsRegisterWorker(WORK_QUEUE_TYPE WorkQueueType, PKSWORKER* Worker); - -KSDDKAPI NTSTATUS NTAPI KsRegisterCountedWorker(WORK_QUEUE_TYPE WorkQueueType, PWORK_QUEUE_ITEM CountedWorkItem, PKSWORKER* Worker); - -KSDDKAPI VOID NTAPI KsUnregisterWorker(PKSWORKER Worker); -KSDDKAPI NTSTATUS NTAPI KsQueueWorkItem(PKSWORKER Worker, PWORK_QUEUE_ITEM WorkItem); -KSDDKAPI ULONG NTAPI KsIncrementCountedWorker(PKSWORKER Worker); -KSDDKAPI ULONG NTAPI KsDecrementCountedWorker(PKSWORKER Worker); - -KSDDKAPI NTSTATUS NTAPI KsCreateTopologyNode(HANDLE ParentHandle, PKSNODE_CREATE NodeCreate, ACCESS_MASK DesiredAccess, PHANDLE NodeHandle); - -KSDDKAPI NTSTATUS NTAPI KsValidateTopologyNodeCreateRequest(PIRP Irp, PKSTOPOLOGY Topology, PKSNODE_CREATE* NodeCreate); - -KSDDKAPI NTSTATUS NTAPI KsMergeAutomationTables(PKSAUTOMATION_TABLE* AutomationTableAB, PKSAUTOMATION_TABLE AutomationTableA, PKSAUTOMATION_TABLE AutomationTableB, KSOBJECT_BAG Bag); - -KSDDKAPI NTSTATUS NTAPI KsInitializeDriver(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPathName, const KSDEVICE_DESCRIPTOR* Descriptor); - -KSDDKAPI NTSTATUS NTAPI KsAddDevice(PDRIVER_OBJECT DriverObject, PDEVICE_OBJECT PhysicalDeviceObject); - -KSDDKAPI NTSTATUS NTAPI KsCreateDevice(PDRIVER_OBJECT DriverObject, PDEVICE_OBJECT PhysicalDeviceObject, const KSDEVICE_DESCRIPTOR* Descriptor, ULONG ExtensionSize, PKSDEVICE* Device); - -KSDDKAPI NTSTATUS NTAPI KsInitializeDevice(PDEVICE_OBJECT FunctionalDeviceObject, PDEVICE_OBJECT PhysicalDeviceObject, PDEVICE_OBJECT NextDeviceObject, const KSDEVICE_DESCRIPTOR* Descriptor); - -KSDDKAPI void NTAPI KsTerminateDevice(PDEVICE_OBJECT DeviceObject); -KSDDKAPI PKSDEVICE NTAPI KsGetDeviceForDeviceObject(PDEVICE_OBJECT FunctionalDeviceObject); -KSDDKAPI void NTAPI KsAcquireDevice(PKSDEVICE Device); -KSDDKAPI void NTAPI KsReleaseDevice(PKSDEVICE Device); - -KSDDKAPI void NTAPI KsDeviceRegisterAdapterObject(PKSDEVICE Device, PADAPTER_OBJECT AdapterObject, ULONG MaxMappingsByteCount, ULONG MappingTableStride); - -KSDDKAPI ULONG NTAPI KsDeviceGetBusData(PKSDEVICE Device, ULONG DataType, PVOID Buffer, ULONG Offset, ULONG Length); - -KSDDKAPI ULONG NTAPI KsDeviceSetBusData(PKSDEVICE Device, ULONG DataType, PVOID Buffer, ULONG Offset, ULONG Length); - -KSDDKAPI NTSTATUS NTAPI KsCreateFilterFactory(PDEVICE_OBJECT DeviceObject, const KSFILTER_DESCRIPTOR* Descriptor, PWSTR RefString, PSECURITY_DESCRIPTOR SecurityDescriptor, ULONG CreateItemFlags, PFNKSFILTERFACTORYPOWER SleepCallback, PFNKSFILTERFACTORYPOWER WakeCallback, PKSFILTERFACTORY* FilterFactory); - - # define KsDeleteFilterFactory(FilterFactory) \ - KsFreeObjectCreateItemsByContext(*(KSDEVICE_HEADER*)( \ - KsFilterFactoryGetParentDevice(FilterFactory)->FunctionalDeviceObject->DeviceExtension), \ - FilterFactory) - -KSDDKAPI NTSTATUS NTAPI KsFilterFactoryUpdateCacheData(PKSFILTERFACTORY FilterFactory, const KSFILTER_DESCRIPTOR* FilterDescriptor); - -KSDDKAPI NTSTATUS NTAPI KsFilterFactoryAddCreateItem(PKSFILTERFACTORY FilterFactory, PWSTR RefString, PSECURITY_DESCRIPTOR SecurityDescriptor, ULONG CreateItemFlags); - -KSDDKAPI NTSTATUS NTAPI KsFilterFactorySetDeviceClassesState(PKSFILTERFACTORY FilterFactory, BOOLEAN NewState); - -KSDDKAPI PUNICODE_STRING NTAPI KsFilterFactoryGetSymbolicLink(PKSFILTERFACTORY FilterFactory); - -KSDDKAPI void NTAPI KsAddEvent(PVOID Object, PKSEVENT_ENTRY EventEntry); - -void __forceinline KsFilterAddEvent(PKSFILTER Filter, PKSEVENT_ENTRY EventEntry) -{ - KsAddEvent(Filter, EventEntry); -} - -void __forceinline KsPinAddEvent(PKSPIN Pin, PKSEVENT_ENTRY EventEntry) -{ - KsAddEvent(Pin, EventEntry); -} - -KSDDKAPI NTSTATUS NTAPI KsDefaultAddEventHandler(PIRP Irp, PKSEVENTDATA EventData, PKSEVENT_ENTRY EventEntry); - -KSDDKAPI void NTAPI KsGenerateEvents(PVOID Object, const GUID* EventSet, ULONG EventId, ULONG DataSize, PVOID Data, PFNKSGENERATEEVENTCALLBACK CallBack, PVOID CallBackContext); - -void __forceinline KsFilterGenerateEvents(PKSFILTER Filter, const GUID* EventSet, ULONG EventId, ULONG DataSize, PVOID Data, PFNKSGENERATEEVENTCALLBACK CallBack, PVOID CallBackContext) -{ - KsGenerateEvents(Filter, EventSet, EventId, DataSize, Data, CallBack, - CallBackContext); -} - -void __forceinline KsPinGenerateEvents(PKSPIN Pin, const GUID* EventSet, ULONG EventId, ULONG DataSize, PVOID Data, PFNKSGENERATEEVENTCALLBACK CallBack, PVOID CallBackContext) -{ - KsGenerateEvents(Pin, EventSet, EventId, DataSize, Data, CallBack, - CallBackContext); -} - -typedef enum -{ - KSSTREAM_POINTER_STATE_UNLOCKED = 0, - KSSTREAM_POINTER_STATE_LOCKED -}KSSTREAM_POINTER_STATE; - -KSDDKAPI NTSTATUS NTAPI KsPinGetAvailableByteCount(PKSPIN Pin, PLONG InputDataBytes, PLONG OutputBufferBytes); - -KSDDKAPI PKSSTREAM_POINTER NTAPI KsPinGetLeadingEdgeStreamPointer(PKSPIN Pin, KSSTREAM_POINTER_STATE State); - -KSDDKAPI PKSSTREAM_POINTER NTAPI KsPinGetTrailingEdgeStreamPointer(PKSPIN Pin, KSSTREAM_POINTER_STATE State); - -KSDDKAPI NTSTATUS NTAPI KsStreamPointerSetStatusCode(PKSSTREAM_POINTER StreamPointer, NTSTATUS Status); - -KSDDKAPI NTSTATUS NTAPI KsStreamPointerLock(PKSSTREAM_POINTER StreamPointer); -KSDDKAPI void NTAPI KsStreamPointerUnlock(PKSSTREAM_POINTER StreamPointer, BOOLEAN Eject); - -KSDDKAPI void NTAPI KsStreamPointerAdvanceOffsetsAndUnlock(PKSSTREAM_POINTER StreamPointer, ULONG InUsed, ULONG OutUsed, BOOLEAN Eject); - -KSDDKAPI void NTAPI KsStreamPointerDelete(PKSSTREAM_POINTER StreamPointer); - -KSDDKAPI NTSTATUS NTAPI KsStreamPointerClone(PKSSTREAM_POINTER StreamPointer, PFNKSSTREAMPOINTER CancelCallback, ULONG ContextSize, PKSSTREAM_POINTER* CloneStreamPointer); - -KSDDKAPI NTSTATUS NTAPI KsStreamPointerAdvanceOffsets(PKSSTREAM_POINTER StreamPointer, ULONG InUsed, ULONG OutUsed, BOOLEAN Eject); - -KSDDKAPI NTSTATUS NTAPI KsStreamPointerAdvance(PKSSTREAM_POINTER StreamPointer); -KSDDKAPI PMDL NTAPI KsStreamPointerGetMdl(PKSSTREAM_POINTER StreamPointer); - -KSDDKAPI PIRP NTAPI KsStreamPointerGetIrp(PKSSTREAM_POINTER StreamPointer, PBOOLEAN FirstFrameInIrp, PBOOLEAN LastFrameInIrp); - -KSDDKAPI void NTAPI KsStreamPointerScheduleTimeout(PKSSTREAM_POINTER StreamPointer, PFNKSSTREAMPOINTER Callback, ULONGLONG Interval); - -KSDDKAPI void NTAPI KsStreamPointerCancelTimeout(PKSSTREAM_POINTER StreamPointer); -KSDDKAPI PKSSTREAM_POINTER NTAPI KsPinGetFirstCloneStreamPointer(PKSPIN Pin); - -KSDDKAPI PKSSTREAM_POINTER NTAPI KsStreamPointerGetNextClone(PKSSTREAM_POINTER StreamPointer); - -KSDDKAPI NTSTATUS NTAPI KsPinHandshake(PKSPIN Pin, PKSHANDSHAKE In, PKSHANDSHAKE Out); -KSDDKAPI void NTAPI KsCompletePendingRequest(PIRP Irp); -KSDDKAPI KSOBJECTTYPE NTAPI KsGetObjectTypeFromIrp(PIRP Irp); -KSDDKAPI PVOID NTAPI KsGetObjectFromFileObject(PFILE_OBJECT FileObject); -KSDDKAPI KSOBJECTTYPE NTAPI KsGetObjectTypeFromFileObject(PFILE_OBJECT FileObject); - -PKSFILTER __forceinline KsGetFilterFromFileObject(PFILE_OBJECT FileObject) -{ - return (PKSFILTER)KsGetObjectFromFileObject(FileObject); -} - -PKSPIN __forceinline KsGetPinFromFileObject(PFILE_OBJECT FileObject) -{ - return (PKSPIN)KsGetObjectFromFileObject(FileObject); -} - -KSDDKAPI PKSGATE NTAPI KsFilterGetAndGate(PKSFILTER Filter); -KSDDKAPI void NTAPI KsFilterAcquireProcessingMutex(PKSFILTER Filter); -KSDDKAPI void NTAPI KsFilterReleaseProcessingMutex(PKSFILTER Filter); -KSDDKAPI void NTAPI KsFilterAttemptProcessing(PKSFILTER Filter, BOOLEAN Asynchronous); -KSDDKAPI PKSGATE NTAPI KsPinGetAndGate(PKSPIN Pin); -KSDDKAPI void NTAPI KsPinAttachAndGate(PKSPIN Pin, PKSGATE AndGate); -KSDDKAPI void NTAPI KsPinAttachOrGate(PKSPIN Pin, PKSGATE OrGate); -KSDDKAPI void NTAPI KsPinAcquireProcessingMutex(PKSPIN Pin); -KSDDKAPI void NTAPI KsPinReleaseProcessingMutex(PKSPIN Pin); -KSDDKAPI BOOLEAN NTAPI KsProcessPinUpdate(PKSPROCESSPIN ProcessPin); - -KSDDKAPI void NTAPI KsPinGetCopyRelationships(PKSPIN Pin, PKSPIN* CopySource, PKSPIN* DelegateBranch); - -KSDDKAPI void NTAPI KsPinAttemptProcessing(PKSPIN Pin, BOOLEAN Asynchronous); -KSDDKAPI PVOID NTAPI KsGetParent(PVOID Object); - -PKSDEVICE __forceinline KsFilterFactoryGetParentDevice(PKSFILTERFACTORY FilterFactory) -{ - return (PKSDEVICE)KsGetParent((PVOID)FilterFactory); -} - -PKSFILTERFACTORY __forceinline KsFilterGetParentFilterFactory(PKSFILTER Filter) -{ - return (PKSFILTERFACTORY)KsGetParent((PVOID)Filter); -} - -KSDDKAPI PKSFILTER NTAPI KsPinGetParentFilter(PKSPIN Pin); -KSDDKAPI PVOID NTAPI KsGetFirstChild(PVOID Object); - -PKSFILTERFACTORY __forceinline KsDeviceGetFirstChildFilterFactory(PKSDEVICE Device) -{ - return (PKSFILTERFACTORY)KsGetFirstChild((PVOID)Device); -} - -PKSFILTER __forceinline KsFilterFactoryGetFirstChildFilter(PKSFILTERFACTORY FilterFactory) -{ - return (PKSFILTER)KsGetFirstChild((PVOID)FilterFactory); -} - -KSDDKAPI ULONG NTAPI KsFilterGetChildPinCount(PKSFILTER Filter, ULONG PinId); -KSDDKAPI PKSPIN NTAPI KsFilterGetFirstChildPin(PKSFILTER Filter, ULONG PinId); -KSDDKAPI PVOID NTAPI KsGetNextSibling(PVOID Object); -KSDDKAPI PKSPIN NTAPI KsPinGetNextSiblingPin(PKSPIN Pin); - -PKSFILTERFACTORY __forceinline KsFilterFactoryGetNextSiblingFilterFactory(PKSFILTERFACTORY FilterFactory) -{ - return (PKSFILTERFACTORY)KsGetNextSibling((PVOID)FilterFactory); -} - -PKSFILTER __forceinline KsFilterGetNextSiblingFilter(PKSFILTER Filter) -{ - return (PKSFILTER)KsGetNextSibling((PVOID)Filter); -} - -KSDDKAPI PKSDEVICE NTAPI KsGetDevice(PVOID Object); - -PKSDEVICE __forceinline KsFilterFactoryGetDevice(PKSFILTERFACTORY FilterFactory) -{ - return KsGetDevice((PVOID)FilterFactory); -} - -PKSDEVICE __forceinline KsFilterGetDevice(PKSFILTER Filter) -{ - return KsGetDevice((PVOID)Filter); -} - -PKSDEVICE __forceinline KsPinGetDevice(PKSPIN Pin) -{ - return KsGetDevice((PVOID)Pin); -} - -KSDDKAPI PKSFILTER NTAPI KsGetFilterFromIrp(PIRP Irp); -KSDDKAPI PKSPIN NTAPI KsGetPinFromIrp(PIRP Irp); -KSDDKAPI ULONG NTAPI KsGetNodeIdFromIrp(PIRP Irp); -KSDDKAPI void NTAPI KsAcquireControl(PVOID Object); -KSDDKAPI void NTAPI KsReleaseControl(PVOID Object); - -void __forceinline KsFilterAcquireControl(PKSFILTER Filter) -{ - KsAcquireControl((PVOID)Filter); -} - -void __forceinline KsFilterReleaseControl(PKSFILTER Filter) -{ - KsReleaseControl((PVOID)Filter); -} - -void __forceinline KsPinAcquireControl(PKSPIN Pin) -{ - KsAcquireControl((PVOID)Pin); -} - -void __forceinline KsPinReleaseControl(PKSPIN Pin) -{ - KsReleaseControl((PVOID)Pin); -} - -KSDDKAPI NTSTATUS NTAPI KsAddItemToObjectBag(KSOBJECT_BAG ObjectBag, PVOID Item, PFNKSFREE Free); - -KSDDKAPI ULONG NTAPI KsRemoveItemFromObjectBag(KSOBJECT_BAG ObjectBag, PVOID Item, BOOLEAN Free); - - # define KsDiscard(Object, Pointer) \ - KsRemoveItemFromObjectBag((Object)->Bag, (PVOID)(Pointer), TRUE) - -KSDDKAPI NTSTATUS NTAPI KsAllocateObjectBag(PKSDEVICE Device, KSOBJECT_BAG* ObjectBag); -KSDDKAPI void NTAPI KsFreeObjectBag(KSOBJECT_BAG ObjectBag); - -KSDDKAPI NTSTATUS NTAPI KsCopyObjectBagItems(KSOBJECT_BAG ObjectBagDestination, KSOBJECT_BAG ObjectBagSource); - -KSDDKAPI NTSTATUS NTAPI _KsEdit(KSOBJECT_BAG ObjectBag, PVOID* PointerToPointerToItem, ULONG NewSize, ULONG OldSize, ULONG Tag); - - # define KsEdit(Object, PointerToPointer, Tag) \ - _KsEdit((Object)->Bag, (PVOID*)(PointerToPointer), \ - sizeof(**(PointerToPointer)), sizeof(**(PointerToPointer)), (Tag)) - - # define KsEditSized(Object, PointerToPointer, NewSize, OldSize, Tag) \ - _KsEdit((Object)->Bag, (PVOID*)(PointerToPointer), (NewSize), (OldSize), (Tag)) - -KSDDKAPI NTSTATUS NTAPI KsRegisterFilterWithNoKSPins(PDEVICE_OBJECT DeviceObject, const GUID* InterfaceClassGUID, ULONG PinCount, WINBOOL* PinDirection, KSPIN_MEDIUM* MediumList, GUID* CategoryList); - -KSDDKAPI NTSTATUS NTAPI KsFilterCreatePinFactory(PKSFILTER Filter, const KSPIN_DESCRIPTOR_EX* const PinDescriptor, PULONG PinID); - -KSDDKAPI NTSTATUS NTAPI KsFilterCreateNode(PKSFILTER Filter, const KSNODE_DESCRIPTOR* const NodeDescriptor, PULONG NodeID); - -KSDDKAPI NTSTATUS NTAPI KsFilterAddTopologyConnections(PKSFILTER Filter, ULONG NewConnectionsCount, const KSTOPOLOGY_CONNECTION* const NewTopologyConnections); - -KSDDKAPI NTSTATUS NTAPI KsPinGetConnectedPinInterface(PKSPIN Pin, const GUID* InterfaceId, PVOID* Interface); - -KSDDKAPI PFILE_OBJECT NTAPI KsPinGetConnectedPinFileObject(PKSPIN Pin); -KSDDKAPI PDEVICE_OBJECT NTAPI KsPinGetConnectedPinDeviceObject(PKSPIN Pin); - -KSDDKAPI NTSTATUS NTAPI KsPinGetConnectedFilterInterface(PKSPIN Pin, const GUID* InterfaceId, PVOID* Interface); - - # if defined(_UNKNOWN_H_) || defined(__IUnknown_INTERFACE_DEFINED__) -KSDDKAPI NTSTATUS NTAPI KsPinGetReferenceClockInterface(PKSPIN Pin, PIKSREFERENCECLOCK* Interface); - # endif /* defined(_UNKNOWN_H_) || defined(__IUnknown_INTERFACE_DEFINED__) */ - -KSDDKAPI VOID NTAPI KsPinSetPinClockTime(PKSPIN Pin, LONGLONG Time); - -KSDDKAPI NTSTATUS NTAPI KsPinSubmitFrame(PKSPIN Pin, PVOID Data, ULONG Size, PKSSTREAM_HEADER StreamHeader, PVOID Context); - -KSDDKAPI NTSTATUS NTAPI KsPinSubmitFrameMdl(PKSPIN Pin, PMDL Mdl, PKSSTREAM_HEADER StreamHeader, PVOID Context); - -KSDDKAPI void NTAPI KsPinRegisterFrameReturnCallback(PKSPIN Pin, PFNKSPINFRAMERETURN FrameReturn); - -KSDDKAPI void NTAPI KsPinRegisterIrpCompletionCallback(PKSPIN Pin, PFNKSPINIRPCOMPLETION IrpCompletion); - -KSDDKAPI void NTAPI KsPinRegisterHandshakeCallback(PKSPIN Pin, PFNKSPINHANDSHAKE Handshake); - -KSDDKAPI void NTAPI KsFilterRegisterPowerCallbacks(PKSFILTER Filter, PFNKSFILTERPOWER Sleep, PFNKSFILTERPOWER Wake); - -KSDDKAPI void NTAPI KsPinRegisterPowerCallbacks(PKSPIN Pin, PFNKSPINPOWER Sleep, PFNKSPINPOWER Wake); - - # if defined(_UNKNOWN_H_) || defined(__IUnknown_INTERFACE_DEFINED__) -KSDDKAPI PUNKNOWN NTAPI KsRegisterAggregatedClientUnknown(PVOID Object, PUNKNOWN ClientUnknown); - -KSDDKAPI PUNKNOWN NTAPI KsGetOuterUnknown(PVOID Object); - -PUNKNOWN __forceinline KsDeviceRegisterAggregatedClientUnknown(PKSDEVICE Device, PUNKNOWN ClientUnknown) -{ - return KsRegisterAggregatedClientUnknown((PVOID)Device, ClientUnknown); -} - -PUNKNOWN __forceinline KsDeviceGetOuterUnknown(PKSDEVICE Device) -{ - return KsGetOuterUnknown((PVOID)Device); -} - -PUNKNOWN __forceinline KsFilterFactoryRegisterAggregatedClientUnknown(PKSFILTERFACTORY FilterFactory, PUNKNOWN ClientUnknown) -{ - return KsRegisterAggregatedClientUnknown((PVOID)FilterFactory, ClientUnknown); -} - -PUNKNOWN __forceinline KsFilterFactoryGetOuterUnknown(PKSFILTERFACTORY FilterFactory) -{ - return KsGetOuterUnknown((PVOID)FilterFactory); -} - -PUNKNOWN __forceinline KsFilterRegisterAggregatedClientUnknown(PKSFILTER Filter, PUNKNOWN ClientUnknown) -{ - return KsRegisterAggregatedClientUnknown((PVOID)Filter, ClientUnknown); -} - -PUNKNOWN __forceinline KsFilterGetOuterUnknown(PKSFILTER Filter) -{ - return KsGetOuterUnknown((PVOID)Filter); -} - -PUNKNOWN __forceinline KsPinRegisterAggregatedClientUnknown(PKSPIN Pin, PUNKNOWN ClientUnknown) -{ - return KsRegisterAggregatedClientUnknown((PVOID)Pin, ClientUnknown); -} - -PUNKNOWN __forceinline KsPinGetOuterUnknown(PKSPIN Pin) -{ - return KsGetOuterUnknown((PVOID)Pin); -} - - # endif /* defined(_UNKNOWN_H_) || defined(__IUnknown_INTERFACE_DEFINED__) */ - -#else /* _NTDDK_ */ - - # ifndef KS_NO_CREATE_FUNCTIONS -KSDDKAPI DWORD WINAPI KsCreateAllocator(HANDLE ConnectionHandle, PKSALLOCATOR_FRAMING AllocatorFraming, PHANDLE AllocatorHandle); -KSDDKAPI DWORD NTAPI KsCreateClock(HANDLE ConnectionHandle, PKSCLOCK_CREATE ClockCreate, PHANDLE ClockHandle); -KSDDKAPI DWORD WINAPI KsCreatePin(HANDLE FilterHandle, PKSPIN_CONNECT Connect, ACCESS_MASK DesiredAccess, PHANDLE ConnectionHandle); -KSDDKAPI DWORD WINAPI KsCreateTopologyNode(HANDLE ParentHandle, PKSNODE_CREATE NodeCreate, ACCESS_MASK DesiredAccess, PHANDLE NodeHandle); - # endif - -#endif /* _NTDDK_ */ - -#ifdef __cplusplus -} -#endif - -#define DENY_USERMODE_ACCESS(pIrp, CompleteRequest) \ - if(pIrp->RequestorMode != KernelMode){ \ - pIrp->IoStatus.Information = 0; \ - pIrp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST; \ - if(CompleteRequest){ \ - IoCompleteRequest(pIrp, IO_NO_INCREMENT); } \ - return STATUS_INVALID_DEVICE_REQUEST; \ - } - -#endif /* _KS_ */ - diff --git a/include/ksmedia.h b/include/ksmedia.h deleted file mode 100644 index a01823b9..00000000 --- a/include/ksmedia.h +++ /dev/null @@ -1,4824 +0,0 @@ -/** - * This file has no copyright assigned and is placed in the Public Domain. - * This file is part of the w64 mingw-runtime package. - */ -#if !defined(_KS_) - # warning ks.h must be included before ksmedia.h - # include "ks.h" -#endif - -#if __GNUC__ >= 3 - # pragma GCC system_header -#endif - -#if !defined(_KSMEDIA_) - # define _KSMEDIA_ - -typedef struct -{ - KSPROPERTY Property; - KSMULTIPLE_ITEM MultipleItem; -}KSMULTIPLE_DATA_PROP, * PKSMULTIPLE_DATA_PROP; - - # define STATIC_KSMEDIUMSETID_MidiBus \ - 0x05908040L, 0x3246, 0x11D0, 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00 -DEFINE_GUIDSTRUCT("05908040-3246-11D0-A5D6-28DB04C10000", KSMEDIUMSETID_MidiBus); - # define KSMEDIUMSETID_MidiBus DEFINE_GUIDNAMED(KSMEDIUMSETID_MidiBus) - - # define STATIC_KSMEDIUMSETID_VPBus \ - 0xA18C15ECL, 0xCE43, 0x11D0, 0xAB, 0xE7, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96 -DEFINE_GUIDSTRUCT("A18C15EC-CE43-11D0-ABE7-00A0C9223196", KSMEDIUMSETID_VPBus); - # define KSMEDIUMSETID_VPBus DEFINE_GUIDNAMED(KSMEDIUMSETID_VPBus) - - # define STATIC_KSINTERFACESETID_Media \ - 0x3A13EB40L, 0x30A7, 0x11D0, 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00 -DEFINE_GUIDSTRUCT("3A13EB40-30A7-11D0-A5D6-28DB04C10000", KSINTERFACESETID_Media); - # define KSINTERFACESETID_Media DEFINE_GUIDNAMED(KSINTERFACESETID_Media) - -typedef enum -{ - KSINTERFACE_MEDIA_MUSIC, - KSINTERFACE_MEDIA_WAVE_BUFFERED, - KSINTERFACE_MEDIA_WAVE_QUEUED -}KSINTERFACE_MEDIA; - - # ifndef INIT_USBAUDIO_MID - # define INIT_USBAUDIO_MID(guid, id) \ - { \ - (guid)->Data1 = 0x4e1cecd2 + (USHORT)(id); \ - (guid)->Data2 = 0x1679; \ - (guid)->Data3 = 0x463b; \ - (guid)->Data4[0] = 0xa7; \ - (guid)->Data4[1] = 0x2f; \ - (guid)->Data4[2] = 0xa5; \ - (guid)->Data4[3] = 0xbf; \ - (guid)->Data4[4] = 0x64; \ - (guid)->Data4[5] = 0xc8; \ - (guid)->Data4[6] = 0x6e; \ - (guid)->Data4[7] = 0xba; \ - } - # define EXTRACT_USBAUDIO_MID(guid) \ - (USHORT)((guid)->Data1 - 0x4e1cecd2) - # define DEFINE_USBAUDIO_MID_GUID(id) \ - 0x4e1cecd2 + (USHORT)(id), 0x1679, 0x463b, 0xa7, 0x2f, 0xa5, 0xbf, 0x64, 0xc8, 0x6e, 0xba - # define IS_COMPATIBLE_USBAUDIO_MID(guid) \ - (((guid)->Data1 >= 0x4e1cecd2) && \ - ((guid)->Data1 < 0x4e1cecd2 + 0xffff) && \ - ((guid)->Data2 == 0x1679) && \ - ((guid)->Data3 == 0x463b) && \ - ((guid)->Data4[0] == 0xa7) && \ - ((guid)->Data4[1] == 0x2f) && \ - ((guid)->Data4[2] == 0xa5) && \ - ((guid)->Data4[3] == 0xbf) && \ - ((guid)->Data4[4] == 0x64) && \ - ((guid)->Data4[5] == 0xc8) && \ - ((guid)->Data4[6] == 0x6e) && \ - ((guid)->Data4[7] == 0xba)) - # endif /* INIT_USBAUDIO_MID */ - - # ifndef INIT_USBAUDIO_PID - # define INIT_USBAUDIO_PID(guid, id) \ - { \ - (guid)->Data1 = 0xabcc5a5e + (USHORT)(id); \ - (guid)->Data2 = 0xc263; \ - (guid)->Data3 = 0x463b; \ - (guid)->Data4[0] = 0xa7; \ - (guid)->Data4[1] = 0x2f; \ - (guid)->Data4[2] = 0xa5; \ - (guid)->Data4[3] = 0xbf; \ - (guid)->Data4[4] = 0x64; \ - (guid)->Data4[5] = 0xc8; \ - (guid)->Data4[6] = 0x6e; \ - (guid)->Data4[7] = 0xba; \ - } - # define EXTRACT_USBAUDIO_PID(guid) \ - (USHORT)((guid)->Data1 - 0xabcc5a5e) - # define DEFINE_USBAUDIO_PID_GUID(id) \ - 0xabcc5a5e + (USHORT)(id), 0xc263, 0x463b, 0xa7, 0x2f, 0xa5, 0xbf, 0x64, 0xc8, 0x6e, 0xba - # define IS_COMPATIBLE_USBAUDIO_PID(guid) \ - (((guid)->Data1 >= 0xabcc5a5e) && \ - ((guid)->Data1 < 0xabcc5a5e + 0xffff) && \ - ((guid)->Data2 == 0xc263) && \ - ((guid)->Data3 == 0x463b) && \ - ((guid)->Data4[0] == 0xa7) && \ - ((guid)->Data4[1] == 0x2f) && \ - ((guid)->Data4[2] == 0xa5) && \ - ((guid)->Data4[3] == 0xbf) && \ - ((guid)->Data4[4] == 0x64) && \ - ((guid)->Data4[5] == 0xc8) && \ - ((guid)->Data4[6] == 0x6e) && \ - ((guid)->Data4[7] == 0xba)) - # endif /* INIT_USBAUDIO_PID */ - - # ifndef INIT_USBAUDIO_PRODUCT_NAME - # define INIT_USBAUDIO_PRODUCT_NAME(guid, vid, pid, strIndex) \ - { \ - (guid)->Data1 = 0XFC575048 + (USHORT)(vid); \ - (guid)->Data2 = 0x2E08 + (USHORT)(pid); \ - (guid)->Data3 = 0x463B + (USHORT)(strIndex); \ - (guid)->Data4[0] = 0xA7; \ - (guid)->Data4[1] = 0x2F; \ - (guid)->Data4[2] = 0xA5; \ - (guid)->Data4[3] = 0xBF; \ - (guid)->Data4[4] = 0x64; \ - (guid)->Data4[5] = 0xC8; \ - (guid)->Data4[6] = 0x6E; \ - (guid)->Data4[7] = 0xBA; \ - } - # define DEFINE_USBAUDIO_PRODUCT_NAME(vid, pid, strIndex) \ - 0xFC575048 + (USHORT)(vid), 0x2E08 + (USHORT)(pid), 0x463B + (USHORT)(strIndex), 0xA7, 0x2F, 0xA5, 0xBF, 0x64, 0xC8, 0x6E, 0xBA - # endif /* INIT_USBAUDIO_PRODUCT_NAME */ - - # define STATIC_KSCOMPONENTID_USBAUDIO \ - 0x8F1275F0, 0x26E9, 0x4264, 0xBA, 0x4D, 0x39, 0xFF, 0xF0, 0x1D, 0x94, 0xAA -DEFINE_GUIDSTRUCT("8F1275F0-26E9-4264-BA4D-39FFF01D94AA", KSCOMPONENTID_USBAUDIO); - # define KSCOMPONENTID_USBAUDIO DEFINE_GUIDNAMED(KSCOMPONENTID_USBAUDIO) - - # define INIT_USB_TERMINAL(guid, id) \ - { \ - (guid)->Data1 = 0xDFF219E0 + (USHORT)(id); \ - (guid)->Data2 = 0xF70F; \ - (guid)->Data3 = 0x11D0; \ - (guid)->Data4[0] = 0xb9; \ - (guid)->Data4[1] = 0x17; \ - (guid)->Data4[2] = 0x00; \ - (guid)->Data4[3] = 0xa0; \ - (guid)->Data4[4] = 0xc9; \ - (guid)->Data4[5] = 0x22; \ - (guid)->Data4[6] = 0x31; \ - (guid)->Data4[7] = 0x96; \ - } - # define EXTRACT_USB_TERMINAL(guid) \ - (USHORT)((guid)->Data1 - 0xDFF219E0) - # define DEFINE_USB_TERMINAL_GUID(id) \ - 0xDFF219E0 + (USHORT)(id), 0xF70F, 0x11D0, 0xB9, 0x17, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96 - - # define STATIC_KSNODETYPE_MICROPHONE \ - DEFINE_USB_TERMINAL_GUID(0x0201) -DEFINE_GUIDSTRUCT("DFF21BE1-F70F-11D0-B917-00A0C9223196", KSNODETYPE_MICROPHONE); - # define KSNODETYPE_MICROPHONE DEFINE_GUIDNAMED(KSNODETYPE_MICROPHONE) - - # define STATIC_KSNODETYPE_DESKTOP_MICROPHONE \ - DEFINE_USB_TERMINAL_GUID(0x0202) -DEFINE_GUIDSTRUCT("DFF21BE2-F70F-11D0-B917-00A0C9223196", KSNODETYPE_DESKTOP_MICROPHONE); - # define KSNODETYPE_DESKTOP_MICROPHONE DEFINE_GUIDNAMED(KSNODETYPE_DESKTOP_MICROPHONE) - - # define STATIC_KSNODETYPE_PERSONAL_MICROPHONE \ - DEFINE_USB_TERMINAL_GUID(0x0203) -DEFINE_GUIDSTRUCT("DFF21BE3-F70F-11D0-B917-00A0C9223196", KSNODETYPE_PERSONAL_MICROPHONE); - # define KSNODETYPE_PERSONAL_MICROPHONE DEFINE_GUIDNAMED(KSNODETYPE_PERSONAL_MICROPHONE) - - # define STATIC_KSNODETYPE_OMNI_DIRECTIONAL_MICROPHONE \ - DEFINE_USB_TERMINAL_GUID(0x0204) -DEFINE_GUIDSTRUCT("DFF21BE4-F70F-11D0-B917-00A0C9223196", KSNODETYPE_OMNI_DIRECTIONAL_MICROPHONE); - # define KSNODETYPE_OMNI_DIRECTIONAL_MICROPHONE DEFINE_GUIDNAMED(KSNODETYPE_OMNI_DIRECTIONAL_MICROPHONE) - - # define STATIC_KSNODETYPE_MICROPHONE_ARRAY \ - DEFINE_USB_TERMINAL_GUID(0x0205) -DEFINE_GUIDSTRUCT("DFF21BE5-F70F-11D0-B917-00A0C9223196", KSNODETYPE_MICROPHONE_ARRAY); - # define KSNODETYPE_MICROPHONE_ARRAY DEFINE_GUIDNAMED(KSNODETYPE_MICROPHONE_ARRAY) - - # define STATIC_KSNODETYPE_PROCESSING_MICROPHONE_ARRAY \ - DEFINE_USB_TERMINAL_GUID(0x0206) -DEFINE_GUIDSTRUCT("DFF21BE6-F70F-11D0-B917-00A0C9223196", KSNODETYPE_PROCESSING_MICROPHONE_ARRAY); - # define KSNODETYPE_PROCESSING_MICROPHONE_ARRAY DEFINE_GUIDNAMED(KSNODETYPE_PROCESSING_MICROPHONE_ARRAY) - - # define STATIC_KSCATEGORY_MICROPHONE_ARRAY_PROCESSOR \ - 0x830a44f2, 0xa32d, 0x476b, 0xbe, 0x97, 0x42, 0x84, 0x56, 0x73, 0xb3, 0x5a -DEFINE_GUIDSTRUCT("830a44f2-a32d-476b-be97-42845673b35a", KSCATEGORY_MICROPHONE_ARRAY_PROCESSOR); - # define KSCATEGORY_MICROPHONE_ARRAY_PROCESSOR DEFINE_GUIDNAMED(KSCATEGORY_MICROPHONE_ARRAY_PROCESSOR) - - # define STATIC_KSNODETYPE_SPEAKER \ - DEFINE_USB_TERMINAL_GUID(0x0301) -DEFINE_GUIDSTRUCT("DFF21CE1-F70F-11D0-B917-00A0C9223196", KSNODETYPE_SPEAKER); - # define KSNODETYPE_SPEAKER DEFINE_GUIDNAMED(KSNODETYPE_SPEAKER) - - # define STATIC_KSNODETYPE_HEADPHONES \ - DEFINE_USB_TERMINAL_GUID(0x0302) -DEFINE_GUIDSTRUCT("DFF21CE2-F70F-11D0-B917-00A0C9223196", KSNODETYPE_HEADPHONES); - # define KSNODETYPE_HEADPHONES DEFINE_GUIDNAMED(KSNODETYPE_HEADPHONES) - - # define STATIC_KSNODETYPE_HEAD_MOUNTED_DISPLAY_AUDIO \ - DEFINE_USB_TERMINAL_GUID(0x0303) -DEFINE_GUIDSTRUCT("DFF21CE3-F70F-11D0-B917-00A0C9223196", KSNODETYPE_HEAD_MOUNTED_DISPLAY_AUDIO); - # define KSNODETYPE_HEAD_MOUNTED_DISPLAY_AUDIO DEFINE_GUIDNAMED(KSNODETYPE_HEAD_MOUNTED_DISPLAY_AUDIO) - - # define STATIC_KSNODETYPE_DESKTOP_SPEAKER \ - DEFINE_USB_TERMINAL_GUID(0x0304) -DEFINE_GUIDSTRUCT("DFF21CE4-F70F-11D0-B917-00A0C9223196", KSNODETYPE_DESKTOP_SPEAKER); - # define KSNODETYPE_DESKTOP_SPEAKER DEFINE_GUIDNAMED(KSNODETYPE_DESKTOP_SPEAKER) - - # define STATIC_KSNODETYPE_ROOM_SPEAKER \ - DEFINE_USB_TERMINAL_GUID(0x0305) -DEFINE_GUIDSTRUCT("DFF21CE5-F70F-11D0-B917-00A0C9223196", KSNODETYPE_ROOM_SPEAKER); - # define KSNODETYPE_ROOM_SPEAKER DEFINE_GUIDNAMED(KSNODETYPE_ROOM_SPEAKER) - - # define STATIC_KSNODETYPE_COMMUNICATION_SPEAKER \ - DEFINE_USB_TERMINAL_GUID(0x0306) -DEFINE_GUIDSTRUCT("DFF21CE6-F70F-11D0-B917-00A0C9223196", KSNODETYPE_COMMUNICATION_SPEAKER); - # define KSNODETYPE_COMMUNICATION_SPEAKER DEFINE_GUIDNAMED(KSNODETYPE_COMMUNICATION_SPEAKER) - - # define STATIC_KSNODETYPE_LOW_FREQUENCY_EFFECTS_SPEAKER \ - DEFINE_USB_TERMINAL_GUID(0x0307) -DEFINE_GUIDSTRUCT("DFF21CE7-F70F-11D0-B917-00A0C9223196", KSNODETYPE_LOW_FREQUENCY_EFFECTS_SPEAKER); - # define KSNODETYPE_LOW_FREQUENCY_EFFECTS_SPEAKER DEFINE_GUIDNAMED(KSNODETYPE_LOW_FREQUENCY_EFFECTS_SPEAKER) - - # define STATIC_KSNODETYPE_HANDSET \ - DEFINE_USB_TERMINAL_GUID(0x0401) -DEFINE_GUIDSTRUCT("DFF21DE1-F70F-11D0-B917-00A0C9223196", KSNODETYPE_HANDSET); - # define KSNODETYPE_HANDSET DEFINE_GUIDNAMED(KSNODETYPE_HANDSET) - - # define STATIC_KSNODETYPE_HEADSET \ - DEFINE_USB_TERMINAL_GUID(0x0402) -DEFINE_GUIDSTRUCT("DFF21DE2-F70F-11D0-B917-00A0C9223196", KSNODETYPE_HEADSET); - # define KSNODETYPE_HEADSET DEFINE_GUIDNAMED(KSNODETYPE_HEADSET) - - # define STATIC_KSNODETYPE_SPEAKERPHONE_NO_ECHO_REDUCTION \ - DEFINE_USB_TERMINAL_GUID(0x0403) -DEFINE_GUIDSTRUCT("DFF21DE3-F70F-11D0-B917-00A0C9223196", KSNODETYPE_SPEAKERPHONE_NO_ECHO_REDUCTION); - # define KSNODETYPE_SPEAKERPHONE_NO_ECHO_REDUCTION DEFINE_GUIDNAMED(KSNODETYPE_SPEAKERPHONE_NO_ECHO_REDUCTION) - - # define STATIC_KSNODETYPE_ECHO_SUPPRESSING_SPEAKERPHONE \ - DEFINE_USB_TERMINAL_GUID(0x0404) -DEFINE_GUIDSTRUCT("DFF21DE4-F70F-11D0-B917-00A0C9223196", KSNODETYPE_ECHO_SUPPRESSING_SPEAKERPHONE); - # define KSNODETYPE_ECHO_SUPPRESSING_SPEAKERPHONE DEFINE_GUIDNAMED(KSNODETYPE_ECHO_SUPPRESSING_SPEAKERPHONE) - - # define STATIC_KSNODETYPE_ECHO_CANCELING_SPEAKERPHONE \ - DEFINE_USB_TERMINAL_GUID(0x0405) -DEFINE_GUIDSTRUCT("DFF21DE5-F70F-11D0-B917-00A0C9223196", KSNODETYPE_ECHO_CANCELING_SPEAKERPHONE); - # define KSNODETYPE_ECHO_CANCELING_SPEAKERPHONE DEFINE_GUIDNAMED(KSNODETYPE_ECHO_CANCELING_SPEAKERPHONE) - - # define STATIC_KSNODETYPE_PHONE_LINE \ - DEFINE_USB_TERMINAL_GUID(0x0501) -DEFINE_GUIDSTRUCT("DFF21EE1-F70F-11D0-B917-00A0C9223196", KSNODETYPE_PHONE_LINE); - # define KSNODETYPE_PHONE_LINE DEFINE_GUIDNAMED(KSNODETYPE_PHONE_LINE) - - # define STATIC_KSNODETYPE_TELEPHONE \ - DEFINE_USB_TERMINAL_GUID(0x0502) -DEFINE_GUIDSTRUCT("DFF21EE2-F70F-11D0-B917-00A0C9223196", KSNODETYPE_TELEPHONE); - # define KSNODETYPE_TELEPHONE DEFINE_GUIDNAMED(KSNODETYPE_TELEPHONE) - - # define STATIC_KSNODETYPE_DOWN_LINE_PHONE \ - DEFINE_USB_TERMINAL_GUID(0x0503) -DEFINE_GUIDSTRUCT("DFF21EE3-F70F-11D0-B917-00A0C9223196", KSNODETYPE_DOWN_LINE_PHONE); - # define KSNODETYPE_DOWN_LINE_PHONE DEFINE_GUIDNAMED(KSNODETYPE_DOWN_LINE_PHONE) - - # define STATIC_KSNODETYPE_ANALOG_CONNECTOR \ - DEFINE_USB_TERMINAL_GUID(0x601) -DEFINE_GUIDSTRUCT("DFF21FE1-F70F-11D0-B917-00A0C9223196", KSNODETYPE_ANALOG_CONNECTOR); - # define KSNODETYPE_ANALOG_CONNECTOR DEFINE_GUIDNAMED(KSNODETYPE_ANALOG_CONNECTOR) - - # define STATIC_KSNODETYPE_DIGITAL_AUDIO_INTERFACE \ - DEFINE_USB_TERMINAL_GUID(0x0602) -DEFINE_GUIDSTRUCT("DFF21FE2-F70F-11D0-B917-00A0C9223196", KSNODETYPE_DIGITAL_AUDIO_INTERFACE); - # define KSNODETYPE_DIGITAL_AUDIO_INTERFACE DEFINE_GUIDNAMED(KSNODETYPE_DIGITAL_AUDIO_INTERFACE) - - # define STATIC_KSNODETYPE_LINE_CONNECTOR \ - DEFINE_USB_TERMINAL_GUID(0x0603) -DEFINE_GUIDSTRUCT("DFF21FE3-F70F-11D0-B917-00A0C9223196", KSNODETYPE_LINE_CONNECTOR); - # define KSNODETYPE_LINE_CONNECTOR DEFINE_GUIDNAMED(KSNODETYPE_LINE_CONNECTOR) - - # define STATIC_KSNODETYPE_LEGACY_AUDIO_CONNECTOR \ - DEFINE_USB_TERMINAL_GUID(0x0604) -DEFINE_GUIDSTRUCT("DFF21FE4-F70F-11D0-B917-00A0C9223196", KSNODETYPE_LEGACY_AUDIO_CONNECTOR); - # define KSNODETYPE_LEGACY_AUDIO_CONNECTOR DEFINE_GUIDNAMED(KSNODETYPE_LEGACY_AUDIO_CONNECTOR) - - # define STATIC_KSNODETYPE_SPDIF_INTERFACE \ - DEFINE_USB_TERMINAL_GUID(0x0605) -DEFINE_GUIDSTRUCT("DFF21FE5-F70F-11D0-B917-00A0C9223196", KSNODETYPE_SPDIF_INTERFACE); - # define KSNODETYPE_SPDIF_INTERFACE DEFINE_GUIDNAMED(KSNODETYPE_SPDIF_INTERFACE) - - # define STATIC_KSNODETYPE_1394_DA_STREAM \ - DEFINE_USB_TERMINAL_GUID(0x0606) -DEFINE_GUIDSTRUCT("DFF21FE6-F70F-11D0-B917-00A0C9223196", KSNODETYPE_1394_DA_STREAM); - # define KSNODETYPE_1394_DA_STREAM DEFINE_GUIDNAMED(KSNODETYPE_1394_DA_STREAM) - - # define STATIC_KSNODETYPE_1394_DV_STREAM_SOUNDTRACK \ - DEFINE_USB_TERMINAL_GUID(0x0607) -DEFINE_GUIDSTRUCT("DFF21FE7-F70F-11D0-B917-00A0C9223196", KSNODETYPE_1394_DV_STREAM_SOUNDTRACK); - # define KSNODETYPE_1394_DV_STREAM_SOUNDTRACK DEFINE_GUIDNAMED(KSNODETYPE_1394_DV_STREAM_SOUNDTRACK) - - # define STATIC_KSNODETYPE_LEVEL_CALIBRATION_NOISE_SOURCE \ - DEFINE_USB_TERMINAL_GUID(0x0701) -DEFINE_GUIDSTRUCT("DFF220E1-F70F-11D0-B917-00A0C9223196", KSNODETYPE_LEVEL_CALIBRATION_NOISE_SOURCE); - # define KSNODETYPE_LEVEL_CALIBRATION_NOISE_SOURCE DEFINE_GUIDNAMED(KSNODETYPE_LEVEL_CALIBRATION_NOISE_SOURCE) - - # define STATIC_KSNODETYPE_EQUALIZATION_NOISE \ - DEFINE_USB_TERMINAL_GUID(0x0702) -DEFINE_GUIDSTRUCT("DFF220E2-F70F-11D0-B917-00A0C9223196", KSNODETYPE_EQUALIZATION_NOISE); - # define KSNODETYPE_EQUALIZATION_NOISE DEFINE_GUIDNAMED(KSNODETYPE_EQUALIZATION_NOISE) - - # define STATIC_KSNODETYPE_CD_PLAYER \ - DEFINE_USB_TERMINAL_GUID(0x0703) -DEFINE_GUIDSTRUCT("DFF220E3-F70F-11D0-B917-00A0C9223196", KSNODETYPE_CD_PLAYER); - # define KSNODETYPE_CD_PLAYER DEFINE_GUIDNAMED(KSNODETYPE_CD_PLAYER) - - # define STATIC_KSNODETYPE_DAT_IO_DIGITAL_AUDIO_TAPE \ - DEFINE_USB_TERMINAL_GUID(0x0704) -DEFINE_GUIDSTRUCT("DFF220E4-F70F-11D0-B917-00A0C9223196", KSNODETYPE_DAT_IO_DIGITAL_AUDIO_TAPE); - # define KSNODETYPE_DAT_IO_DIGITAL_AUDIO_TAPE DEFINE_GUIDNAMED(KSNODETYPE_DAT_IO_DIGITAL_AUDIO_TAPE) - - # define STATIC_KSNODETYPE_DCC_IO_DIGITAL_COMPACT_CASSETTE \ - DEFINE_USB_TERMINAL_GUID(0x0705) -DEFINE_GUIDSTRUCT("DFF220E5-F70F-11D0-B917-00A0C9223196", KSNODETYPE_DCC_IO_DIGITAL_COMPACT_CASSETTE); - # define KSNODETYPE_DCC_IO_DIGITAL_COMPACT_CASSETTE DEFINE_GUIDNAMED(KSNODETYPE_DCC_IO_DIGITAL_COMPACT_CASSETTE) - - # define STATIC_KSNODETYPE_MINIDISK \ - DEFINE_USB_TERMINAL_GUID(0x0706) -DEFINE_GUIDSTRUCT("DFF220E6-F70F-11D0-B917-00A0C9223196", KSNODETYPE_MINIDISK); - # define KSNODETYPE_MINIDISK DEFINE_GUIDNAMED(KSNODETYPE_MINIDISK) - - # define STATIC_KSNODETYPE_ANALOG_TAPE \ - DEFINE_USB_TERMINAL_GUID(0x0707) -DEFINE_GUIDSTRUCT("DFF220E7-F70F-11D0-B917-00A0C9223196", KSNODETYPE_ANALOG_TAPE); - # define KSNODETYPE_ANALOG_TAPE DEFINE_GUIDNAMED(KSNODETYPE_ANALOG_TAPE) - - # define STATIC_KSNODETYPE_PHONOGRAPH \ - DEFINE_USB_TERMINAL_GUID(0x0708) -DEFINE_GUIDSTRUCT("DFF220E8-F70F-11D0-B917-00A0C9223196", KSNODETYPE_PHONOGRAPH); - # define KSNODETYPE_PHONOGRAPH DEFINE_GUIDNAMED(KSNODETYPE_PHONOGRAPH) - - # define STATIC_KSNODETYPE_VCR_AUDIO \ - DEFINE_USB_TERMINAL_GUID(0x0708) -DEFINE_GUIDSTRUCT("DFF220E9-F70F-11D0-B917-00A0C9223196", KSNODETYPE_VCR_AUDIO); - # define KSNODETYPE_VCR_AUDIO DEFINE_GUIDNAMED(KSNODETYPE_VCR_AUDIO) - - # define STATIC_KSNODETYPE_VIDEO_DISC_AUDIO \ - DEFINE_USB_TERMINAL_GUID(0x070A) -DEFINE_GUIDSTRUCT("DFF220EA-F70F-11D0-B917-00A0C9223196", KSNODETYPE_VIDEO_DISC_AUDIO); - # define KSNODETYPE_VIDEO_DISC_AUDIO DEFINE_GUIDNAMED(KSNODETYPE_VIDEO_DISC_AUDIO) - - # define STATIC_KSNODETYPE_DVD_AUDIO \ - DEFINE_USB_TERMINAL_GUID(0x070B) -DEFINE_GUIDSTRUCT("DFF220EB-F70F-11D0-B917-00A0C9223196", KSNODETYPE_DVD_AUDIO); - # define KSNODETYPE_DVD_AUDIO DEFINE_GUIDNAMED(KSNODETYPE_DVD_AUDIO) - - # define STATIC_KSNODETYPE_TV_TUNER_AUDIO \ - DEFINE_USB_TERMINAL_GUID(0x070C) -DEFINE_GUIDSTRUCT("DFF220EC-F70F-11D0-B917-00A0C9223196", KSNODETYPE_TV_TUNER_AUDIO); - # define KSNODETYPE_TV_TUNER_AUDIO DEFINE_GUIDNAMED(KSNODETYPE_TV_TUNER_AUDIO) - - # define STATIC_KSNODETYPE_SATELLITE_RECEIVER_AUDIO \ - DEFINE_USB_TERMINAL_GUID(0x070D) -DEFINE_GUIDSTRUCT("DFF220ED-F70F-11D0-B917-00A0C9223196", KSNODETYPE_SATELLITE_RECEIVER_AUDIO); - # define KSNODETYPE_SATELLITE_RECEIVER_AUDIO DEFINE_GUIDNAMED(KSNODETYPE_SATELLITE_RECEIVER_AUDIO) - - # define STATIC_KSNODETYPE_CABLE_TUNER_AUDIO \ - DEFINE_USB_TERMINAL_GUID(0x070E) -DEFINE_GUIDSTRUCT("DFF220EE-F70F-11D0-B917-00A0C9223196", KSNODETYPE_CABLE_TUNER_AUDIO); - # define KSNODETYPE_CABLE_TUNER_AUDIO DEFINE_GUIDNAMED(KSNODETYPE_CABLE_TUNER_AUDIO) - - # define STATIC_KSNODETYPE_DSS_AUDIO \ - DEFINE_USB_TERMINAL_GUID(0x070F) -DEFINE_GUIDSTRUCT("DFF220EF-F70F-11D0-B917-00A0C9223196", KSNODETYPE_DSS_AUDIO); - # define KSNODETYPE_DSS_AUDIO DEFINE_GUIDNAMED(KSNODETYPE_DSS_AUDIO) - - # define STATIC_KSNODETYPE_RADIO_RECEIVER \ - DEFINE_USB_TERMINAL_GUID(0x0710) -DEFINE_GUIDSTRUCT("DFF220F0-F70F-11D0-B917-00A0C9223196", KSNODETYPE_RADIO_RECEIVER); - # define KSNODETYPE_RADIO_RECEIVER DEFINE_GUIDNAMED(KSNODETYPE_RADIO_RECEIVER) - - # define STATIC_KSNODETYPE_RADIO_TRANSMITTER \ - DEFINE_USB_TERMINAL_GUID(0x0711) -DEFINE_GUIDSTRUCT("DFF220F1-F70F-11D0-B917-00A0C9223196", KSNODETYPE_RADIO_TRANSMITTER); - # define KSNODETYPE_RADIO_TRANSMITTER DEFINE_GUIDNAMED(KSNODETYPE_RADIO_TRANSMITTER) - - # define STATIC_KSNODETYPE_MULTITRACK_RECORDER \ - DEFINE_USB_TERMINAL_GUID(0x0712) -DEFINE_GUIDSTRUCT("DFF220F2-F70F-11D0-B917-00A0C9223196", KSNODETYPE_MULTITRACK_RECORDER); - # define KSNODETYPE_MULTITRACK_RECORDER DEFINE_GUIDNAMED(KSNODETYPE_MULTITRACK_RECORDER) - - # define STATIC_KSNODETYPE_SYNTHESIZER \ - DEFINE_USB_TERMINAL_GUID(0x0713) -DEFINE_GUIDSTRUCT("DFF220F3-F70F-11D0-B917-00A0C9223196", KSNODETYPE_SYNTHESIZER); - # define KSNODETYPE_SYNTHESIZER DEFINE_GUIDNAMED(KSNODETYPE_SYNTHESIZER) - - # define STATIC_KSNODETYPE_SWSYNTH \ - 0x423274A0L, 0x8B81, 0x11D1, 0xA0, 0x50, 0x00, 0x00, 0xF8, 0x00, 0x47, 0x88 -DEFINE_GUIDSTRUCT("423274A0-8B81-11D1-A050-0000F8004788", KSNODETYPE_SWSYNTH); - # define KSNODETYPE_SWSYNTH DEFINE_GUIDNAMED(KSNODETYPE_SWSYNTH) - - # define STATIC_KSNODETYPE_SWMIDI \ - 0xCB9BEFA0L, 0xA251, 0x11D1, 0xA0, 0x50, 0x00, 0x00, 0xF8, 0x00, 0x47, 0x88 -DEFINE_GUIDSTRUCT("CB9BEFA0-A251-11D1-A050-0000F8004788", KSNODETYPE_SWMIDI); - # define KSNODETYPE_SWMIDI DEFINE_GUIDNAMED(KSNODETYPE_SWMIDI) - - # define STATIC_KSNODETYPE_DRM_DESCRAMBLE \ - 0xFFBB6E3FL, 0xCCFE, 0x4D84, 0x90, 0xD9, 0x42, 0x14, 0x18, 0xB0, 0x3A, 0x8E -DEFINE_GUIDSTRUCT("FFBB6E3F-CCFE-4D84-90D9-421418B03A8E", KSNODETYPE_DRM_DESCRAMBLE); - # define KSNODETYPE_DRM_DESCRAMBLE DEFINE_GUIDNAMED(KSNODETYPE_DRM_DESCRAMBLE) - - # define STATIC_KSCATEGORY_AUDIO \ - 0x6994AD04L, 0x93EF, 0x11D0, { 0xA3, 0xCC, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96 } -DEFINE_GUIDSTRUCT("6994AD04-93EF-11D0-A3CC-00A0C9223196", KSCATEGORY_AUDIO); - # define KSCATEGORY_AUDIO DEFINE_GUIDNAMED(KSCATEGORY_AUDIO) - - # define STATIC_KSCATEGORY_VIDEO \ - 0x6994AD05L, 0x93EF, 0x11D0, 0xA3, 0xCC, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96 -DEFINE_GUIDSTRUCT("6994AD05-93EF-11D0-A3CC-00A0C9223196", KSCATEGORY_VIDEO); - # define KSCATEGORY_VIDEO DEFINE_GUIDNAMED(KSCATEGORY_VIDEO) - - # define STATIC_KSCATEGORY_TEXT \ - 0x6994AD06L, 0x93EF, 0x11D0, 0xA3, 0xCC, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96 -DEFINE_GUIDSTRUCT("6994AD06-93EF-11D0-A3CC-00A0C9223196", KSCATEGORY_TEXT); - # define KSCATEGORY_TEXT DEFINE_GUIDNAMED(KSCATEGORY_TEXT) - - # define STATIC_KSCATEGORY_NETWORK \ - 0x67C9CC3CL, 0x69C4, 0x11D2, 0x87, 0x59, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96 -DEFINE_GUIDSTRUCT("67C9CC3C-69C4-11D2-8759-00A0C9223196", KSCATEGORY_NETWORK); - # define KSCATEGORY_NETWORK DEFINE_GUIDNAMED(KSCATEGORY_NETWORK) - - # define STATIC_KSCATEGORY_TOPOLOGY \ - 0xDDA54A40L, 0x1E4C, 0x11D1, 0xA0, 0x50, 0x40, 0x57, 0x05, 0xC1, 0x00, 0x00 -DEFINE_GUIDSTRUCT("DDA54A40-1E4C-11D1-A050-405705C10000", KSCATEGORY_TOPOLOGY); - # define KSCATEGORY_TOPOLOGY DEFINE_GUIDNAMED(KSCATEGORY_TOPOLOGY) - - # define STATIC_KSCATEGORY_VIRTUAL \ - 0x3503EAC4L, 0x1F26, 0x11D1, 0x8A, 0xB0, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96 -DEFINE_GUIDSTRUCT("3503EAC4-1F26-11D1-8AB0-00A0C9223196", KSCATEGORY_VIRTUAL); - # define KSCATEGORY_VIRTUAL DEFINE_GUIDNAMED(KSCATEGORY_VIRTUAL) - - # define STATIC_KSCATEGORY_ACOUSTIC_ECHO_CANCEL \ - 0xBF963D80L, 0xC559, 0x11D0, 0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1 -DEFINE_GUIDSTRUCT("BF963D80-C559-11D0-8A2B-00A0C9255AC1", KSCATEGORY_ACOUSTIC_ECHO_CANCEL); - # define KSCATEGORY_ACOUSTIC_ECHO_CANCEL DEFINE_GUIDNAMED(KSCATEGORY_ACOUSTIC_ECHO_CANCEL) - - # define STATIC_KSCATEGORY_SYSAUDIO \ - 0xA7C7A5B1L, 0x5AF3, 0x11D1, 0x9C, 0xED, 0x00, 0xA0, 0x24, 0xBF, 0x04, 0x07 -DEFINE_GUIDSTRUCT("A7C7A5B1-5AF3-11D1-9CED-00A024BF0407", KSCATEGORY_SYSAUDIO); - # define KSCATEGORY_SYSAUDIO DEFINE_GUIDNAMED(KSCATEGORY_SYSAUDIO) - - # define STATIC_KSCATEGORY_WDMAUD \ - 0x3E227E76L, 0x690D, 0x11D2, 0x81, 0x61, 0x00, 0x00, 0xF8, 0x77, 0x5B, 0xF1 -DEFINE_GUIDSTRUCT("3E227E76-690D-11D2-8161-0000F8775BF1", KSCATEGORY_WDMAUD); - # define KSCATEGORY_WDMAUD DEFINE_GUIDNAMED(KSCATEGORY_WDMAUD) - - # define STATIC_KSCATEGORY_AUDIO_GFX \ - 0x9BAF9572L, 0x340C, 0x11D3, 0xAB, 0xDC, 0x00, 0xA0, 0xC9, 0x0A, 0xB1, 0x6F -DEFINE_GUIDSTRUCT("9BAF9572-340C-11D3-ABDC-00A0C90AB16F", KSCATEGORY_AUDIO_GFX); - # define KSCATEGORY_AUDIO_GFX DEFINE_GUIDNAMED(KSCATEGORY_AUDIO_GFX) - - # define STATIC_KSCATEGORY_AUDIO_SPLITTER \ - 0x9EA331FAL, 0xB91B, 0x45F8, 0x92, 0x85, 0xBD, 0x2B, 0xC7, 0x7A, 0xFC, 0xDE -DEFINE_GUIDSTRUCT("9EA331FA-B91B-45F8-9285-BD2BC77AFCDE", KSCATEGORY_AUDIO_SPLITTER); - # define KSCATEGORY_AUDIO_SPLITTER DEFINE_GUIDNAMED(KSCATEGORY_AUDIO_SPLITTER) - - # define STATIC_KSCATEGORY_SYNTHESIZER STATIC_KSNODETYPE_SYNTHESIZER - # define KSCATEGORY_SYNTHESIZER KSNODETYPE_SYNTHESIZER - - # define STATIC_KSCATEGORY_DRM_DESCRAMBLE STATIC_KSNODETYPE_DRM_DESCRAMBLE - # define KSCATEGORY_DRM_DESCRAMBLE KSNODETYPE_DRM_DESCRAMBLE - - # define STATIC_KSCATEGORY_AUDIO_DEVICE \ - 0xFBF6F530L, 0x07B9, 0x11D2, 0xA7, 0x1E, 0x00, 0x00, 0xF8, 0x00, 0x47, 0x88 -DEFINE_GUIDSTRUCT("FBF6F530-07B9-11D2-A71E-0000F8004788", KSCATEGORY_AUDIO_DEVICE); - # define KSCATEGORY_AUDIO_DEVICE DEFINE_GUIDNAMED(KSCATEGORY_AUDIO_DEVICE) - - # define STATIC_KSCATEGORY_PREFERRED_WAVEOUT_DEVICE \ - 0xD6C5066EL, 0x72C1, 0x11D2, 0x97, 0x55, 0x00, 0x00, 0xF8, 0x00, 0x47, 0x88 -DEFINE_GUIDSTRUCT("D6C5066E-72C1-11D2-9755-0000F8004788", KSCATEGORY_PREFERRED_WAVEOUT_DEVICE); - # define KSCATEGORY_PREFERRED_WAVEOUT_DEVICE DEFINE_GUIDNAMED(KSCATEGORY_PREFERRED_WAVEOUT_DEVICE) - - # define STATIC_KSCATEGORY_PREFERRED_WAVEIN_DEVICE \ - 0xD6C50671L, 0x72C1, 0x11D2, 0x97, 0x55, 0x00, 0x00, 0xF8, 0x00, 0x47, 0x88 -DEFINE_GUIDSTRUCT("D6C50671-72C1-11D2-9755-0000F8004788", KSCATEGORY_PREFERRED_WAVEIN_DEVICE); - # define KSCATEGORY_PREFERRED_WAVEIN_DEVICE DEFINE_GUIDNAMED(KSCATEGORY_PREFERRED_WAVEIN_DEVICE) - - # define STATIC_KSCATEGORY_PREFERRED_MIDIOUT_DEVICE \ - 0xD6C50674L, 0x72C1, 0x11D2, 0x97, 0x55, 0x00, 0x00, 0xF8, 0x00, 0x47, 0x88 -DEFINE_GUIDSTRUCT("D6C50674-72C1-11D2-9755-0000F8004788", KSCATEGORY_PREFERRED_MIDIOUT_DEVICE); - # define KSCATEGORY_PREFERRED_MIDIOUT_DEVICE DEFINE_GUIDNAMED(KSCATEGORY_PREFERRED_MIDIOUT_DEVICE) - - # define STATIC_KSCATEGORY_WDMAUD_USE_PIN_NAME \ - 0x47A4FA20L, 0xA251, 0x11D1, 0xA0, 0x50, 0x00, 0x00, 0xF8, 0x00, 0x47, 0x88 -DEFINE_GUIDSTRUCT("47A4FA20-A251-11D1-A050-0000F8004788", KSCATEGORY_WDMAUD_USE_PIN_NAME); - # define KSCATEGORY_WDMAUD_USE_PIN_NAME DEFINE_GUIDNAMED(KSCATEGORY_WDMAUD_USE_PIN_NAME) - - # define STATIC_KSCATEGORY_ESCALANTE_PLATFORM_DRIVER \ - 0x74f3aea8L, 0x9768, 0x11d1, 0x8e, 0x07, 0x00, 0xa0, 0xc9, 0x5e, 0xc2, 0x2e -DEFINE_GUIDSTRUCT("74f3aea8-9768-11d1-8e07-00a0c95ec22e", KSCATEGORY_ESCALANTE_PLATFORM_DRIVER); - # define KSCATEGORY_ESCALANTE_PLATFORM_DRIVER DEFINE_GUIDNAMED(KSCATEGORY_ESCALANTE_PLATFORM_DRIVER) - - # define STATIC_KSDATAFORMAT_TYPE_VIDEO \ - 0x73646976L, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 -DEFINE_GUIDSTRUCT("73646976-0000-0010-8000-00aa00389b71", KSDATAFORMAT_TYPE_VIDEO); - # define KSDATAFORMAT_TYPE_VIDEO DEFINE_GUIDNAMED(KSDATAFORMAT_TYPE_VIDEO) - - # define STATIC_KSDATAFORMAT_TYPE_AUDIO \ - 0x73647561L, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 -DEFINE_GUIDSTRUCT("73647561-0000-0010-8000-00aa00389b71", KSDATAFORMAT_TYPE_AUDIO); - # define KSDATAFORMAT_TYPE_AUDIO DEFINE_GUIDNAMED(KSDATAFORMAT_TYPE_AUDIO) - - # define STATIC_KSDATAFORMAT_TYPE_TEXT \ - 0x73747874L, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 -DEFINE_GUIDSTRUCT("73747874-0000-0010-8000-00aa00389b71", KSDATAFORMAT_TYPE_TEXT); - # define KSDATAFORMAT_TYPE_TEXT DEFINE_GUIDNAMED(KSDATAFORMAT_TYPE_TEXT) - - # if !defined(DEFINE_WAVEFORMATEX_GUID) - # define DEFINE_WAVEFORMATEX_GUID(x) \ - (USHORT)(x), 0x0000, 0x0010, { 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 } - # endif - - # define STATIC_KSDATAFORMAT_SUBTYPE_WAVEFORMATEX \ - 0x00000000L, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 -DEFINE_GUIDSTRUCT("00000000-0000-0010-8000-00aa00389b71", KSDATAFORMAT_SUBTYPE_WAVEFORMATEX); - # define KSDATAFORMAT_SUBTYPE_WAVEFORMATEX DEFINE_GUIDNAMED(KSDATAFORMAT_SUBTYPE_WAVEFORMATEX) - - # define INIT_WAVEFORMATEX_GUID(Guid, x) \ - { \ - *(Guid) = KSDATAFORMAT_SUBTYPE_WAVEFORMATEX; \ - (Guid)->Data1 = (USHORT)(x); \ - } - - # define EXTRACT_WAVEFORMATEX_ID(Guid) \ - (USHORT)((Guid)->Data1) - - # define IS_VALID_WAVEFORMATEX_GUID(Guid) \ - (!memcmp(((PUSHORT)&KSDATAFORMAT_SUBTYPE_WAVEFORMATEX) + 1, ((PUSHORT)(Guid)) + 1, sizeof(GUID) - sizeof(USHORT))) - - # ifndef INIT_MMREG_MID - # define INIT_MMREG_MID(guid, id) \ - { \ - (guid)->Data1 = 0xd5a47fa7 + (USHORT)(id); \ - (guid)->Data2 = 0x6d98; \ - (guid)->Data3 = 0x11d1; \ - (guid)->Data4[0] = 0xa2; \ - (guid)->Data4[1] = 0x1a; \ - (guid)->Data4[2] = 0x00; \ - (guid)->Data4[3] = 0xa0; \ - (guid)->Data4[4] = 0xc9; \ - (guid)->Data4[5] = 0x22; \ - (guid)->Data4[6] = 0x31; \ - (guid)->Data4[7] = 0x96; \ - } - # define EXTRACT_MMREG_MID(guid) \ - (USHORT)((guid)->Data1 - 0xd5a47fa7) - # define DEFINE_MMREG_MID_GUID(id) \ - 0xd5a47fa7 + (USHORT)(id), 0x6d98, 0x11d1, 0xa2, 0x1a, 0x00, 0xa0, 0xc9, 0x22, 0x31, 0x96 - - # define IS_COMPATIBLE_MMREG_MID(guid) \ - (((guid)->Data1 >= 0xd5a47fa7) && \ - ((guid)->Data1 < 0xd5a47fa7 + 0xffff) && \ - ((guid)->Data2 == 0x6d98) && \ - ((guid)->Data3 == 0x11d1) && \ - ((guid)->Data4[0] == 0xa2) && \ - ((guid)->Data4[1] == 0x1a) && \ - ((guid)->Data4[2] == 0x00) && \ - ((guid)->Data4[3] == 0xa0) && \ - ((guid)->Data4[4] == 0xc9) && \ - ((guid)->Data4[5] == 0x22) && \ - ((guid)->Data4[6] == 0x31) && \ - ((guid)->Data4[7] == 0x96)) - # endif /* INIT_MMREG_MID */ - - # ifndef INIT_MMREG_PID - # define INIT_MMREG_PID(guid, id) \ - { \ - (guid)->Data1 = 0xe36dc2ac + (USHORT)(id); \ - (guid)->Data2 = 0x6d9a; \ - (guid)->Data3 = 0x11d1; \ - (guid)->Data4[0] = 0xa2; \ - (guid)->Data4[1] = 0x1a; \ - (guid)->Data4[2] = 0x00; \ - (guid)->Data4[3] = 0xa0; \ - (guid)->Data4[4] = 0xc9; \ - (guid)->Data4[5] = 0x22; \ - (guid)->Data4[6] = 0x31; \ - (guid)->Data4[7] = 0x96; \ - } - # define EXTRACT_MMREG_PID(guid) \ - (USHORT)((guid)->Data1 - 0xe36dc2ac) - # define DEFINE_MMREG_PID_GUID(id) \ - 0xe36dc2ac + (USHORT)(id), 0x6d9a, 0x11d1, 0xa2, 0x1a, 0x00, 0xa0, 0xc9, 0x22, 0x31, 0x96 - - # define IS_COMPATIBLE_MMREG_PID(guid) \ - (((guid)->Data1 >= 0xe36dc2ac) && \ - ((guid)->Data1 < 0xe36dc2ac + 0xffff) && \ - ((guid)->Data2 == 0x6d9a) && \ - ((guid)->Data3 == 0x11d1) && \ - ((guid)->Data4[0] == 0xa2) && \ - ((guid)->Data4[1] == 0x1a) && \ - ((guid)->Data4[2] == 0x00) && \ - ((guid)->Data4[3] == 0xa0) && \ - ((guid)->Data4[4] == 0xc9) && \ - ((guid)->Data4[5] == 0x22) && \ - ((guid)->Data4[6] == 0x31) && \ - ((guid)->Data4[7] == 0x96)) - # endif /* INIT_MMREG_PID */ - - # define STATIC_KSDATAFORMAT_SUBTYPE_ANALOG \ - 0x6dba3190L, 0x67bd, 0x11cf, 0xa0, 0xf7, 0x00, 0x20, 0xaf, 0xd1, 0x56, 0xe4 -DEFINE_GUIDSTRUCT("6dba3190-67bd-11cf-a0f7-0020afd156e4", KSDATAFORMAT_SUBTYPE_ANALOG); - # define KSDATAFORMAT_SUBTYPE_ANALOG DEFINE_GUIDNAMED(KSDATAFORMAT_SUBTYPE_ANALOG) - - # define STATIC_KSDATAFORMAT_SUBTYPE_PCM \ - DEFINE_WAVEFORMATEX_GUID(WAVE_FORMAT_PCM) -DEFINE_GUIDSTRUCT("00000001-0000-0010-8000-00aa00389b71", KSDATAFORMAT_SUBTYPE_PCM); - # define KSDATAFORMAT_SUBTYPE_PCM DEFINE_GUIDNAMED(KSDATAFORMAT_SUBTYPE_PCM) - - # ifdef _INC_MMREG - # define STATIC_KSDATAFORMAT_SUBTYPE_IEEE_FLOAT \ - DEFINE_WAVEFORMATEX_GUID(WAVE_FORMAT_IEEE_FLOAT) -DEFINE_GUIDSTRUCT("00000003-0000-0010-8000-00aa00389b71", KSDATAFORMAT_SUBTYPE_IEEE_FLOAT); - # define KSDATAFORMAT_SUBTYPE_IEEE_FLOAT DEFINE_GUIDNAMED(KSDATAFORMAT_SUBTYPE_IEEE_FLOAT) - - # define STATIC_KSDATAFORMAT_SUBTYPE_DRM \ - DEFINE_WAVEFORMATEX_GUID(WAVE_FORMAT_DRM) -DEFINE_GUIDSTRUCT("00000009-0000-0010-8000-00aa00389b71", KSDATAFORMAT_SUBTYPE_DRM); - # define KSDATAFORMAT_SUBTYPE_DRM DEFINE_GUIDNAMED(KSDATAFORMAT_SUBTYPE_DRM) - - # define STATIC_KSDATAFORMAT_SUBTYPE_ALAW \ - DEFINE_WAVEFORMATEX_GUID(WAVE_FORMAT_ALAW) -DEFINE_GUIDSTRUCT("00000006-0000-0010-8000-00aa00389b71", KSDATAFORMAT_SUBTYPE_ALAW); - # define KSDATAFORMAT_SUBTYPE_ALAW DEFINE_GUIDNAMED(KSDATAFORMAT_SUBTYPE_ALAW) - - # define STATIC_KSDATAFORMAT_SUBTYPE_MULAW \ - DEFINE_WAVEFORMATEX_GUID(WAVE_FORMAT_MULAW) -DEFINE_GUIDSTRUCT("00000007-0000-0010-8000-00aa00389b71", KSDATAFORMAT_SUBTYPE_MULAW); - # define KSDATAFORMAT_SUBTYPE_MULAW DEFINE_GUIDNAMED(KSDATAFORMAT_SUBTYPE_MULAW) - - # define STATIC_KSDATAFORMAT_SUBTYPE_ADPCM \ - DEFINE_WAVEFORMATEX_GUID(WAVE_FORMAT_ADPCM) -DEFINE_GUIDSTRUCT("00000002-0000-0010-8000-00aa00389b71", KSDATAFORMAT_SUBTYPE_ADPCM); - # define KSDATAFORMAT_SUBTYPE_ADPCM DEFINE_GUIDNAMED(KSDATAFORMAT_SUBTYPE_ADPCM) - - # define STATIC_KSDATAFORMAT_SUBTYPE_MPEG \ - DEFINE_WAVEFORMATEX_GUID(WAVE_FORMAT_MPEG) -DEFINE_GUIDSTRUCT("00000050-0000-0010-8000-00aa00389b71", KSDATAFORMAT_SUBTYPE_MPEG); - # define KSDATAFORMAT_SUBTYPE_MPEG DEFINE_GUIDNAMED(KSDATAFORMAT_SUBTYPE_MPEG) - # endif /* _INC_MMREG */ - - # define STATIC_KSDATAFORMAT_SPECIFIER_VC_ID \ - 0xAD98D184L, 0xAAC3, 0x11D0, 0xA4, 0x1C, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96 -DEFINE_GUIDSTRUCT("AD98D184-AAC3-11D0-A41C-00A0C9223196", KSDATAFORMAT_SPECIFIER_VC_ID); - # define KSDATAFORMAT_SPECIFIER_VC_ID DEFINE_GUIDNAMED(KSDATAFORMAT_SPECIFIER_VC_ID) - - # define STATIC_KSDATAFORMAT_SPECIFIER_WAVEFORMATEX \ - 0x05589f81L, 0xc356, 0x11ce, 0xbf, 0x01, 0x00, 0xaa, 0x00, 0x55, 0x59, 0x5a -DEFINE_GUIDSTRUCT("05589f81-c356-11ce-bf01-00aa0055595a", KSDATAFORMAT_SPECIFIER_WAVEFORMATEX); - # define KSDATAFORMAT_SPECIFIER_WAVEFORMATEX DEFINE_GUIDNAMED(KSDATAFORMAT_SPECIFIER_WAVEFORMATEX) - - # define STATIC_KSDATAFORMAT_SPECIFIER_DSOUND \ - 0x518590a2L, 0xa184, 0x11d0, 0x85, 0x22, 0x00, 0xc0, 0x4f, 0xd9, 0xba, 0xf3 -DEFINE_GUIDSTRUCT("518590a2-a184-11d0-8522-00c04fd9baf3", KSDATAFORMAT_SPECIFIER_DSOUND); - # define KSDATAFORMAT_SPECIFIER_DSOUND DEFINE_GUIDNAMED(KSDATAFORMAT_SPECIFIER_DSOUND) - - # if defined(_INC_MMSYSTEM) || defined(_INC_MMREG) || 1 - # if !defined(PACK_PRAGMAS_NOT_SUPPORTED) - # include - # endif -typedef struct -{ - KSDATAFORMAT DataFormat; - WAVEFORMATEX WaveFormatEx; -}KSDATAFORMAT_WAVEFORMATEX, * PKSDATAFORMAT_WAVEFORMATEX; - - # ifndef _WAVEFORMATEXTENSIBLE_ - # define _WAVEFORMATEXTENSIBLE_ -typedef struct -{ - WAVEFORMATEX Format; - union - { - WORD wValidBitsPerSample; - WORD wSamplesPerBlock; - WORD wReserved; - }Samples; - DWORD dwChannelMask; - - GUID SubFormat; -}WAVEFORMATEXTENSIBLE, * PWAVEFORMATEXTENSIBLE; - # endif /* _WAVEFORMATEXTENSIBLE_ */ - - # if !defined(WAVE_FORMAT_EXTENSIBLE) - # define WAVE_FORMAT_EXTENSIBLE 0xFFFE - # endif - -typedef struct -{ - ULONG Flags; - ULONG Control; - WAVEFORMATEX WaveFormatEx; -}KSDSOUND_BUFFERDESC, * PKSDSOUND_BUFFERDESC; - -typedef struct -{ - KSDATAFORMAT DataFormat; - KSDSOUND_BUFFERDESC BufferDesc; -}KSDATAFORMAT_DSOUND, * PKSDATAFORMAT_DSOUND; - - # if !defined(PACK_PRAGMAS_NOT_SUPPORTED) - # include - # endif - # endif /* defined(_INC_MMSYSTEM) || defined(_INC_MMREG) */ - - # define KSDSOUND_BUFFER_PRIMARY 0x00000001 - # define KSDSOUND_BUFFER_STATIC 0x00000002 - # define KSDSOUND_BUFFER_LOCHARDWARE 0x00000004 - # define KSDSOUND_BUFFER_LOCSOFTWARE 0x00000008 - - # define KSDSOUND_BUFFER_CTRL_3D 0x00000001 - # define KSDSOUND_BUFFER_CTRL_FREQUENCY 0x00000002 - # define KSDSOUND_BUFFER_CTRL_PAN 0x00000004 - # define KSDSOUND_BUFFER_CTRL_VOLUME 0x00000008 - # define KSDSOUND_BUFFER_CTRL_POSITIONNOTIFY 0x00000010 - -typedef struct -{ - DWORDLONG PlayOffset; - DWORDLONG WriteOffset; -}KSAUDIO_POSITION, * PKSAUDIO_POSITION; - -typedef struct _DS3DVECTOR -{ - __MINGW_EXTENSION union - { - FLOAT x; - FLOAT dvX; - }; - __MINGW_EXTENSION union - { - FLOAT y; - FLOAT dvY; - }; - __MINGW_EXTENSION union - { - FLOAT z; - FLOAT dvZ; - }; -}DS3DVECTOR, * PDS3DVECTOR; - - # define STATIC_KSPROPSETID_DirectSound3DListener \ - 0x437b3414L, 0xd060, 0x11d0, 0x85, 0x83, 0x00, 0xc0, 0x4f, 0xd9, 0xba, 0xf3 -DEFINE_GUIDSTRUCT("437b3414-d060-11d0-8583-00c04fd9baf3", KSPROPSETID_DirectSound3DListener); - # define KSPROPSETID_DirectSound3DListener DEFINE_GUIDNAMED(KSPROPSETID_DirectSound3DListener) - -typedef enum -{ - KSPROPERTY_DIRECTSOUND3DLISTENER_ALL, - KSPROPERTY_DIRECTSOUND3DLISTENER_POSITION, - KSPROPERTY_DIRECTSOUND3DLISTENER_VELOCITY, - KSPROPERTY_DIRECTSOUND3DLISTENER_ORIENTATION, - KSPROPERTY_DIRECTSOUND3DLISTENER_DISTANCEFACTOR, - KSPROPERTY_DIRECTSOUND3DLISTENER_ROLLOFFFACTOR, - KSPROPERTY_DIRECTSOUND3DLISTENER_DOPPLERFACTOR, - KSPROPERTY_DIRECTSOUND3DLISTENER_BATCH, - KSPROPERTY_DIRECTSOUND3DLISTENER_ALLOCATION -}KSPROPERTY_DIRECTSOUND3DLISTENER; - -typedef struct -{ - DS3DVECTOR Position; - DS3DVECTOR Velocity; - DS3DVECTOR OrientFront; - DS3DVECTOR OrientTop; - FLOAT DistanceFactor; - FLOAT RolloffFactor; - FLOAT DopplerFactor; -}KSDS3D_LISTENER_ALL, * PKSDS3D_LISTENER_ALL; - -typedef struct -{ - DS3DVECTOR Front; - DS3DVECTOR Top; -}KSDS3D_LISTENER_ORIENTATION, * PKSDS3D_LISTENER_ORIENTATION; - - # define STATIC_KSPROPSETID_DirectSound3DBuffer \ - 0x437b3411L, 0xd060, 0x11d0, 0x85, 0x83, 0x00, 0xc0, 0x4f, 0xd9, 0xba, 0xf3 -DEFINE_GUIDSTRUCT("437b3411-d060-11d0-8583-00c04fd9baf3", KSPROPSETID_DirectSound3DBuffer); - # define KSPROPSETID_DirectSound3DBuffer DEFINE_GUIDNAMED(KSPROPSETID_DirectSound3DBuffer) - -typedef enum -{ - KSPROPERTY_DIRECTSOUND3DBUFFER_ALL, - KSPROPERTY_DIRECTSOUND3DBUFFER_POSITION, - KSPROPERTY_DIRECTSOUND3DBUFFER_VELOCITY, - KSPROPERTY_DIRECTSOUND3DBUFFER_CONEANGLES, - KSPROPERTY_DIRECTSOUND3DBUFFER_CONEORIENTATION, - KSPROPERTY_DIRECTSOUND3DBUFFER_CONEOUTSIDEVOLUME, - KSPROPERTY_DIRECTSOUND3DBUFFER_MINDISTANCE, - KSPROPERTY_DIRECTSOUND3DBUFFER_MAXDISTANCE, - KSPROPERTY_DIRECTSOUND3DBUFFER_MODE -}KSPROPERTY_DIRECTSOUND3DBUFFER; - -typedef struct -{ - DS3DVECTOR Position; - DS3DVECTOR Velocity; - ULONG InsideConeAngle; - ULONG OutsideConeAngle; - DS3DVECTOR ConeOrientation; - LONG ConeOutsideVolume; - FLOAT MinDistance; - FLOAT MaxDistance; - ULONG Mode; -}KSDS3D_BUFFER_ALL, * PKSDS3D_BUFFER_ALL; - -typedef struct -{ - ULONG InsideConeAngle; - ULONG OutsideConeAngle; -}KSDS3D_BUFFER_CONE_ANGLES, * PKSDS3D_BUFFER_CONE_ANGLES; - - # define KSAUDIO_STEREO_SPEAKER_GEOMETRY_HEADPHONE (-1) - # define KSAUDIO_STEREO_SPEAKER_GEOMETRY_MIN 5 - # define KSAUDIO_STEREO_SPEAKER_GEOMETRY_NARROW 10 - # define KSAUDIO_STEREO_SPEAKER_GEOMETRY_WIDE 20 - # define KSAUDIO_STEREO_SPEAKER_GEOMETRY_MAX 180 - - # define KSDSOUND_3D_MODE_NORMAL 0x00000000 - # define KSDSOUND_3D_MODE_HEADRELATIVE 0x00000001 - # define KSDSOUND_3D_MODE_DISABLE 0x00000002 - - # define KSDSOUND_BUFFER_CTRL_HRTF_3D 0x40000000 - -typedef struct -{ - ULONG Size; - ULONG Enabled; - WINBOOL SwapChannels; - WINBOOL ZeroAzimuth; - WINBOOL CrossFadeOutput; - ULONG FilterSize; -}KSDS3D_HRTF_PARAMS_MSG, * PKSDS3D_HRTF_PARAMS_MSG; - -typedef enum -{ - FULL_FILTER, - LIGHT_FILTER, - KSDS3D_FILTER_QUALITY_COUNT -}KSDS3D_HRTF_FILTER_QUALITY; - -typedef struct -{ - ULONG Size; - KSDS3D_HRTF_FILTER_QUALITY Quality; - FLOAT SampleRate; - ULONG MaxFilterSize; - ULONG FilterTransientMuteLength; - ULONG FilterOverlapBufferLength; - ULONG OutputOverlapBufferLength; - ULONG Reserved; -}KSDS3D_HRTF_INIT_MSG, * PKSDS3D_HRTF_INIT_MSG; - -typedef enum -{ - FLOAT_COEFF, - SHORT_COEFF, - KSDS3D_COEFF_COUNT -}KSDS3D_HRTF_COEFF_FORMAT; - -typedef enum -{ - DIRECT_FORM, - CASCADE_FORM, - KSDS3D_FILTER_METHOD_COUNT -}KSDS3D_HRTF_FILTER_METHOD; - -typedef enum -{ - DS3D_HRTF_VERSION_1 -}KSDS3D_HRTF_FILTER_VERSION; - -typedef struct -{ - KSDS3D_HRTF_FILTER_METHOD FilterMethod; - KSDS3D_HRTF_COEFF_FORMAT CoeffFormat; - KSDS3D_HRTF_FILTER_VERSION Version; - ULONG Reserved; -}KSDS3D_HRTF_FILTER_FORMAT_MSG, * PKSDS3D_HRTF_FILTER_FORMAT_MSG; - - # define STATIC_KSPROPSETID_Hrtf3d \ - 0xb66decb0L, 0xa083, 0x11d0, 0x85, 0x1e, 0x00, 0xc0, 0x4f, 0xd9, 0xba, 0xf3 -DEFINE_GUIDSTRUCT("b66decb0-a083-11d0-851e-00c04fd9baf3", KSPROPSETID_Hrtf3d); - # define KSPROPSETID_Hrtf3d DEFINE_GUIDNAMED(KSPROPSETID_Hrtf3d) - -typedef enum -{ - KSPROPERTY_HRTF3D_PARAMS = 0, - KSPROPERTY_HRTF3D_INITIALIZE, - KSPROPERTY_HRTF3D_FILTER_FORMAT -}KSPROPERTY_HRTF3D; - -typedef struct -{ - LONG Channel; - FLOAT VolSmoothScale; - FLOAT TotalDryAttenuation; - FLOAT TotalWetAttenuation; - LONG SmoothFrequency; - LONG Delay; -}KSDS3D_ITD_PARAMS, * PKSDS3D_ITD_PARAMS; - -typedef struct -{ - ULONG Enabled; - KSDS3D_ITD_PARAMS LeftParams; - KSDS3D_ITD_PARAMS RightParams; - ULONG Reserved; -}KSDS3D_ITD_PARAMS_MSG, * PKSDS3D_ITD_PARAMS_MSG; - - # define STATIC_KSPROPSETID_Itd3d \ - 0x6429f090L, 0x9fd9, 0x11d0, 0xa7, 0x5b, 0x00, 0xa0, 0xc9, 0x03, 0x65, 0xe3 -DEFINE_GUIDSTRUCT("6429f090-9fd9-11d0-a75b-00a0c90365e3", KSPROPSETID_Itd3d); - # define KSPROPSETID_Itd3d DEFINE_GUIDNAMED(KSPROPSETID_Itd3d) - -typedef enum -{ - KSPROPERTY_ITD3D_PARAMS = 0 -}KSPROPERTY_ITD3D; - -typedef struct -{ - KSDATARANGE DataRange; - ULONG MaximumChannels; - ULONG MinimumBitsPerSample; - ULONG MaximumBitsPerSample; - ULONG MinimumSampleFrequency; - ULONG MaximumSampleFrequency; -}KSDATARANGE_AUDIO, * PKSDATARANGE_AUDIO; - - # define STATIC_KSDATAFORMAT_SUBTYPE_RIFF \ - 0x4995DAEEL, 0x9EE6, 0x11D0, 0xA4, 0x0E, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96 -DEFINE_GUIDSTRUCT("4995DAEE-9EE6-11D0-A40E-00A0C9223196", KSDATAFORMAT_SUBTYPE_RIFF); - # define KSDATAFORMAT_SUBTYPE_RIFF DEFINE_GUIDNAMED(KSDATAFORMAT_SUBTYPE_RIFF) - - # define STATIC_KSDATAFORMAT_SUBTYPE_RIFFWAVE \ - 0xe436eb8bL, 0x524f, 0x11ce, 0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70 -DEFINE_GUIDSTRUCT("e436eb8b-524f-11ce-9f53-0020af0ba770", KSDATAFORMAT_SUBTYPE_RIFFWAVE); - # define KSDATAFORMAT_SUBTYPE_RIFFWAVE DEFINE_GUIDNAMED(KSDATAFORMAT_SUBTYPE_RIFFWAVE) - - # define STATIC_KSPROPSETID_Bibliographic \ - 0x07BA150EL, 0xE2B1, 0x11D0, 0xAC, 0x17, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96 -DEFINE_GUIDSTRUCT("07BA150E-E2B1-11D0-AC17-00A0C9223196", KSPROPSETID_Bibliographic); - # define KSPROPSETID_Bibliographic DEFINE_GUIDNAMED(KSPROPSETID_Bibliographic) - - # define SEB_MK_FOURCC(a, b, c, d) ((a << 24) | (b << 16) | (c << 8) | (d << 0)) - -typedef enum -{ - KSPROPERTY_BIBLIOGRAPHIC_LEADER = SEB_MK_FOURCC('R', 'D', 'L', ' '), - KSPROPERTY_BIBLIOGRAPHIC_LCCN = SEB_MK_FOURCC('0', '1', '0', ' '), - KSPROPERTY_BIBLIOGRAPHIC_ISBN = SEB_MK_FOURCC('0', '2', '0', ' '), - KSPROPERTY_BIBLIOGRAPHIC_ISSN = SEB_MK_FOURCC('2', '2', '0', ' '), - KSPROPERTY_BIBLIOGRAPHIC_CATALOGINGSOURCE = SEB_MK_FOURCC('0', '4', '0', ' '), - KSPROPERTY_BIBLIOGRAPHIC_MAINPERSONALNAME = SEB_MK_FOURCC('0', '0', '1', ' '), - KSPROPERTY_BIBLIOGRAPHIC_MAINCORPORATEBODY = SEB_MK_FOURCC('0', '1', '1', ' '), - KSPROPERTY_BIBLIOGRAPHIC_MAINMEETINGNAME = SEB_MK_FOURCC('1', '1', '1', ' '), - KSPROPERTY_BIBLIOGRAPHIC_MAINUNIFORMTITLE = SEB_MK_FOURCC('0', '3', '1', ' '), - KSPROPERTY_BIBLIOGRAPHIC_UNIFORMTITLE = SEB_MK_FOURCC('0', '4', '2', ' '), - KSPROPERTY_BIBLIOGRAPHIC_TITLESTATEMENT = SEB_MK_FOURCC('5', '4', '2', ' '), - KSPROPERTY_BIBLIOGRAPHIC_VARYINGFORMTITLE = SEB_MK_FOURCC('6', '4', '2', ' '), - KSPROPERTY_BIBLIOGRAPHIC_PUBLICATION = SEB_MK_FOURCC('0', '6', '2', ' '), - KSPROPERTY_BIBLIOGRAPHIC_PHYSICALDESCRIPTION = SEB_MK_FOURCC('0', '0', '3', ' '), - KSPROPERTY_BIBLIOGRAPHIC_ADDEDENTRYTITLE = SEB_MK_FOURCC('0', '4', '4', ' '), - KSPROPERTY_BIBLIOGRAPHIC_SERIESSTATEMENT = SEB_MK_FOURCC('0', '9', '4', ' '), - KSPROPERTY_BIBLIOGRAPHIC_GENERALNOTE = SEB_MK_FOURCC('0', '0', '5', ' '), - KSPROPERTY_BIBLIOGRAPHIC_BIBLIOGRAPHYNOTE = SEB_MK_FOURCC('4', '0', '5', ' '), - KSPROPERTY_BIBLIOGRAPHIC_CONTENTSNOTE = SEB_MK_FOURCC('5', '0', '5', ' '), - KSPROPERTY_BIBLIOGRAPHIC_CREATIONCREDIT = SEB_MK_FOURCC('8', '0', '5', ' '), - KSPROPERTY_BIBLIOGRAPHIC_CITATION = SEB_MK_FOURCC('0', '1', '5', ' '), - KSPROPERTY_BIBLIOGRAPHIC_PARTICIPANT = SEB_MK_FOURCC('1', '1', '5', ' '), - KSPROPERTY_BIBLIOGRAPHIC_SUMMARY = SEB_MK_FOURCC('0', '2', '5', ' '), - KSPROPERTY_BIBLIOGRAPHIC_TARGETAUDIENCE = SEB_MK_FOURCC('1', '2', '5', ' '), - KSPROPERTY_BIBLIOGRAPHIC_ADDEDFORMAVAILABLE = SEB_MK_FOURCC('0', '3', '5', ' '), - KSPROPERTY_BIBLIOGRAPHIC_SYSTEMDETAILS = SEB_MK_FOURCC('8', '3', '5', ' '), - KSPROPERTY_BIBLIOGRAPHIC_AWARDS = SEB_MK_FOURCC('6', '8', '5', ' '), - KSPROPERTY_BIBLIOGRAPHIC_ADDEDENTRYPERSONALNAME = SEB_MK_FOURCC('0', '0', '6', ' '), - KSPROPERTY_BIBLIOGRAPHIC_ADDEDENTRYTOPICALTERM = SEB_MK_FOURCC('0', '5', '6', ' '), - KSPROPERTY_BIBLIOGRAPHIC_ADDEDENTRYGEOGRAPHIC = SEB_MK_FOURCC('1', '5', '6', ' '), - KSPROPERTY_BIBLIOGRAPHIC_INDEXTERMGENRE = SEB_MK_FOURCC('5', '5', '6', ' '), - KSPROPERTY_BIBLIOGRAPHIC_INDEXTERMCURRICULUM = SEB_MK_FOURCC('8', '5', '6', ' '), - KSPROPERTY_BIBLIOGRAPHIC_ADDEDENTRYUNIFORMTITLE = SEB_MK_FOURCC('0', '3', '7', ' '), - KSPROPERTY_BIBLIOGRAPHIC_ADDEDENTRYRELATED = SEB_MK_FOURCC('0', '4', '7', ' '), - KSPROPERTY_BIBLIOGRAPHIC_SERIESSTATEMENTPERSONALNAME = SEB_MK_FOURCC('0', '0', '8', ' '), - KSPROPERTY_BIBLIOGRAPHIC_SERIESSTATEMENTUNIFORMTITLE = SEB_MK_FOURCC('0', '3', '8', ' ') -}KSPROPERTY_BIBLIOGRAPHIC; - - # undef SEB_MK_FOURCC - - # define STATIC_KSPROPSETID_TopologyNode \ - 0x45FFAAA1L, 0x6E1B, 0x11D0, 0xBC, 0xF2, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00 -DEFINE_GUIDSTRUCT("45FFAAA1-6E1B-11D0-BCF2-444553540000", KSPROPSETID_TopologyNode); - # define KSPROPSETID_TopologyNode DEFINE_GUIDNAMED(KSPROPSETID_TopologyNode) - -typedef enum -{ - KSPROPERTY_TOPOLOGYNODE_ENABLE = 1, - KSPROPERTY_TOPOLOGYNODE_RESET -}KSPROPERTY_TOPOLOGYNODE; - - # define STATIC_KSPROPSETID_RtAudio \ - 0xa855a48c, 0x2f78, 0x4729, 0x90, 0x51, 0x19, 0x68, 0x74, 0x6b, 0x9e, 0xef -DEFINE_GUIDSTRUCT("A855A48C-2F78-4729-9051-1968746B9EEF", KSPROPSETID_RtAudio); - # define KSPROPSETID_RtAudio DEFINE_GUIDNAMED(KSPROPSETID_RtAudio) - -typedef enum -{ - KSPROPERTY_RTAUDIO_GETPOSITIONFUNCTION -}KSPROPERTY_RTAUDIO; - - # define STATIC_KSPROPSETID_DrmAudioStream \ - 0x2f2c8ddd, 0x4198, 0x4fac, 0xba, 0x29, 0x61, 0xbb, 0x5, 0xb7, 0xde, 0x6 -DEFINE_GUIDSTRUCT("2F2C8DDD-4198-4fac-BA29-61BB05B7DE06", KSPROPSETID_DrmAudioStream); - # define KSPROPSETID_DrmAudioStream DEFINE_GUIDNAMED(KSPROPSETID_DrmAudioStream) - -typedef enum -{ - KSPROPERTY_DRMAUDIOSTREAM_CONTENTID -}KSPROPERTY_DRMAUDIOSTREAM; - - # define STATIC_KSPROPSETID_Audio \ - 0x45FFAAA0L, 0x6E1B, 0x11D0, 0xBC, 0xF2, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00 -DEFINE_GUIDSTRUCT("45FFAAA0-6E1B-11D0-BCF2-444553540000", KSPROPSETID_Audio); - # define KSPROPSETID_Audio DEFINE_GUIDNAMED(KSPROPSETID_Audio) - -typedef enum -{ - KSPROPERTY_AUDIO_LATENCY = 1, - KSPROPERTY_AUDIO_COPY_PROTECTION, - KSPROPERTY_AUDIO_CHANNEL_CONFIG, - KSPROPERTY_AUDIO_VOLUMELEVEL, - KSPROPERTY_AUDIO_POSITION, - KSPROPERTY_AUDIO_DYNAMIC_RANGE, - KSPROPERTY_AUDIO_QUALITY, - KSPROPERTY_AUDIO_SAMPLING_RATE, - KSPROPERTY_AUDIO_DYNAMIC_SAMPLING_RATE, - KSPROPERTY_AUDIO_MIX_LEVEL_TABLE, - KSPROPERTY_AUDIO_MIX_LEVEL_CAPS, - KSPROPERTY_AUDIO_MUX_SOURCE, - KSPROPERTY_AUDIO_MUTE, - KSPROPERTY_AUDIO_BASS, - KSPROPERTY_AUDIO_MID, - KSPROPERTY_AUDIO_TREBLE, - KSPROPERTY_AUDIO_BASS_BOOST, - KSPROPERTY_AUDIO_EQ_LEVEL, - KSPROPERTY_AUDIO_NUM_EQ_BANDS, - KSPROPERTY_AUDIO_EQ_BANDS, - KSPROPERTY_AUDIO_AGC, - KSPROPERTY_AUDIO_DELAY, - KSPROPERTY_AUDIO_LOUDNESS, - KSPROPERTY_AUDIO_WIDE_MODE, - KSPROPERTY_AUDIO_WIDENESS, - KSPROPERTY_AUDIO_REVERB_LEVEL, - KSPROPERTY_AUDIO_CHORUS_LEVEL, - KSPROPERTY_AUDIO_DEV_SPECIFIC, - KSPROPERTY_AUDIO_DEMUX_DEST, - KSPROPERTY_AUDIO_STEREO_ENHANCE, - KSPROPERTY_AUDIO_MANUFACTURE_GUID, - KSPROPERTY_AUDIO_PRODUCT_GUID, - KSPROPERTY_AUDIO_CPU_RESOURCES, - KSPROPERTY_AUDIO_STEREO_SPEAKER_GEOMETRY, - KSPROPERTY_AUDIO_SURROUND_ENCODE, - KSPROPERTY_AUDIO_3D_INTERFACE, - KSPROPERTY_AUDIO_PEAKMETER, - KSPROPERTY_AUDIO_ALGORITHM_INSTANCE, - KSPROPERTY_AUDIO_FILTER_STATE, - KSPROPERTY_AUDIO_PREFERRED_STATUS -}KSPROPERTY_AUDIO; - - # define KSAUDIO_QUALITY_WORST 0x0 - # define KSAUDIO_QUALITY_PC 0x1 - # define KSAUDIO_QUALITY_BASIC 0x2 - # define KSAUDIO_QUALITY_ADVANCED 0x3 - - # define KSAUDIO_CPU_RESOURCES_NOT_HOST_CPU 0x00000000 - # define KSAUDIO_CPU_RESOURCES_HOST_CPU 0x7FFFFFFF - -typedef struct -{ - WINBOOL fCopyrighted; - WINBOOL fOriginal; -}KSAUDIO_COPY_PROTECTION, * PKSAUDIO_COPY_PROTECTION; - -typedef struct -{ - LONG ActiveSpeakerPositions; -}KSAUDIO_CHANNEL_CONFIG, * PKSAUDIO_CHANNEL_CONFIG; - - # define SPEAKER_FRONT_LEFT 0x1 - # define SPEAKER_FRONT_RIGHT 0x2 - # define SPEAKER_FRONT_CENTER 0x4 - # define SPEAKER_LOW_FREQUENCY 0x8 - # define SPEAKER_BACK_LEFT 0x10 - # define SPEAKER_BACK_RIGHT 0x20 - # define SPEAKER_FRONT_LEFT_OF_CENTER 0x40 - # define SPEAKER_FRONT_RIGHT_OF_CENTER 0x80 - # define SPEAKER_BACK_CENTER 0x100 - # define SPEAKER_SIDE_LEFT 0x200 - # define SPEAKER_SIDE_RIGHT 0x400 - # define SPEAKER_TOP_CENTER 0x800 - # define SPEAKER_TOP_FRONT_LEFT 0x1000 - # define SPEAKER_TOP_FRONT_CENTER 0x2000 - # define SPEAKER_TOP_FRONT_RIGHT 0x4000 - # define SPEAKER_TOP_BACK_LEFT 0x8000 - # define SPEAKER_TOP_BACK_CENTER 0x10000 - # define SPEAKER_TOP_BACK_RIGHT 0x20000 - - # define SPEAKER_RESERVED 0x7FFC0000 - - # define SPEAKER_ALL 0x80000000 - - # define KSAUDIO_SPEAKER_DIRECTOUT 0 - # define KSAUDIO_SPEAKER_MONO (SPEAKER_FRONT_CENTER) - # define KSAUDIO_SPEAKER_STEREO (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT) - # define KSAUDIO_SPEAKER_QUAD (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | \ - SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT) - # define KSAUDIO_SPEAKER_SURROUND (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | \ - SPEAKER_FRONT_CENTER | SPEAKER_BACK_CENTER) - # define KSAUDIO_SPEAKER_5POINT1 (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | \ - SPEAKER_FRONT_CENTER | SPEAKER_LOW_FREQUENCY | \ - SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT) - # define KSAUDIO_SPEAKER_7POINT1 (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | \ - SPEAKER_FRONT_CENTER | SPEAKER_LOW_FREQUENCY | \ - SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT | \ - SPEAKER_FRONT_LEFT_OF_CENTER | SPEAKER_FRONT_RIGHT_OF_CENTER) - # define KSAUDIO_SPEAKER_5POINT1_SURROUND (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | \ - SPEAKER_FRONT_CENTER | SPEAKER_LOW_FREQUENCY | \ - SPEAKER_SIDE_LEFT | SPEAKER_SIDE_RIGHT) - # define KSAUDIO_SPEAKER_7POINT1_SURROUND (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | \ - SPEAKER_FRONT_CENTER | SPEAKER_LOW_FREQUENCY | \ - SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT | \ - SPEAKER_SIDE_LEFT | SPEAKER_SIDE_RIGHT) - - # define KSAUDIO_SPEAKER_5POINT1_BACK KSAUDIO_SPEAKER_5POINT1 - # define KSAUDIO_SPEAKER_7POINT1_WIDE KSAUDIO_SPEAKER_7POINT1 - - # define KSAUDIO_SPEAKER_GROUND_FRONT_LEFT SPEAKER_FRONT_LEFT - # define KSAUDIO_SPEAKER_GROUND_FRONT_CENTER SPEAKER_FRONT_CENTER - # define KSAUDIO_SPEAKER_GROUND_FRONT_RIGHT SPEAKER_FRONT_RIGHT - # define KSAUDIO_SPEAKER_GROUND_REAR_LEFT SPEAKER_BACK_LEFT - # define KSAUDIO_SPEAKER_GROUND_REAR_RIGHT SPEAKER_BACK_RIGHT - # define KSAUDIO_SPEAKER_TOP_MIDDLE SPEAKER_TOP_CENTER - # define KSAUDIO_SPEAKER_SUPER_WOOFER SPEAKER_LOW_FREQUENCY - -typedef struct -{ - ULONG QuietCompression; - ULONG LoudCompression; -}KSAUDIO_DYNAMIC_RANGE, * PKSAUDIO_DYNAMIC_RANGE; - -typedef struct -{ - WINBOOL Mute; - LONG Level; -}KSAUDIO_MIXLEVEL, * PKSAUDIO_MIXLEVEL; - -typedef struct -{ - WINBOOL Mute; - LONG Minimum; - LONG Maximum; - LONG Reset; -}KSAUDIO_MIX_CAPS, * PKSAUDIO_MIX_CAPS; - -typedef struct -{ - ULONG InputChannels; - ULONG OutputChannels; - KSAUDIO_MIX_CAPS Capabilities[1]; -}KSAUDIO_MIXCAP_TABLE, * PKSAUDIO_MIXCAP_TABLE; - -typedef enum -{ - SE_TECH_NONE, - SE_TECH_ANALOG_DEVICES_PHAT, - SE_TECH_CREATIVE, - SE_TECH_NATIONAL_SEMI, - SE_TECH_YAMAHA_YMERSION, - SE_TECH_BBE, - SE_TECH_CRYSTAL_SEMI, - SE_TECH_QSOUND_QXPANDER, - SE_TECH_SPATIALIZER, - SE_TECH_SRS, - SE_TECH_PLATFORM_TECH, - SE_TECH_AKM, - SE_TECH_AUREAL, - SE_TECH_AZTECH, - SE_TECH_BINAURA, - SE_TECH_ESS_TECH, - SE_TECH_HARMAN_VMAX, - SE_TECH_NVIDEA, - SE_TECH_PHILIPS_INCREDIBLE, - SE_TECH_TEXAS_INST, - SE_TECH_VLSI_TECH -}SE_TECHNIQUE; - -typedef struct -{ - SE_TECHNIQUE Technique; - ULONG Center; - ULONG Depth; - ULONG Reserved; -}KSAUDIO_STEREO_ENHANCE, * PKSAUDIO_STEREO_ENHANCE; - -typedef enum -{ - KSPROPERTY_SYSAUDIO_NORMAL_DEFAULT = 0, - KSPROPERTY_SYSAUDIO_PLAYBACK_DEFAULT, - KSPROPERTY_SYSAUDIO_RECORD_DEFAULT, - KSPROPERTY_SYSAUDIO_MIDI_DEFAULT, - KSPROPERTY_SYSAUDIO_MIXER_DEFAULT -}KSPROPERTY_SYSAUDIO_DEFAULT_TYPE; - -typedef struct -{ - WINBOOL Enable; - KSPROPERTY_SYSAUDIO_DEFAULT_TYPE DeviceType; - ULONG Flags; - ULONG Reserved; -}KSAUDIO_PREFERRED_STATUS, * PKSAUDIO_PREFERRED_STATUS; - - # define STATIC_KSNODETYPE_DAC \ - 0x507AE360L, 0xC554, 0x11D0, 0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1 -DEFINE_GUIDSTRUCT("507AE360-C554-11D0-8A2B-00A0C9255AC1", KSNODETYPE_DAC); - # define KSNODETYPE_DAC DEFINE_GUIDNAMED(KSNODETYPE_DAC) - - # define STATIC_KSNODETYPE_ADC \ - 0x4D837FE0L, 0xC555, 0x11D0, 0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1 -DEFINE_GUIDSTRUCT("4D837FE0-C555-11D0-8A2B-00A0C9255AC1", KSNODETYPE_ADC); - # define KSNODETYPE_ADC DEFINE_GUIDNAMED(KSNODETYPE_ADC) - - # define STATIC_KSNODETYPE_SRC \ - 0x9DB7B9E0L, 0xC555, 0x11D0, 0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1 -DEFINE_GUIDSTRUCT("9DB7B9E0-C555-11D0-8A2B-00A0C9255AC1", KSNODETYPE_SRC); - # define KSNODETYPE_SRC DEFINE_GUIDNAMED(KSNODETYPE_SRC) - - # define STATIC_KSNODETYPE_SUPERMIX \ - 0xE573ADC0L, 0xC555, 0x11D0, 0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1 -DEFINE_GUIDSTRUCT("E573ADC0-C555-11D0-8A2B-00A0C9255AC1", KSNODETYPE_SUPERMIX); - # define KSNODETYPE_SUPERMIX DEFINE_GUIDNAMED(KSNODETYPE_SUPERMIX) - - # define STATIC_KSNODETYPE_MUX \ - 0x2CEAF780L, 0xC556, 0x11D0, 0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1 -DEFINE_GUIDSTRUCT("2CEAF780-C556-11D0-8A2B-00A0C9255AC1", KSNODETYPE_MUX); - # define KSNODETYPE_MUX DEFINE_GUIDNAMED(KSNODETYPE_MUX) - - # define STATIC_KSNODETYPE_DEMUX \ - 0xC0EB67D4L, 0xE807, 0x11D0, 0x95, 0x8A, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3 -DEFINE_GUIDSTRUCT("C0EB67D4-E807-11D0-958A-00C04FB925D3", KSNODETYPE_DEMUX); - # define KSNODETYPE_DEMUX DEFINE_GUIDNAMED(KSNODETYPE_DEMUX) - - # define STATIC_KSNODETYPE_SUM \ - 0xDA441A60L, 0xC556, 0x11D0, 0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1 -DEFINE_GUIDSTRUCT("DA441A60-C556-11D0-8A2B-00A0C9255AC1", KSNODETYPE_SUM); - # define KSNODETYPE_SUM DEFINE_GUIDNAMED(KSNODETYPE_SUM) - - # define STATIC_KSNODETYPE_MUTE \ - 0x02B223C0L, 0xC557, 0x11D0, 0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1 -DEFINE_GUIDSTRUCT("02B223C0-C557-11D0-8A2B-00A0C9255AC1", KSNODETYPE_MUTE); - # define KSNODETYPE_MUTE DEFINE_GUIDNAMED(KSNODETYPE_MUTE) - - # define STATIC_KSNODETYPE_VOLUME \ - 0x3A5ACC00L, 0xC557, 0x11D0, 0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1 -DEFINE_GUIDSTRUCT("3A5ACC00-C557-11D0-8A2B-00A0C9255AC1", KSNODETYPE_VOLUME); - # define KSNODETYPE_VOLUME DEFINE_GUIDNAMED(KSNODETYPE_VOLUME) - - # define STATIC_KSNODETYPE_TONE \ - 0x7607E580L, 0xC557, 0x11D0, 0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1 -DEFINE_GUIDSTRUCT("7607E580-C557-11D0-8A2B-00A0C9255AC1", KSNODETYPE_TONE); - # define KSNODETYPE_TONE DEFINE_GUIDNAMED(KSNODETYPE_TONE) - - # define STATIC_KSNODETYPE_EQUALIZER \ - 0x9D41B4A0L, 0xC557, 0x11D0, 0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1 -DEFINE_GUIDSTRUCT("9D41B4A0-C557-11D0-8A2B-00A0C9255AC1", KSNODETYPE_EQUALIZER); - # define KSNODETYPE_EQUALIZER DEFINE_GUIDNAMED(KSNODETYPE_EQUALIZER) - - # define STATIC_KSNODETYPE_AGC \ - 0xE88C9BA0L, 0xC557, 0x11D0, 0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1 -DEFINE_GUIDSTRUCT("E88C9BA0-C557-11D0-8A2B-00A0C9255AC1", KSNODETYPE_AGC); - # define KSNODETYPE_AGC DEFINE_GUIDNAMED(KSNODETYPE_AGC) - - # define STATIC_KSNODETYPE_NOISE_SUPPRESS \ - 0xe07f903f, 0x62fd, 0x4e60, 0x8c, 0xdd, 0xde, 0xa7, 0x23, 0x66, 0x65, 0xb5 -DEFINE_GUIDSTRUCT("E07F903F-62FD-4e60-8CDD-DEA7236665B5", KSNODETYPE_NOISE_SUPPRESS); - # define KSNODETYPE_NOISE_SUPPRESS DEFINE_GUIDNAMED(KSNODETYPE_NOISE_SUPPRESS) - - # define STATIC_KSNODETYPE_DELAY \ - 0x144981E0L, 0xC558, 0x11D0, 0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1 -DEFINE_GUIDSTRUCT("144981E0-C558-11D0-8A2B-00A0C9255AC1", KSNODETYPE_DELAY); - # define KSNODETYPE_DELAY DEFINE_GUIDNAMED(KSNODETYPE_DELAY) - - # define STATIC_KSNODETYPE_LOUDNESS \ - 0x41887440L, 0xC558, 0x11D0, 0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1 -DEFINE_GUIDSTRUCT("41887440-C558-11D0-8A2B-00A0C9255AC1", KSNODETYPE_LOUDNESS); - # define KSNODETYPE_LOUDNESS DEFINE_GUIDNAMED(KSNODETYPE_LOUDNESS) - - # define STATIC_KSNODETYPE_PROLOGIC_DECODER \ - 0x831C2C80L, 0xC558, 0x11D0, 0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1 -DEFINE_GUIDSTRUCT("831C2C80-C558-11D0-8A2B-00A0C9255AC1", KSNODETYPE_PROLOGIC_DECODER); - # define KSNODETYPE_PROLOGIC_DECODER DEFINE_GUIDNAMED(KSNODETYPE_PROLOGIC_DECODER) - - # define STATIC_KSNODETYPE_STEREO_WIDE \ - 0xA9E69800L, 0xC558, 0x11D0, 0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1 -DEFINE_GUIDSTRUCT("A9E69800-C558-11D0-8A2B-00A0C9255AC1", KSNODETYPE_STEREO_WIDE); - # define KSNODETYPE_STEREO_WIDE DEFINE_GUIDNAMED(KSNODETYPE_STEREO_WIDE) - - # define STATIC_KSNODETYPE_STEREO_ENHANCE \ - 0xAF6878ACL, 0xE83F, 0x11D0, 0x95, 0x8A, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3 -DEFINE_GUIDSTRUCT("AF6878AC-E83F-11D0-958A-00C04FB925D3", KSNODETYPE_STEREO_ENHANCE); - # define KSNODETYPE_STEREO_ENHANCE DEFINE_GUIDNAMED(KSNODETYPE_STEREO_ENHANCE) - - # define STATIC_KSNODETYPE_REVERB \ - 0xEF0328E0L, 0xC558, 0x11D0, 0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1 -DEFINE_GUIDSTRUCT("EF0328E0-C558-11D0-8A2B-00A0C9255AC1", KSNODETYPE_REVERB); - # define KSNODETYPE_REVERB DEFINE_GUIDNAMED(KSNODETYPE_REVERB) - - # define STATIC_KSNODETYPE_CHORUS \ - 0x20173F20L, 0xC559, 0x11D0, 0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1 -DEFINE_GUIDSTRUCT("20173F20-C559-11D0-8A2B-00A0C9255AC1", KSNODETYPE_CHORUS); - # define KSNODETYPE_CHORUS DEFINE_GUIDNAMED(KSNODETYPE_CHORUS) - - # define STATIC_KSNODETYPE_3D_EFFECTS \ - 0x55515860L, 0xC559, 0x11D0, 0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1 -DEFINE_GUIDSTRUCT("55515860-C559-11D0-8A2B-00A0C9255AC1", KSNODETYPE_3D_EFFECTS); - # define KSNODETYPE_3D_EFFECTS DEFINE_GUIDNAMED(KSNODETYPE_3D_EFFECTS) - - # define STATIC_KSNODETYPE_ACOUSTIC_ECHO_CANCEL STATIC_KSCATEGORY_ACOUSTIC_ECHO_CANCEL - # define KSNODETYPE_ACOUSTIC_ECHO_CANCEL KSCATEGORY_ACOUSTIC_ECHO_CANCEL - - # define STATIC_KSALGORITHMINSTANCE_SYSTEM_ACOUSTIC_ECHO_CANCEL \ - 0x1c22c56dL, 0x9879, 0x4f5b, 0xa3, 0x89, 0x27, 0x99, 0x6d, 0xdc, 0x28, 0x10 -DEFINE_GUIDSTRUCT("1C22C56D-9879-4f5b-A389-27996DDC2810", KSALGORITHMINSTANCE_SYSTEM_ACOUSTIC_ECHO_CANCEL); - # define KSALGORITHMINSTANCE_SYSTEM_ACOUSTIC_ECHO_CANCEL DEFINE_GUIDNAMED(KSALGORITHMINSTANCE_SYSTEM_ACOUSTIC_ECHO_CANCEL) - - # define STATIC_KSALGORITHMINSTANCE_SYSTEM_NOISE_SUPPRESS \ - 0x5ab0882eL, 0x7274, 0x4516, 0x87, 0x7d, 0x4e, 0xee, 0x99, 0xba, 0x4f, 0xd0 -DEFINE_GUIDSTRUCT("5AB0882E-7274-4516-877D-4EEE99BA4FD0", KSALGORITHMINSTANCE_SYSTEM_NOISE_SUPPRESS); - # define KSALGORITHMINSTANCE_SYSTEM_NOISE_SUPPRESS DEFINE_GUIDNAMED(KSALGORITHMINSTANCE_SYSTEM_NOISE_SUPPRESS) - - # define STATIC_KSALGORITHMINSTANCE_SYSTEM_AGC \ - 0x950e55b9L, 0x877c, 0x4c67, 0xbe, 0x8, 0xe4, 0x7b, 0x56, 0x11, 0x13, 0xa -DEFINE_GUIDSTRUCT("950E55B9-877C-4c67-BE08-E47B5611130A", KSALGORITHMINSTANCE_SYSTEM_AGC); - # define KSALGORITHMINSTANCE_SYSTEM_AGC DEFINE_GUIDNAMED(KSALGORITHMINSTANCE_SYSTEM_AGC) - - # define STATIC_KSALGORITHMINSTANCE_SYSTEM_MICROPHONE_ARRAY_PROCESSOR \ - 0xB6F5A0A0L, 0x9E61, 0x4F8C, 0x91, 0xE3, 0x76, 0xCF, 0xF, 0x3C, 0x47, 0x1F -DEFINE_GUIDSTRUCT("B6F5A0A0-9E61-4f8c-91E3-76CF0F3C471F", KSALGORITHMINSTANCE_SYSTEM_MICROPHONE_ARRAY_PROCESSOR); - # define KSALGORITHMINSTANCE_SYSTEM_MICROPHONE_ARRAY_PROCESSOR DEFINE_GUIDNAMED(KSALGORITHMINSTANCE_SYSTEM_MICROPHONE_ARRAY_PROCESSOR) - - # define STATIC_KSNODETYPE_MICROPHONE_ARRAY_PROCESSOR STATIC_KSCATEGORY_MICROPHONE_ARRAY_PROCESSOR - # define KSNODETYPE_MICROPHONE_ARRAY_PROCESSOR KSCATEGORY_MICROPHONE_ARRAY_PROCESSOR - - # define STATIC_KSNODETYPE_DEV_SPECIFIC \ - 0x941C7AC0L, 0xC559, 0x11D0, 0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1 -DEFINE_GUIDSTRUCT("941C7AC0-C559-11D0-8A2B-00A0C9255AC1", KSNODETYPE_DEV_SPECIFIC); - # define KSNODETYPE_DEV_SPECIFIC DEFINE_GUIDNAMED(KSNODETYPE_DEV_SPECIFIC) - - # define STATIC_KSNODETYPE_PROLOGIC_ENCODER \ - 0x8074C5B2L, 0x3C66, 0x11D2, 0xB4, 0x5A, 0x30, 0x78, 0x30, 0x2C, 0x20, 0x30 -DEFINE_GUIDSTRUCT("8074C5B2-3C66-11D2-B45A-3078302C2030", KSNODETYPE_PROLOGIC_ENCODER); - # define KSNODETYPE_PROLOGIC_ENCODER DEFINE_GUIDNAMED(KSNODETYPE_PROLOGIC_ENCODER) - # define KSNODETYPE_SURROUND_ENCODER KSNODETYPE_PROLOGIC_ENCODER - - # define STATIC_KSNODETYPE_PEAKMETER \ - 0xa085651eL, 0x5f0d, 0x4b36, 0xa8, 0x69, 0xd1, 0x95, 0xd6, 0xab, 0x4b, 0x9e -DEFINE_GUIDSTRUCT("A085651E-5F0D-4b36-A869-D195D6AB4B9E", KSNODETYPE_PEAKMETER); - # define KSNODETYPE_PEAKMETER DEFINE_GUIDNAMED(KSNODETYPE_PEAKMETER) - - # define STATIC_KSAUDFNAME_BASS \ - 0x185FEDE0L, 0x9905, 0x11D1, 0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3 -DEFINE_GUIDSTRUCT("185FEDE0-9905-11D1-95A9-00C04FB925D3", KSAUDFNAME_BASS); - # define KSAUDFNAME_BASS DEFINE_GUIDNAMED(KSAUDFNAME_BASS) - - # define STATIC_KSAUDFNAME_TREBLE \ - 0x185FEDE1L, 0x9905, 0x11D1, 0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3 -DEFINE_GUIDSTRUCT("185FEDE1-9905-11D1-95A9-00C04FB925D3", KSAUDFNAME_TREBLE); - # define KSAUDFNAME_TREBLE DEFINE_GUIDNAMED(KSAUDFNAME_TREBLE) - - # define STATIC_KSAUDFNAME_3D_STEREO \ - 0x185FEDE2L, 0x9905, 0x11D1, 0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3 -DEFINE_GUIDSTRUCT("185FEDE2-9905-11D1-95A9-00C04FB925D3", KSAUDFNAME_3D_STEREO); - # define KSAUDFNAME_3D_STEREO DEFINE_GUIDNAMED(KSAUDFNAME_3D_STEREO) - - # define STATIC_KSAUDFNAME_MASTER_VOLUME \ - 0x185FEDE3L, 0x9905, 0x11D1, 0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3 -DEFINE_GUIDSTRUCT("185FEDE3-9905-11D1-95A9-00C04FB925D3", KSAUDFNAME_MASTER_VOLUME); - # define KSAUDFNAME_MASTER_VOLUME DEFINE_GUIDNAMED(KSAUDFNAME_MASTER_VOLUME) - - # define STATIC_KSAUDFNAME_MASTER_MUTE \ - 0x185FEDE4L, 0x9905, 0x11D1, 0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3 -DEFINE_GUIDSTRUCT("185FEDE4-9905-11D1-95A9-00C04FB925D3", KSAUDFNAME_MASTER_MUTE); - # define KSAUDFNAME_MASTER_MUTE DEFINE_GUIDNAMED(KSAUDFNAME_MASTER_MUTE) - - # define STATIC_KSAUDFNAME_WAVE_VOLUME \ - 0x185FEDE5L, 0x9905, 0x11D1, 0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3 -DEFINE_GUIDSTRUCT("185FEDE5-9905-11D1-95A9-00C04FB925D3", KSAUDFNAME_WAVE_VOLUME); - # define KSAUDFNAME_WAVE_VOLUME DEFINE_GUIDNAMED(KSAUDFNAME_WAVE_VOLUME) - - # define STATIC_KSAUDFNAME_WAVE_MUTE \ - 0x185FEDE6L, 0x9905, 0x11D1, 0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3 -DEFINE_GUIDSTRUCT("185FEDE6-9905-11D1-95A9-00C04FB925D3", KSAUDFNAME_WAVE_MUTE); - # define KSAUDFNAME_WAVE_MUTE DEFINE_GUIDNAMED(KSAUDFNAME_WAVE_MUTE) - - # define STATIC_KSAUDFNAME_MIDI_VOLUME \ - 0x185FEDE7L, 0x9905, 0x11D1, 0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3 -DEFINE_GUIDSTRUCT("185FEDE7-9905-11D1-95A9-00C04FB925D3", KSAUDFNAME_MIDI_VOLUME); - # define KSAUDFNAME_MIDI_VOLUME DEFINE_GUIDNAMED(KSAUDFNAME_MIDI_VOLUME) - - # define STATIC_KSAUDFNAME_MIDI_MUTE \ - 0x185FEDE8L, 0x9905, 0x11D1, 0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3 -DEFINE_GUIDSTRUCT("185FEDE8-9905-11D1-95A9-00C04FB925D3", KSAUDFNAME_MIDI_MUTE); - # define KSAUDFNAME_MIDI_MUTE DEFINE_GUIDNAMED(KSAUDFNAME_MIDI_MUTE) - - # define STATIC_KSAUDFNAME_CD_VOLUME \ - 0x185FEDE9L, 0x9905, 0x11D1, 0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3 -DEFINE_GUIDSTRUCT("185FEDE9-9905-11D1-95A9-00C04FB925D3", KSAUDFNAME_CD_VOLUME); - # define KSAUDFNAME_CD_VOLUME DEFINE_GUIDNAMED(KSAUDFNAME_CD_VOLUME) - - # define STATIC_KSAUDFNAME_CD_MUTE \ - 0x185FEDEAL, 0x9905, 0x11D1, 0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3 -DEFINE_GUIDSTRUCT("185FEDEA-9905-11D1-95A9-00C04FB925D3", KSAUDFNAME_CD_MUTE); - # define KSAUDFNAME_CD_MUTE DEFINE_GUIDNAMED(KSAUDFNAME_CD_MUTE) - - # define STATIC_KSAUDFNAME_LINE_VOLUME \ - 0x185FEDEBL, 0x9905, 0x11D1, 0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3 -DEFINE_GUIDSTRUCT("185FEDEB-9905-11D1-95A9-00C04FB925D3", KSAUDFNAME_LINE_VOLUME); - # define KSAUDFNAME_LINE_VOLUME DEFINE_GUIDNAMED(KSAUDFNAME_LINE_VOLUME) - - # define STATIC_KSAUDFNAME_LINE_MUTE \ - 0x185FEDECL, 0x9905, 0x11D1, 0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3 -DEFINE_GUIDSTRUCT("185FEDEC-9905-11D1-95A9-00C04FB925D3", KSAUDFNAME_LINE_MUTE); - # define KSAUDFNAME_LINE_MUTE DEFINE_GUIDNAMED(KSAUDFNAME_LINE_MUTE) - - # define STATIC_KSAUDFNAME_MIC_VOLUME \ - 0x185FEDEDL, 0x9905, 0x11D1, 0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3 -DEFINE_GUIDSTRUCT("185FEDED-9905-11D1-95A9-00C04FB925D3", KSAUDFNAME_MIC_VOLUME); - # define KSAUDFNAME_MIC_VOLUME DEFINE_GUIDNAMED(KSAUDFNAME_MIC_VOLUME) - - # define STATIC_KSAUDFNAME_MIC_MUTE \ - 0x185FEDEEL, 0x9905, 0x11D1, 0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3 -DEFINE_GUIDSTRUCT("185FEDEE-9905-11D1-95A9-00C04FB925D3", KSAUDFNAME_MIC_MUTE); - # define KSAUDFNAME_MIC_MUTE DEFINE_GUIDNAMED(KSAUDFNAME_MIC_MUTE) - - # define STATIC_KSAUDFNAME_RECORDING_SOURCE \ - 0x185FEDEFL, 0x9905, 0x11D1, 0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3 -DEFINE_GUIDSTRUCT("185FEDEF-9905-11D1-95A9-00C04FB925D3", KSAUDFNAME_RECORDING_SOURCE); - # define KSAUDFNAME_RECORDING_SOURCE DEFINE_GUIDNAMED(KSAUDFNAME_RECORDING_SOURCE) - - # define STATIC_KSAUDFNAME_PC_SPEAKER_VOLUME \ - 0x185FEDF0L, 0x9905, 0x11D1, 0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3 -DEFINE_GUIDSTRUCT("185FEDF0-9905-11D1-95A9-00C04FB925D3", KSAUDFNAME_PC_SPEAKER_VOLUME); - # define KSAUDFNAME_PC_SPEAKER_VOLUME DEFINE_GUIDNAMED(KSAUDFNAME_PC_SPEAKER_VOLUME) - - # define STATIC_KSAUDFNAME_PC_SPEAKER_MUTE \ - 0x185FEDF1L, 0x9905, 0x11D1, 0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3 -DEFINE_GUIDSTRUCT("185FEDF1-9905-11D1-95A9-00C04FB925D3", KSAUDFNAME_PC_SPEAKER_MUTE); - # define KSAUDFNAME_PC_SPEAKER_MUTE DEFINE_GUIDNAMED(KSAUDFNAME_PC_SPEAKER_MUTE) - - # define STATIC_KSAUDFNAME_MIDI_IN_VOLUME \ - 0x185FEDF2L, 0x9905, 0x11D1, 0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3 -DEFINE_GUIDSTRUCT("185FEDF2-9905-11D1-95A9-00C04FB925D3", KSAUDFNAME_MIDI_IN_VOLUME); - # define KSAUDFNAME_MIDI_IN_VOLUME DEFINE_GUIDNAMED(KSAUDFNAME_MIDI_IN_VOLUME) - - # define STATIC_KSAUDFNAME_CD_IN_VOLUME \ - 0x185FEDF3L, 0x9905, 0x11D1, 0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3 -DEFINE_GUIDSTRUCT("185FEDF3-9905-11D1-95A9-00C04FB925D3", KSAUDFNAME_CD_IN_VOLUME); - # define KSAUDFNAME_CD_IN_VOLUME DEFINE_GUIDNAMED(KSAUDFNAME_CD_IN_VOLUME) - - # define STATIC_KSAUDFNAME_LINE_IN_VOLUME \ - 0x185FEDF4L, 0x9905, 0x11D1, 0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3 -DEFINE_GUIDSTRUCT("185FEDF4-9905-11D1-95A9-00C04FB925D3", KSAUDFNAME_LINE_IN_VOLUME); - # define KSAUDFNAME_LINE_IN_VOLUME DEFINE_GUIDNAMED(KSAUDFNAME_LINE_IN_VOLUME) - - # define STATIC_KSAUDFNAME_MIC_IN_VOLUME \ - 0x185FEDF5L, 0x9905, 0x11D1, 0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3 -DEFINE_GUIDSTRUCT("185FEDF5-9905-11D1-95A9-00C04FB925D3", KSAUDFNAME_MIC_IN_VOLUME); - # define KSAUDFNAME_MIC_IN_VOLUME DEFINE_GUIDNAMED(KSAUDFNAME_MIC_IN_VOLUME) - - # define STATIC_KSAUDFNAME_WAVE_IN_VOLUME \ - 0x185FEDF6L, 0x9905, 0x11D1, 0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3 -DEFINE_GUIDSTRUCT("185FEDF6-9905-11D1-95A9-00C04FB925D3", KSAUDFNAME_WAVE_IN_VOLUME); - # define KSAUDFNAME_WAVE_IN_VOLUME DEFINE_GUIDNAMED(KSAUDFNAME_WAVE_IN_VOLUME) - - # define STATIC_KSAUDFNAME_VOLUME_CONTROL \ - 0x185FEDF7L, 0x9905, 0x11D1, 0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3 -DEFINE_GUIDSTRUCT("185FEDF7-9905-11D1-95A9-00C04FB925D3", KSAUDFNAME_VOLUME_CONTROL); - # define KSAUDFNAME_VOLUME_CONTROL DEFINE_GUIDNAMED(KSAUDFNAME_VOLUME_CONTROL) - - # define STATIC_KSAUDFNAME_MIDI \ - 0x185FEDF8L, 0x9905, 0x11D1, 0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3 -DEFINE_GUIDSTRUCT("185FEDF8-9905-11D1-95A9-00C04FB925D3", KSAUDFNAME_MIDI); - # define KSAUDFNAME_MIDI DEFINE_GUIDNAMED(KSAUDFNAME_MIDI) - - # define STATIC_KSAUDFNAME_LINE_IN \ - 0x185FEDF9L, 0x9905, 0x11D1, 0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3 -DEFINE_GUIDSTRUCT("185FEDF9-9905-11D1-95A9-00C04FB925D3", KSAUDFNAME_LINE_IN); - # define KSAUDFNAME_LINE_IN DEFINE_GUIDNAMED(KSAUDFNAME_LINE_IN) - - # define STATIC_KSAUDFNAME_RECORDING_CONTROL \ - 0x185FEDFAL, 0x9905, 0x11D1, 0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3 -DEFINE_GUIDSTRUCT("185FEDFA-9905-11D1-95A9-00C04FB925D3", KSAUDFNAME_RECORDING_CONTROL); - # define KSAUDFNAME_RECORDING_CONTROL DEFINE_GUIDNAMED(KSAUDFNAME_RECORDING_CONTROL) - - # define STATIC_KSAUDFNAME_CD_AUDIO \ - 0x185FEDFBL, 0x9905, 0x11D1, 0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3 -DEFINE_GUIDSTRUCT("185FEDFB-9905-11D1-95A9-00C04FB925D3", KSAUDFNAME_CD_AUDIO); - # define KSAUDFNAME_CD_AUDIO DEFINE_GUIDNAMED(KSAUDFNAME_CD_AUDIO) - - # define STATIC_KSAUDFNAME_AUX_VOLUME \ - 0x185FEDFCL, 0x9905, 0x11D1, 0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3 -DEFINE_GUIDSTRUCT("185FEDFC-9905-11D1-95A9-00C04FB925D3", KSAUDFNAME_AUX_VOLUME); - # define KSAUDFNAME_AUX_VOLUME DEFINE_GUIDNAMED(KSAUDFNAME_AUX_VOLUME) - - # define STATIC_KSAUDFNAME_AUX_MUTE \ - 0x185FEDFDL, 0x9905, 0x11D1, 0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3 -DEFINE_GUIDSTRUCT("185FEDFD-9905-11D1-95A9-00C04FB925D3", KSAUDFNAME_AUX_MUTE); - # define KSAUDFNAME_AUX_MUTE DEFINE_GUIDNAMED(KSAUDFNAME_AUX_MUTE) - - # define STATIC_KSAUDFNAME_AUX \ - 0x185FEDFEL, 0x9905, 0x11D1, 0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3 -DEFINE_GUIDSTRUCT("185FEDFE-9905-11D1-95A9-00C04FB925D3", KSAUDFNAME_AUX); - # define KSAUDFNAME_AUX DEFINE_GUIDNAMED(KSAUDFNAME_AUX) - - # define STATIC_KSAUDFNAME_PC_SPEAKER \ - 0x185FEDFFL, 0x9905, 0x11D1, 0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3 -DEFINE_GUIDSTRUCT("185FEDFF-9905-11D1-95A9-00C04FB925D3", KSAUDFNAME_PC_SPEAKER); - # define KSAUDFNAME_PC_SPEAKER DEFINE_GUIDNAMED(KSAUDFNAME_PC_SPEAKER) - - # define STATIC_KSAUDFNAME_WAVE_OUT_MIX \ - 0x185FEE00L, 0x9905, 0x11D1, 0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3 -DEFINE_GUIDSTRUCT("185FEE00-9905-11D1-95A9-00C04FB925D3", KSAUDFNAME_WAVE_OUT_MIX); - # define KSAUDFNAME_WAVE_OUT_MIX DEFINE_GUIDNAMED(KSAUDFNAME_WAVE_OUT_MIX) - - # define STATIC_KSAUDFNAME_MONO_OUT \ - 0xf9b41dc3L, 0x96e2, 0x11d2, 0xac, 0x4c, 0x0, 0xc0, 0x4f, 0x8e, 0xfb, 0x68 -DEFINE_GUIDSTRUCT("F9B41DC3-96E2-11d2-AC4C-00C04F8EFB68", KSAUDFNAME_MONO_OUT); - # define KSAUDFNAME_MONO_OUT DEFINE_GUIDNAMED(KSAUDFNAME_MONO_OUT) - - # define STATIC_KSAUDFNAME_STEREO_MIX \ - 0xdff077L, 0x96e3, 0x11d2, 0xac, 0x4c, 0x0, 0xc0, 0x4f, 0x8e, 0xfb, 0x68 -DEFINE_GUIDSTRUCT("00DFF077-96E3-11d2-AC4C-00C04F8EFB68", KSAUDFNAME_STEREO_MIX); - # define KSAUDFNAME_STEREO_MIX DEFINE_GUIDNAMED(KSAUDFNAME_STEREO_MIX) - - # define STATIC_KSAUDFNAME_MONO_MIX \ - 0xdff078L, 0x96e3, 0x11d2, 0xac, 0x4c, 0x0, 0xc0, 0x4f, 0x8e, 0xfb, 0x68 -DEFINE_GUIDSTRUCT("00DFF078-96E3-11d2-AC4C-00C04F8EFB68", KSAUDFNAME_MONO_MIX); - # define KSAUDFNAME_MONO_MIX DEFINE_GUIDNAMED(KSAUDFNAME_MONO_MIX) - - # define STATIC_KSAUDFNAME_MONO_OUT_VOLUME \ - 0x1ad247ebL, 0x96e3, 0x11d2, 0xac, 0x4c, 0x0, 0xc0, 0x4f, 0x8e, 0xfb, 0x68 -DEFINE_GUIDSTRUCT("1AD247EB-96E3-11d2-AC4C-00C04F8EFB68", KSAUDFNAME_MONO_OUT_VOLUME); - # define KSAUDFNAME_MONO_OUT_VOLUME DEFINE_GUIDNAMED(KSAUDFNAME_MONO_OUT_VOLUME) - - # define STATIC_KSAUDFNAME_MONO_OUT_MUTE \ - 0x1ad247ecL, 0x96e3, 0x11d2, 0xac, 0x4c, 0x0, 0xc0, 0x4f, 0x8e, 0xfb, 0x68 -DEFINE_GUIDSTRUCT("1AD247EC-96E3-11d2-AC4C-00C04F8EFB68", KSAUDFNAME_MONO_OUT_MUTE); - # define KSAUDFNAME_MONO_OUT_MUTE DEFINE_GUIDNAMED(KSAUDFNAME_MONO_OUT_MUTE) - - # define STATIC_KSAUDFNAME_STEREO_MIX_VOLUME \ - 0x1ad247edL, 0x96e3, 0x11d2, 0xac, 0x4c, 0x0, 0xc0, 0x4f, 0x8e, 0xfb, 0x68 -DEFINE_GUIDSTRUCT("1AD247ED-96E3-11d2-AC4C-00C04F8EFB68", KSAUDFNAME_STEREO_MIX_VOLUME); - # define KSAUDFNAME_STEREO_MIX_VOLUME DEFINE_GUIDNAMED(KSAUDFNAME_STEREO_MIX_VOLUME) - - # define STATIC_KSAUDFNAME_STEREO_MIX_MUTE \ - 0x22b0eafdL, 0x96e3, 0x11d2, 0xac, 0x4c, 0x0, 0xc0, 0x4f, 0x8e, 0xfb, 0x68 -DEFINE_GUIDSTRUCT("22B0EAFD-96E3-11d2-AC4C-00C04F8EFB68", KSAUDFNAME_STEREO_MIX_MUTE); - # define KSAUDFNAME_STEREO_MIX_MUTE DEFINE_GUIDNAMED(KSAUDFNAME_STEREO_MIX_MUTE) - - # define STATIC_KSAUDFNAME_MONO_MIX_VOLUME \ - 0x22b0eafeL, 0x96e3, 0x11d2, 0xac, 0x4c, 0x0, 0xc0, 0x4f, 0x8e, 0xfb, 0x68 -DEFINE_GUIDSTRUCT("22B0EAFE-96E3-11d2-AC4C-00C04F8EFB68", KSAUDFNAME_MONO_MIX_VOLUME); - # define KSAUDFNAME_MONO_MIX_VOLUME DEFINE_GUIDNAMED(KSAUDFNAME_MONO_MIX_VOLUME) - - # define STATIC_KSAUDFNAME_MONO_MIX_MUTE \ - 0x2bc31d69L, 0x96e3, 0x11d2, 0xac, 0x4c, 0x0, 0xc0, 0x4f, 0x8e, 0xfb, 0x68 -DEFINE_GUIDSTRUCT("2BC31D69-96E3-11d2-AC4C-00C04F8EFB68", KSAUDFNAME_MONO_MIX_MUTE); - # define KSAUDFNAME_MONO_MIX_MUTE DEFINE_GUIDNAMED(KSAUDFNAME_MONO_MIX_MUTE) - - # define STATIC_KSAUDFNAME_MICROPHONE_BOOST \ - 0x2bc31d6aL, 0x96e3, 0x11d2, 0xac, 0x4c, 0x0, 0xc0, 0x4f, 0x8e, 0xfb, 0x68 -DEFINE_GUIDSTRUCT("2BC31D6A-96E3-11d2-AC4C-00C04F8EFB68", KSAUDFNAME_MICROPHONE_BOOST); - # define KSAUDFNAME_MICROPHONE_BOOST DEFINE_GUIDNAMED(KSAUDFNAME_MICROPHONE_BOOST) - - # define STATIC_KSAUDFNAME_ALTERNATE_MICROPHONE \ - 0x2bc31d6bL, 0x96e3, 0x11d2, 0xac, 0x4c, 0x0, 0xc0, 0x4f, 0x8e, 0xfb, 0x68 -DEFINE_GUIDSTRUCT("2BC31D6B-96E3-11d2-AC4C-00C04F8EFB68", KSAUDFNAME_ALTERNATE_MICROPHONE); - # define KSAUDFNAME_ALTERNATE_MICROPHONE DEFINE_GUIDNAMED(KSAUDFNAME_ALTERNATE_MICROPHONE) - - # define STATIC_KSAUDFNAME_3D_DEPTH \ - 0x63ff5747L, 0x991f, 0x11d2, 0xac, 0x4d, 0x0, 0xc0, 0x4f, 0x8e, 0xfb, 0x68 -DEFINE_GUIDSTRUCT("63FF5747-991F-11d2-AC4D-00C04F8EFB68", KSAUDFNAME_3D_DEPTH); - # define KSAUDFNAME_3D_DEPTH DEFINE_GUIDNAMED(KSAUDFNAME_3D_DEPTH) - - # define STATIC_KSAUDFNAME_3D_CENTER \ - 0x9f0670b4L, 0x991f, 0x11d2, 0xac, 0x4d, 0x0, 0xc0, 0x4f, 0x8e, 0xfb, 0x68 -DEFINE_GUIDSTRUCT("9F0670B4-991F-11d2-AC4D-00C04F8EFB68", KSAUDFNAME_3D_CENTER); - # define KSAUDFNAME_3D_CENTER DEFINE_GUIDNAMED(KSAUDFNAME_3D_CENTER) - - # define STATIC_KSAUDFNAME_VIDEO_VOLUME \ - 0x9b46e708L, 0x992a, 0x11d2, 0xac, 0x4d, 0x0, 0xc0, 0x4f, 0x8e, 0xfb, 0x68 -DEFINE_GUIDSTRUCT("9B46E708-992A-11d2-AC4D-00C04F8EFB68", KSAUDFNAME_VIDEO_VOLUME); - # define KSAUDFNAME_VIDEO_VOLUME DEFINE_GUIDNAMED(KSAUDFNAME_VIDEO_VOLUME) - - # define STATIC_KSAUDFNAME_VIDEO_MUTE \ - 0x9b46e709L, 0x992a, 0x11d2, 0xac, 0x4d, 0x0, 0xc0, 0x4f, 0x8e, 0xfb, 0x68 -DEFINE_GUIDSTRUCT("9B46E709-992A-11d2-AC4D-00C04F8EFB68", KSAUDFNAME_VIDEO_MUTE); - # define KSAUDFNAME_VIDEO_MUTE DEFINE_GUIDNAMED(KSAUDFNAME_VIDEO_MUTE) - - # define STATIC_KSAUDFNAME_VIDEO \ - 0x915daec4L, 0xa434, 0x11d2, 0xac, 0x52, 0x0, 0xc0, 0x4f, 0x8e, 0xfb, 0x68 -DEFINE_GUIDSTRUCT("915DAEC4-A434-11d2-AC52-00C04F8EFB68", KSAUDFNAME_VIDEO); - # define KSAUDFNAME_VIDEO DEFINE_GUIDNAMED(KSAUDFNAME_VIDEO) - - # define STATIC_KSAUDFNAME_PEAKMETER \ - 0x57e24340L, 0xfc5b, 0x4612, 0xa5, 0x62, 0x72, 0xb1, 0x1a, 0x29, 0xdf, 0xae -DEFINE_GUIDSTRUCT("57E24340-FC5B-4612-A562-72B11A29DFAE", KSAUDFNAME_PEAKMETER); - # define KSAUDFNAME_PEAKMETER DEFINE_GUIDNAMED(KSAUDFNAME_PEAKMETER) - - # define KSNODEPIN_STANDARD_IN 1 - # define KSNODEPIN_STANDARD_OUT 0 - - # define KSNODEPIN_SUM_MUX_IN 1 - # define KSNODEPIN_SUM_MUX_OUT 0 - - # define KSNODEPIN_DEMUX_IN 0 - # define KSNODEPIN_DEMUX_OUT 1 - - # define KSNODEPIN_AEC_RENDER_IN 1 - # define KSNODEPIN_AEC_RENDER_OUT 0 - # define KSNODEPIN_AEC_CAPTURE_IN 2 - # define KSNODEPIN_AEC_CAPTURE_OUT 3 - - # define STATIC_KSMETHODSETID_Wavetable \ - 0xDCEF31EBL, 0xD907, 0x11D0, 0x95, 0x83, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3 -DEFINE_GUIDSTRUCT("DCEF31EB-D907-11D0-9583-00C04FB925D3", KSMETHODSETID_Wavetable); - # define KSMETHODSETID_Wavetable DEFINE_GUIDNAMED(KSMETHODSETID_Wavetable) - -typedef enum -{ - KSMETHOD_WAVETABLE_WAVE_ALLOC, - KSMETHOD_WAVETABLE_WAVE_FREE, - KSMETHOD_WAVETABLE_WAVE_FIND, - KSMETHOD_WAVETABLE_WAVE_WRITE -}KSMETHOD_WAVETABLE; - -typedef struct -{ - KSIDENTIFIER Identifier; - ULONG Size; - WINBOOL Looped; - ULONG LoopPoint; - WINBOOL InROM; - KSDATAFORMAT Format; -}KSWAVETABLE_WAVE_DESC, * PKSWAVETABLE_WAVE_DESC; - - # define STATIC_KSPROPSETID_Acoustic_Echo_Cancel \ - 0xd7a4af8bL, 0x3dc1, 0x4902, 0x91, 0xea, 0x8a, 0x15, 0xc9, 0x0e, 0x05, 0xb2 -DEFINE_GUIDSTRUCT("D7A4AF8B-3DC1-4902-91EA-8A15C90E05B2", KSPROPSETID_Acoustic_Echo_Cancel); - # define KSPROPSETID_Acoustic_Echo_Cancel DEFINE_GUIDNAMED(KSPROPSETID_Acoustic_Echo_Cancel) - -typedef enum -{ - KSPROPERTY_AEC_NOISE_FILL_ENABLE = 0, - KSPROPERTY_AEC_STATUS, - KSPROPERTY_AEC_MODE -}KSPROPERTY_AEC; - - # define AEC_STATUS_FD_HISTORY_UNINITIALIZED 0x0 - # define AEC_STATUS_FD_HISTORY_CONTINUOUSLY_CONVERGED 0x1 - # define AEC_STATUS_FD_HISTORY_PREVIOUSLY_DIVERGED 0x2 - # define AEC_STATUS_FD_CURRENTLY_CONVERGED 0x8 - - # define AEC_MODE_PASS_THROUGH 0x0 - # define AEC_MODE_HALF_DUPLEX 0x1 - # define AEC_MODE_FULL_DUPLEX 0x2 - - # define STATIC_KSPROPSETID_Wave \ - 0x924e54b0L, 0x630f, 0x11cf, 0xad, 0xa7, 0x08, 0x00, 0x3e, 0x30, 0x49, 0x4a -DEFINE_GUIDSTRUCT("924e54b0-630f-11cf-ada7-08003e30494a", KSPROPSETID_Wave); - # define KSPROPSETID_Wave DEFINE_GUIDNAMED(KSPROPSETID_Wave) - -typedef enum -{ - KSPROPERTY_WAVE_COMPATIBLE_CAPABILITIES, - KSPROPERTY_WAVE_INPUT_CAPABILITIES, - KSPROPERTY_WAVE_OUTPUT_CAPABILITIES, - KSPROPERTY_WAVE_BUFFER, - KSPROPERTY_WAVE_FREQUENCY, - KSPROPERTY_WAVE_VOLUME, - KSPROPERTY_WAVE_PAN -}KSPROPERTY_WAVE; - -typedef struct -{ - ULONG ulDeviceType; -}KSWAVE_COMPATCAPS, * PKSWAVE_COMPATCAPS; - - # define KSWAVE_COMPATCAPS_INPUT 0x00000000 - # define KSWAVE_COMPATCAPS_OUTPUT 0x00000001 - -typedef struct -{ - ULONG MaximumChannelsPerConnection; - ULONG MinimumBitsPerSample; - ULONG MaximumBitsPerSample; - ULONG MinimumSampleFrequency; - ULONG MaximumSampleFrequency; - ULONG TotalConnections; - ULONG ActiveConnections; -}KSWAVE_INPUT_CAPABILITIES, * PKSWAVE_INPUT_CAPABILITIES; - -typedef struct -{ - ULONG MaximumChannelsPerConnection; - ULONG MinimumBitsPerSample; - ULONG MaximumBitsPerSample; - ULONG MinimumSampleFrequency; - ULONG MaximumSampleFrequency; - ULONG TotalConnections; - ULONG StaticConnections; - ULONG StreamingConnections; - ULONG ActiveConnections; - ULONG ActiveStaticConnections; - ULONG ActiveStreamingConnections; - ULONG Total3DConnections; - ULONG Static3DConnections; - ULONG Streaming3DConnections; - ULONG Active3DConnections; - ULONG ActiveStatic3DConnections; - ULONG ActiveStreaming3DConnections; - ULONG TotalSampleMemory; - ULONG FreeSampleMemory; - ULONG LargestFreeContiguousSampleMemory; -}KSWAVE_OUTPUT_CAPABILITIES, * PKSWAVE_OUTPUT_CAPABILITIES; - -typedef struct -{ - LONG LeftAttenuation; - LONG RightAttenuation; -}KSWAVE_VOLUME, * PKSWAVE_VOLUME; - - # define KSWAVE_BUFFER_ATTRIBUTEF_LOOPING 0x00000001 - # define KSWAVE_BUFFER_ATTRIBUTEF_STATIC 0x00000002 - -typedef struct -{ - ULONG Attributes; - ULONG BufferSize; - PVOID BufferAddress; -}KSWAVE_BUFFER, * PKSWAVE_BUFFER; - - # define STATIC_KSMUSIC_TECHNOLOGY_PORT \ - 0x86C92E60L, 0x62E8, 0x11CF, 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00 -DEFINE_GUIDSTRUCT("86C92E60-62E8-11CF-A5D6-28DB04C10000", KSMUSIC_TECHNOLOGY_PORT); - # define KSMUSIC_TECHNOLOGY_PORT DEFINE_GUIDNAMED(KSMUSIC_TECHNOLOGY_PORT) - - # define STATIC_KSMUSIC_TECHNOLOGY_SQSYNTH \ - 0x0ECF4380L, 0x62E9, 0x11CF, 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00 -DEFINE_GUIDSTRUCT("0ECF4380-62E9-11CF-A5D6-28DB04C10000", KSMUSIC_TECHNOLOGY_SQSYNTH); - # define KSMUSIC_TECHNOLOGY_SQSYNTH DEFINE_GUIDNAMED(KSMUSIC_TECHNOLOGY_SQSYNTH) - - # define STATIC_KSMUSIC_TECHNOLOGY_FMSYNTH \ - 0x252C5C80L, 0x62E9, 0x11CF, 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00 -DEFINE_GUIDSTRUCT("252C5C80-62E9-11CF-A5D6-28DB04C10000", KSMUSIC_TECHNOLOGY_FMSYNTH); - # define KSMUSIC_TECHNOLOGY_FMSYNTH DEFINE_GUIDNAMED(KSMUSIC_TECHNOLOGY_FMSYNTH) - - # define STATIC_KSMUSIC_TECHNOLOGY_WAVETABLE \ - 0x394EC7C0L, 0x62E9, 0x11CF, 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00 -DEFINE_GUIDSTRUCT("394EC7C0-62E9-11CF-A5D6-28DB04C10000", KSMUSIC_TECHNOLOGY_WAVETABLE); - # define KSMUSIC_TECHNOLOGY_WAVETABLE DEFINE_GUIDNAMED(KSMUSIC_TECHNOLOGY_WAVETABLE) - - # define STATIC_KSMUSIC_TECHNOLOGY_SWSYNTH \ - 0x37407736L, 0x3620, 0x11D1, 0x85, 0xD3, 0x00, 0x00, 0xF8, 0x75, 0x43, 0x80 -DEFINE_GUIDSTRUCT("37407736-3620-11D1-85D3-0000F8754380", KSMUSIC_TECHNOLOGY_SWSYNTH); - # define KSMUSIC_TECHNOLOGY_SWSYNTH DEFINE_GUIDNAMED(KSMUSIC_TECHNOLOGY_SWSYNTH) - - # define STATIC_KSPROPSETID_WaveTable \ - 0x8539E660L, 0x62E9, 0x11CF, 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00 -DEFINE_GUIDSTRUCT("8539E660-62E9-11CF-A5D6-28DB04C10000", KSPROPSETID_WaveTable); - # define KSPROPSETID_WaveTable DEFINE_GUIDNAMED(KSPROPSETID_WaveTable) - -typedef enum -{ - KSPROPERTY_WAVETABLE_LOAD_SAMPLE, - KSPROPERTY_WAVETABLE_UNLOAD_SAMPLE, - KSPROPERTY_WAVETABLE_MEMORY, - KSPROPERTY_WAVETABLE_VERSION -}KSPROPERTY_WAVETABLE; - -typedef struct -{ - KSDATARANGE DataRange; - GUID Technology; - ULONG Channels; - ULONG Notes; - ULONG ChannelMask; -}KSDATARANGE_MUSIC, * PKSDATARANGE_MUSIC; - - # define STATIC_KSEVENTSETID_Cyclic \ - 0x142C1AC0L, 0x072A, 0x11D0, 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00 -DEFINE_GUIDSTRUCT("142C1AC0-072A-11D0-A5D6-28DB04C10000", KSEVENTSETID_Cyclic); - # define KSEVENTSETID_Cyclic DEFINE_GUIDNAMED(KSEVENTSETID_Cyclic) - -typedef enum -{ - KSEVENT_CYCLIC_TIME_INTERVAL -}KSEVENT_CYCLIC_TIME; - - # define STATIC_KSPROPSETID_Cyclic \ - 0x3FFEAEA0L, 0x2BEE, 0x11CF, 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00 -DEFINE_GUIDSTRUCT("3FFEAEA0-2BEE-11CF-A5D6-28DB04C10000", KSPROPSETID_Cyclic); - # define KSPROPSETID_Cyclic DEFINE_GUIDNAMED(KSPROPSETID_Cyclic) - -typedef enum -{ - KSPROPERTY_CYCLIC_POSITION -}KSPROPERTY_CYCLIC; - - # define STATIC_KSEVENTSETID_AudioControlChange \ - 0xE85E9698L, 0xFA2F, 0x11D1, 0x95, 0xBD, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3 -DEFINE_GUIDSTRUCT("E85E9698-FA2F-11D1-95BD-00C04FB925D3", KSEVENTSETID_AudioControlChange); - # define KSEVENTSETID_AudioControlChange DEFINE_GUIDNAMED(KSEVENTSETID_AudioControlChange) - -typedef enum -{ - KSEVENT_CONTROL_CHANGE -}KSEVENT_AUDIO_CONTROL_CHANGE; - - # define STATIC_KSEVENTSETID_LoopedStreaming \ - 0x4682B940L, 0xC6EF, 0x11D0, 0x96, 0xD8, 0x00, 0xAA, 0x00, 0x51, 0xE5, 0x1D -DEFINE_GUIDSTRUCT("4682B940-C6EF-11D0-96D8-00AA0051E51D", KSEVENTSETID_LoopedStreaming); - # define KSEVENTSETID_LoopedStreaming DEFINE_GUIDNAMED(KSEVENTSETID_LoopedStreaming) - -typedef enum -{ - KSEVENT_LOOPEDSTREAMING_POSITION -}KSEVENT_LOOPEDSTREAMING; - -typedef struct -{ - KSEVENTDATA KsEventData; - DWORDLONG Position; -}LOOPEDSTREAMING_POSITION_EVENT_DATA, * PLOOPEDSTREAMING_POSITION_EVENT_DATA; - - # define STATIC_KSPROPSETID_Sysaudio \ - 0xCBE3FAA0L, 0xCC75, 0x11D0, 0xB4, 0x65, 0x00, 0x00, 0x1A, 0x18, 0x18, 0xE6 -DEFINE_GUIDSTRUCT("CBE3FAA0-CC75-11D0-B465-00001A1818E6", KSPROPSETID_Sysaudio); - # define KSPROPSETID_Sysaudio DEFINE_GUIDNAMED(KSPROPSETID_Sysaudio) - -typedef enum -{ - KSPROPERTY_SYSAUDIO_DEVICE_COUNT = 1, - KSPROPERTY_SYSAUDIO_DEVICE_FRIENDLY_NAME = 2, - KSPROPERTY_SYSAUDIO_DEVICE_INSTANCE = 3, - KSPROPERTY_SYSAUDIO_DEVICE_INTERFACE_NAME = 4, - KSPROPERTY_SYSAUDIO_SELECT_GRAPH = 5, - KSPROPERTY_SYSAUDIO_CREATE_VIRTUAL_SOURCE = 6, - KSPROPERTY_SYSAUDIO_DEVICE_DEFAULT = 7, - KSPROPERTY_SYSAUDIO_INSTANCE_INFO = 14, - KSPROPERTY_SYSAUDIO_COMPONENT_ID = 16 -}KSPROPERTY_SYSAUDIO; - -typedef struct -{ - KSPROPERTY Property; - GUID PinCategory; - GUID PinName; -}SYSAUDIO_CREATE_VIRTUAL_SOURCE, * PSYSAUDIO_CREATE_VIRTUAL_SOURCE; - -typedef struct -{ - KSPROPERTY Property; - ULONG PinId; - ULONG NodeId; - ULONG Flags; - ULONG Reserved; -}SYSAUDIO_SELECT_GRAPH, * PSYSAUDIO_SELECT_GRAPH; - -typedef struct -{ - KSPROPERTY Property; - ULONG Flags; - ULONG DeviceNumber; -}SYSAUDIO_INSTANCE_INFO, * PSYSAUDIO_INSTANCE_INFO; - - # define SYSAUDIO_FLAGS_DONT_COMBINE_PINS 0x00000001 - - # define STATIC_KSPROPSETID_Sysaudio_Pin \ - 0xA3A53220L, 0xC6E4, 0x11D0, 0xB4, 0x65, 0x00, 0x00, 0x1A, 0x18, 0x18, 0xE6 -DEFINE_GUIDSTRUCT("A3A53220-C6E4-11D0-B465-00001A1818E6", KSPROPSETID_Sysaudio_Pin); - # define KSPROPSETID_Sysaudio_Pin DEFINE_GUIDNAMED(KSPROPSETID_Sysaudio_Pin) - -typedef enum -{ - KSPROPERTY_SYSAUDIO_ATTACH_VIRTUAL_SOURCE = 1 -}KSPROPERTY_SYSAUDIO_PIN; - -typedef struct -{ - KSPROPERTY Property; - ULONG MixerPinId; - ULONG Reserved; -}SYSAUDIO_ATTACH_VIRTUAL_SOURCE, * PSYSAUDIO_ATTACH_VIRTUAL_SOURCE; - -typedef struct -{ - KSPROPERTY Property; - ULONG NodeId; - ULONG Reserved; -}KSNODEPROPERTY, * PKSNODEPROPERTY; - -typedef struct -{ - KSNODEPROPERTY NodeProperty; - LONG Channel; - ULONG Reserved; -}KSNODEPROPERTY_AUDIO_CHANNEL, * PKSNODEPROPERTY_AUDIO_CHANNEL; - -typedef struct -{ - KSNODEPROPERTY NodeProperty; - ULONG DevSpecificId; - ULONG DeviceInfo; - ULONG Length; -}KSNODEPROPERTY_AUDIO_DEV_SPECIFIC, * PKSNODEPROPERTY_AUDIO_DEV_SPECIFIC; - -typedef struct -{ - KSNODEPROPERTY NodeProperty; - PVOID ListenerId; - # ifndef _WIN64 - ULONG Reserved; - # endif -}KSNODEPROPERTY_AUDIO_3D_LISTENER, * PKSNODEPROPERTY_AUDIO_3D_LISTENER; - -typedef struct -{ - KSNODEPROPERTY NodeProperty; - PVOID AppContext; - ULONG Length; - # ifndef _WIN64 - ULONG Reserved; - # endif -}KSNODEPROPERTY_AUDIO_PROPERTY, * PKSNODEPROPERTY_AUDIO_PROPERTY; - - # define STATIC_KSPROPSETID_AudioGfx \ - 0x79a9312eL, 0x59ae, 0x43b0, 0xa3, 0x50, 0x8b, 0x5, 0x28, 0x4c, 0xab, 0x24 -DEFINE_GUIDSTRUCT("79A9312E-59AE-43b0-A350-8B05284CAB24", KSPROPSETID_AudioGfx); - # define KSPROPSETID_AudioGfx DEFINE_GUIDNAMED(KSPROPSETID_AudioGfx) - -typedef enum -{ - KSPROPERTY_AUDIOGFX_RENDERTARGETDEVICEID, - KSPROPERTY_AUDIOGFX_CAPTURETARGETDEVICEID -}KSPROPERTY_AUDIOGFX; - - # define STATIC_KSPROPSETID_Linear \ - 0x5A2FFE80L, 0x16B9, 0x11D0, 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00 -DEFINE_GUIDSTRUCT("5A2FFE80-16B9-11D0-A5D6-28DB04C10000", KSPROPSETID_Linear); - # define KSPROPSETID_Linear DEFINE_GUIDNAMED(KSPROPSETID_Linear) - -typedef enum -{ - KSPROPERTY_LINEAR_POSITION -}KSPROPERTY_LINEAR; - - # define STATIC_KSDATAFORMAT_TYPE_MUSIC \ - 0xE725D360L, 0x62CC, 0x11CF, { 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00 } -DEFINE_GUIDSTRUCT("E725D360-62CC-11CF-A5D6-28DB04C10000", KSDATAFORMAT_TYPE_MUSIC); - # define KSDATAFORMAT_TYPE_MUSIC DEFINE_GUIDNAMED(KSDATAFORMAT_TYPE_MUSIC) - - # define STATIC_KSDATAFORMAT_TYPE_MIDI \ - 0x7364696DL, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 -DEFINE_GUIDSTRUCT("7364696D-0000-0010-8000-00aa00389b71", KSDATAFORMAT_TYPE_MIDI); - # define KSDATAFORMAT_TYPE_MIDI DEFINE_GUIDNAMED(KSDATAFORMAT_TYPE_MIDI) - - # define STATIC_KSDATAFORMAT_SUBTYPE_MIDI \ - 0x1D262760L, 0xE957, 0x11CF, { 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00 } -DEFINE_GUIDSTRUCT("1D262760-E957-11CF-A5D6-28DB04C10000", KSDATAFORMAT_SUBTYPE_MIDI); - # define KSDATAFORMAT_SUBTYPE_MIDI DEFINE_GUIDNAMED(KSDATAFORMAT_SUBTYPE_MIDI) - - # define STATIC_KSDATAFORMAT_SUBTYPE_MIDI_BUS \ - 0x2CA15FA0L, 0x6CFE, 0x11CF, 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00 -DEFINE_GUIDSTRUCT("2CA15FA0-6CFE-11CF-A5D6-28DB04C10000", KSDATAFORMAT_SUBTYPE_MIDI_BUS); - # define KSDATAFORMAT_SUBTYPE_MIDI_BUS DEFINE_GUIDNAMED(KSDATAFORMAT_SUBTYPE_MIDI_BUS) - - # define STATIC_KSDATAFORMAT_SUBTYPE_RIFFMIDI \ - 0x4995DAF0L, 0x9EE6, 0x11D0, 0xA4, 0x0E, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96 -DEFINE_GUIDSTRUCT("4995DAF0-9EE6-11D0-A40E-00A0C9223196", KSDATAFORMAT_SUBTYPE_RIFFMIDI); - # define KSDATAFORMAT_SUBTYPE_RIFFMIDI DEFINE_GUIDNAMED(KSDATAFORMAT_SUBTYPE_RIFFMIDI) - -typedef struct -{ - ULONG TimeDeltaMs; - - ULONG ByteCount; -}KSMUSICFORMAT, * PKSMUSICFORMAT; - - # define STATIC_KSDATAFORMAT_TYPE_STANDARD_ELEMENTARY_STREAM \ - 0x36523b11L, 0x8ee5, 0x11d1, 0x8c, 0xa3, 0x00, 0x60, 0xb0, 0x57, 0x66, 0x4a -DEFINE_GUIDSTRUCT("36523B11-8EE5-11d1-8CA3-0060B057664A", KSDATAFORMAT_TYPE_STANDARD_ELEMENTARY_STREAM); - # define KSDATAFORMAT_TYPE_STANDARD_ELEMENTARY_STREAM DEFINE_GUIDNAMED(KSDATAFORMAT_TYPE_STANDARD_ELEMENTARY_STREAM) - - # define STATIC_KSDATAFORMAT_TYPE_STANDARD_PES_PACKET \ - 0x36523b12L, 0x8ee5, 0x11d1, 0x8c, 0xa3, 0x00, 0x60, 0xb0, 0x57, 0x66, 0x4a -DEFINE_GUIDSTRUCT("36523B12-8EE5-11d1-8CA3-0060B057664A", KSDATAFORMAT_TYPE_STANDARD_PES_PACKET); - # define KSDATAFORMAT_TYPE_STANDARD_PES_PACKET DEFINE_GUIDNAMED(KSDATAFORMAT_TYPE_STANDARD_PES_PACKET) - - # define STATIC_KSDATAFORMAT_TYPE_STANDARD_PACK_HEADER \ - 0x36523b13L, 0x8ee5, 0x11d1, 0x8c, 0xa3, 0x00, 0x60, 0xb0, 0x57, 0x66, 0x4a -DEFINE_GUIDSTRUCT("36523B13-8EE5-11d1-8CA3-0060B057664A", KSDATAFORMAT_TYPE_STANDARD_PACK_HEADER); - # define KSDATAFORMAT_TYPE_STANDARD_PACK_HEADER DEFINE_GUIDNAMED(KSDATAFORMAT_TYPE_STANDARD_PACK_HEADER) - - # define STATIC_KSDATAFORMAT_SUBTYPE_STANDARD_MPEG1_VIDEO \ - 0x36523b21L, 0x8ee5, 0x11d1, 0x8c, 0xa3, 0x00, 0x60, 0xb0, 0x57, 0x66, 0x4a -DEFINE_GUIDSTRUCT("36523B21-8EE5-11d1-8CA3-0060B057664A", KSDATAFORMAT_SUBTYPE_STANDARD_MPEG1_VIDEO); - # define KSDATAFORMAT_SUBTYPE_STANDARD_MPEG1_VIDEO DEFINE_GUIDNAMED(KSDATAFORMAT_SUBTYPE_STANDARD_MPEG1_VIDEO) - - # define STATIC_KSDATAFORMAT_SUBTYPE_STANDARD_MPEG1_AUDIO \ - 0x36523b22L, 0x8ee5, 0x11d1, 0x8c, 0xa3, 0x00, 0x60, 0xb0, 0x57, 0x66, 0x4a -DEFINE_GUIDSTRUCT("36523B22-8EE5-11d1-8CA3-0060B057664A", KSDATAFORMAT_SUBTYPE_STANDARD_MPEG1_AUDIO); - # define KSDATAFORMAT_SUBTYPE_STANDARD_MPEG1_AUDIO DEFINE_GUIDNAMED(KSDATAFORMAT_SUBTYPE_STANDARD_MPEG1_AUDIO) - - # define STATIC_KSDATAFORMAT_SUBTYPE_STANDARD_MPEG2_VIDEO \ - 0x36523b23L, 0x8ee5, 0x11d1, 0x8c, 0xa3, 0x00, 0x60, 0xb0, 0x57, 0x66, 0x4a -DEFINE_GUIDSTRUCT("36523B23-8EE5-11d1-8CA3-0060B057664A", KSDATAFORMAT_SUBTYPE_STANDARD_MPEG2_VIDEO); - # define KSDATAFORMAT_SUBTYPE_STANDARD_MPEG2_VIDEO DEFINE_GUIDNAMED(KSDATAFORMAT_SUBTYPE_STANDARD_MPEG2_VIDEO) - - # define STATIC_KSDATAFORMAT_SUBTYPE_STANDARD_MPEG2_AUDIO \ - 0x36523b24L, 0x8ee5, 0x11d1, 0x8c, 0xa3, 0x00, 0x60, 0xb0, 0x57, 0x66, 0x4a -DEFINE_GUIDSTRUCT("36523B24-8EE5-11d1-8CA3-0060B057664A", KSDATAFORMAT_SUBTYPE_STANDARD_MPEG2_AUDIO); - # define KSDATAFORMAT_SUBTYPE_STANDARD_MPEG2_AUDIO DEFINE_GUIDNAMED(KSDATAFORMAT_SUBTYPE_STANDARD_MPEG2_AUDIO) - - # define STATIC_KSDATAFORMAT_SUBTYPE_STANDARD_AC3_AUDIO \ - 0x36523b25L, 0x8ee5, 0x11d1, 0x8c, 0xa3, 0x00, 0x60, 0xb0, 0x57, 0x66, 0x4a -DEFINE_GUIDSTRUCT("36523B25-8EE5-11d1-8CA3-0060B057664A", KSDATAFORMAT_SUBTYPE_STANDARD_AC3_AUDIO); - # define KSDATAFORMAT_SUBTYPE_STANDARD_AC3_AUDIO DEFINE_GUIDNAMED(KSDATAFORMAT_SUBTYPE_STANDARD_AC3_AUDIO) - - # define STATIC_KSDATAFORMAT_SPECIFIER_DIALECT_MPEG1_VIDEO \ - 0x36523b31L, 0x8ee5, 0x11d1, 0x8c, 0xa3, 0x00, 0x60, 0xb0, 0x57, 0x66, 0x4a -DEFINE_GUIDSTRUCT("36523B31-8EE5-11d1-8CA3-0060B057664A", KSDATAFORMAT_SPECIFIER_DIALECT_MPEG1_VIDEO); - # define KSDATAFORMAT_SPECIFIER_DIALECT_MPEG1_VIDEO DEFINE_GUIDNAMED(KSDATAFORMAT_SPECIFIER_DIALECT_MPEG1_VIDEO) - - # define STATIC_KSDATAFORMAT_SPECIFIER_DIALECT_MPEG1_AUDIO \ - 0x36523b32L, 0x8ee5, 0x11d1, 0x8c, 0xa3, 0x00, 0x60, 0xb0, 0x57, 0x66, 0x4a -DEFINE_GUIDSTRUCT("36523B32-8EE5-11d1-8CA3-0060B057664A", KSDATAFORMAT_SPECIFIER_DIALECT_MPEG1_AUDIO); - # define KSDATAFORMAT_SPECIFIER_DIALECT_MPEG1_AUDIO DEFINE_GUIDNAMED(KSDATAFORMAT_SPECIFIER_DIALECT_MPEG1_AUDIO) - - # define STATIC_KSDATAFORMAT_SPECIFIER_DIALECT_MPEG2_VIDEO \ - 0x36523b33L, 0x8ee5, 0x11d1, 0x8c, 0xa3, 0x00, 0x60, 0xb0, 0x57, 0x66, 0x4a -DEFINE_GUIDSTRUCT("36523B33-8EE5-11d1-8CA3-0060B057664A", KSDATAFORMAT_SPECIFIER_DIALECT_MPEG2_VIDEO); - # define KSDATAFORMAT_SPECIFIER_DIALECT_MPEG2_VIDEO DEFINE_GUIDNAMED(KSDATAFORMAT_SPECIFIER_DIALECT_MPEG2_VIDEO) - - # define STATIC_KSDATAFORMAT_SPECIFIER_DIALECT_MPEG2_AUDIO \ - 0x36523b34L, 0x8ee5, 0x11d1, 0x8c, 0xa3, 0x00, 0x60, 0xb0, 0x57, 0x66, 0x4a -DEFINE_GUIDSTRUCT("36523B34-8EE5-11d1-8CA3-0060B057664A", KSDATAFORMAT_SPECIFIER_DIALECT_MPEG2_AUDIO); - # define KSDATAFORMAT_SPECIFIER_DIALECT_MPEG2_AUDIO DEFINE_GUIDNAMED(KSDATAFORMAT_SPECIFIER_DIALECT_MPEG2_AUDIO) - - # define STATIC_KSDATAFORMAT_SPECIFIER_DIALECT_AC3_AUDIO \ - 0x36523b35L, 0x8ee5, 0x11d1, 0x8c, 0xa3, 0x00, 0x60, 0xb0, 0x57, 0x66, 0x4a -DEFINE_GUIDSTRUCT("36523B35-8EE5-11d1-8CA3-0060B057664A", KSDATAFORMAT_SPECIFIER_DIALECT_AC3_AUDIO); - # define KSDATAFORMAT_SPECIFIER_DIALECT_AC3_AUDIO DEFINE_GUIDNAMED(KSDATAFORMAT_SPECIFIER_DIALECT_AC3_AUDIO) - - # define STATIC_KSDATAFORMAT_SUBTYPE_DSS_VIDEO \ - 0xa0af4f81L, 0xe163, 0x11d0, 0xba, 0xd9, 0x00, 0x60, 0x97, 0x44, 0x11, 0x1a -DEFINE_GUIDSTRUCT("a0af4f81-e163-11d0-bad9-00609744111a", KSDATAFORMAT_SUBTYPE_DSS_VIDEO); - # define KSDATAFORMAT_SUBTYPE_DSS_VIDEO DEFINE_GUIDNAMED(KSDATAFORMAT_SUBTYPE_DSS_VIDEO) - - # define STATIC_KSDATAFORMAT_SUBTYPE_DSS_AUDIO \ - 0xa0af4f82L, 0xe163, 0x11d0, 0xba, 0xd9, 0x00, 0x60, 0x97, 0x44, 0x11, 0x1a -DEFINE_GUIDSTRUCT("a0af4f82-e163-11d0-bad9-00609744111a", KSDATAFORMAT_SUBTYPE_DSS_AUDIO); - # define KSDATAFORMAT_SUBTYPE_DSS_AUDIO DEFINE_GUIDNAMED(KSDATAFORMAT_SUBTYPE_DSS_AUDIO) - - # define STATIC_KSDATAFORMAT_SUBTYPE_MPEG1Packet \ - 0xe436eb80, 0x524f, 0x11ce, 0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70 -DEFINE_GUIDSTRUCT("e436eb80-524f-11ce-9F53-0020af0ba770", KSDATAFORMAT_SUBTYPE_MPEG1Packet); - # define KSDATAFORMAT_SUBTYPE_MPEG1Packet DEFINE_GUIDNAMED(KSDATAFORMAT_SUBTYPE_MPEG1Packet) - - # define STATIC_KSDATAFORMAT_SUBTYPE_MPEG1Payload \ - 0xe436eb81, 0x524f, 0x11ce, 0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70 -DEFINE_GUIDSTRUCT("e436eb81-524f-11ce-9F53-0020af0ba770", KSDATAFORMAT_SUBTYPE_MPEG1Payload); - # define KSDATAFORMAT_SUBTYPE_MPEG1Payload DEFINE_GUIDNAMED(KSDATAFORMAT_SUBTYPE_MPEG1Payload) - - # define STATIC_KSDATAFORMAT_SUBTYPE_MPEG1Video \ - 0xe436eb86, 0x524f, 0x11ce, 0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70 -DEFINE_GUIDSTRUCT("e436eb86-524f-11ce-9f53-0020af0ba770", KSDATAFORMAT_SUBTYPE_MPEG1Video); - # define KSDATAFORMAT_SUBTYPE_MPEG1Video DEFINE_GUIDNAMED(KSDATAFORMAT_SUBTYPE_MPEG1Video) - - # define STATIC_KSDATAFORMAT_SPECIFIER_MPEG1_VIDEO \ - 0x05589f82L, 0xc356, 0x11ce, 0xbf, 0x01, 0x00, 0xaa, 0x00, 0x55, 0x59, 0x5a -DEFINE_GUIDSTRUCT("05589f82-c356-11ce-bf01-00aa0055595a", KSDATAFORMAT_SPECIFIER_MPEG1_VIDEO); - # define KSDATAFORMAT_SPECIFIER_MPEG1_VIDEO DEFINE_GUIDNAMED(KSDATAFORMAT_SPECIFIER_MPEG1_VIDEO) - - # define STATIC_KSDATAFORMAT_TYPE_MPEG2_PES \ - 0xe06d8020L, 0xdb46, 0x11cf, 0xb4, 0xd1, 0x00, 0x80, 0x5f, 0x6c, 0xbb, 0xea -DEFINE_GUIDSTRUCT("e06d8020-db46-11cf-b4d1-00805f6cbbea", KSDATAFORMAT_TYPE_MPEG2_PES); - # define KSDATAFORMAT_TYPE_MPEG2_PES DEFINE_GUIDNAMED(KSDATAFORMAT_TYPE_MPEG2_PES) - - # define STATIC_KSDATAFORMAT_TYPE_MPEG2_PROGRAM \ - 0xe06d8022L, 0xdb46, 0x11cf, 0xb4, 0xd1, 0x00, 0x80, 0x5f, 0x6c, 0xbb, 0xea -DEFINE_GUIDSTRUCT("e06d8022-db46-11cf-b4d1-00805f6cbbea", KSDATAFORMAT_TYPE_MPEG2_PROGRAM); - # define KSDATAFORMAT_TYPE_MPEG2_PROGRAM DEFINE_GUIDNAMED(KSDATAFORMAT_TYPE_MPEG2_PROGRAM) - - # define STATIC_KSDATAFORMAT_TYPE_MPEG2_TRANSPORT \ - 0xe06d8023L, 0xdb46, 0x11cf, 0xb4, 0xd1, 0x00, 0x80, 0x5f, 0x6c, 0xbb, 0xea -DEFINE_GUIDSTRUCT("e06d8023-db46-11cf-b4d1-00805f6cbbea", KSDATAFORMAT_TYPE_MPEG2_TRANSPORT); - # define KSDATAFORMAT_TYPE_MPEG2_TRANSPORT DEFINE_GUIDNAMED(KSDATAFORMAT_TYPE_MPEG2_TRANSPORT) - - # define STATIC_KSDATAFORMAT_SUBTYPE_MPEG2_VIDEO \ - 0xe06d8026L, 0xdb46, 0x11cf, 0xb4, 0xd1, 0x00, 0x80, 0x5f, 0x6c, 0xbb, 0xea -DEFINE_GUIDSTRUCT("e06d8026-db46-11cf-b4d1-00805f6cbbea", KSDATAFORMAT_SUBTYPE_MPEG2_VIDEO); - # define KSDATAFORMAT_SUBTYPE_MPEG2_VIDEO DEFINE_GUIDNAMED(KSDATAFORMAT_SUBTYPE_MPEG2_VIDEO) - - # define STATIC_KSDATAFORMAT_SPECIFIER_MPEG2_VIDEO \ - 0xe06d80e3L, 0xdb46, 0x11cf, 0xb4, 0xd1, 0x00, 0x80, 0x5f, 0x6c, 0xbb, 0xea -DEFINE_GUIDSTRUCT("e06d80e3-db46-11cf-b4d1-00805f6cbbea", KSDATAFORMAT_SPECIFIER_MPEG2_VIDEO); - # define KSDATAFORMAT_SPECIFIER_MPEG2_VIDEO DEFINE_GUIDNAMED(KSDATAFORMAT_SPECIFIER_MPEG2_VIDEO) - - # define STATIC_KSPROPSETID_Mpeg2Vid \ - 0xC8E11B60L, 0x0CC9, 0x11D0, 0xBD, 0x69, 0x00, 0x35, 0x05, 0xC1, 0x03, 0xA9 -DEFINE_GUIDSTRUCT("C8E11B60-0CC9-11D0-BD69-003505C103A9", KSPROPSETID_Mpeg2Vid); - # define KSPROPSETID_Mpeg2Vid DEFINE_GUIDNAMED(KSPROPSETID_Mpeg2Vid) - -typedef enum -{ - KSPROPERTY_MPEG2VID_MODES, - KSPROPERTY_MPEG2VID_CUR_MODE, - KSPROPERTY_MPEG2VID_4_3_RECT, - KSPROPERTY_MPEG2VID_16_9_RECT, - KSPROPERTY_MPEG2VID_16_9_PANSCAN -}KSPROPERTY_MPEG2VID; - - # define KSMPEGVIDMODE_PANSCAN 0x0001 - # define KSMPEGVIDMODE_LTRBOX 0x0002 - # define KSMPEGVIDMODE_SCALE 0x0004 - -typedef struct _KSMPEGVID_RECT -{ - ULONG StartX; - ULONG StartY; - ULONG EndX; - ULONG EndY; -}KSMPEGVID_RECT, * PKSMPEGVID_RECT; - - # define STATIC_KSDATAFORMAT_SUBTYPE_MPEG2_AUDIO \ - 0xe06d802bL, 0xdb46, 0x11cf, 0xb4, 0xd1, 0x00, 0x80, 0x5f, 0x6c, 0xbb, 0xea -DEFINE_GUIDSTRUCT("e06d802b-db46-11cf-b4d1-00805f6cbbea", KSDATAFORMAT_SUBTYPE_MPEG2_AUDIO); - # define KSDATAFORMAT_SUBTYPE_MPEG2_AUDIO DEFINE_GUIDNAMED(KSDATAFORMAT_SUBTYPE_MPEG2_AUDIO) - - # define STATIC_KSDATAFORMAT_SPECIFIER_MPEG2_AUDIO \ - 0xe06d80e5L, 0xdb46, 0x11cf, 0xb4, 0xd1, 0x00, 0x80, 0x5f, 0x6c, 0xbb, 0xea -DEFINE_GUIDSTRUCT("e06d80e5-db46-11cf-b4d1-00805f6cbbea", KSDATAFORMAT_SPECIFIER_MPEG2_AUDIO); - # define KSDATAFORMAT_SPECIFIER_MPEG2_AUDIO DEFINE_GUIDNAMED(KSDATAFORMAT_SPECIFIER_MPEG2_AUDIO) - - # define STATIC_KSDATAFORMAT_SUBTYPE_LPCM_AUDIO \ - 0xe06d8032L, 0xdb46, 0x11cf, 0xb4, 0xd1, 0x00, 0x80, 0x5f, 0x6c, 0xbb, 0xea -DEFINE_GUIDSTRUCT("e06d8032-db46-11cf-b4d1-00805f6cbbea", KSDATAFORMAT_SUBTYPE_LPCM_AUDIO); - # define KSDATAFORMAT_SUBTYPE_LPCM_AUDIO DEFINE_GUIDNAMED(KSDATAFORMAT_SUBTYPE_LPCM_AUDIO) - - # define STATIC_KSDATAFORMAT_SPECIFIER_LPCM_AUDIO \ - 0xe06d80e6L, 0xdb46, 0x11cf, 0xb4, 0xd1, 0x00, 0x80, 0x5f, 0x6c, 0xbb, 0xea -DEFINE_GUIDSTRUCT("e06d80e6-db46-11cf-b4d1-00805f6cbbea", KSDATAFORMAT_SPECIFIER_LPCM_AUDIO); - # define KSDATAFORMAT_SPECIFIER_LPCM_AUDIO DEFINE_GUIDNAMED(KSDATAFORMAT_SPECIFIER_LPCM_AUDIO) - - # define STATIC_KSDATAFORMAT_SUBTYPE_AC3_AUDIO \ - 0xe06d802cL, 0xdb46, 0x11cf, 0xb4, 0xd1, 0x00, 0x80, 0x5f, 0x6c, 0xbb, 0xea -DEFINE_GUIDSTRUCT("e06d802c-db46-11cf-b4d1-00805f6cbbea", KSDATAFORMAT_SUBTYPE_AC3_AUDIO); - # define KSDATAFORMAT_SUBTYPE_AC3_AUDIO DEFINE_GUIDNAMED(KSDATAFORMAT_SUBTYPE_AC3_AUDIO) - - # define STATIC_KSDATAFORMAT_SPECIFIER_AC3_AUDIO \ - 0xe06d80e4L, 0xdb46, 0x11cf, 0xb4, 0xd1, 0x00, 0x80, 0x5f, 0x6c, 0xbb, 0xea -DEFINE_GUIDSTRUCT("e06d80e4-db46-11cf-b4d1-00805f6cbbea", KSDATAFORMAT_SPECIFIER_AC3_AUDIO); - # define KSDATAFORMAT_SPECIFIER_AC3_AUDIO DEFINE_GUIDNAMED(KSDATAFORMAT_SPECIFIER_AC3_AUDIO) - - # define STATIC_KSPROPSETID_AC3 \ - 0xBFABE720L, 0x6E1F, 0x11D0, 0xBC, 0xF2, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00 -DEFINE_GUIDSTRUCT("BFABE720-6E1F-11D0-BCF2-444553540000", KSPROPSETID_AC3); - # define KSPROPSETID_AC3 DEFINE_GUIDNAMED(KSPROPSETID_AC3) - -typedef enum -{ - KSPROPERTY_AC3_ERROR_CONCEALMENT = 1, - KSPROPERTY_AC3_ALTERNATE_AUDIO, - KSPROPERTY_AC3_DOWNMIX, - KSPROPERTY_AC3_BIT_STREAM_MODE, - KSPROPERTY_AC3_DIALOGUE_LEVEL, - KSPROPERTY_AC3_LANGUAGE_CODE, - KSPROPERTY_AC3_ROOM_TYPE -}KSPROPERTY_AC3; - -typedef struct -{ - WINBOOL fRepeatPreviousBlock; - WINBOOL fErrorInCurrentBlock; -}KSAC3_ERROR_CONCEALMENT, * PKSAC3_ERROR_CONCEALMENT; - -typedef struct -{ - WINBOOL fStereo; - ULONG DualMode; -}KSAC3_ALTERNATE_AUDIO, * PKSAC3_ALTERNATE_AUDIO; - - # define KSAC3_ALTERNATE_AUDIO_1 1 - # define KSAC3_ALTERNATE_AUDIO_2 2 - # define KSAC3_ALTERNATE_AUDIO_BOTH 3 - -typedef struct -{ - WINBOOL fDownMix; - WINBOOL fDolbySurround; -}KSAC3_DOWNMIX, * PKSAC3_DOWNMIX; - -typedef struct -{ - LONG BitStreamMode; -}KSAC3_BIT_STREAM_MODE, * PKSAC3_BIT_STREAM_MODE; - - # define KSAC3_SERVICE_MAIN_AUDIO 0 - # define KSAC3_SERVICE_NO_DIALOG 1 - # define KSAC3_SERVICE_VISUALLY_IMPAIRED 2 - # define KSAC3_SERVICE_HEARING_IMPAIRED 3 - # define KSAC3_SERVICE_DIALOG_ONLY 4 - # define KSAC3_SERVICE_COMMENTARY 5 - # define KSAC3_SERVICE_EMERGENCY_FLASH 6 - # define KSAC3_SERVICE_VOICE_OVER 7 - -typedef struct -{ - ULONG DialogueLevel; -}KSAC3_DIALOGUE_LEVEL, * PKSAC3_DIALOGUE_LEVEL; - -typedef struct -{ - WINBOOL fLargeRoom; -}KSAC3_ROOM_TYPE, * PKSAC3_ROOM_TYPE; - - # define STATIC_KSDATAFORMAT_SUBTYPE_DTS_AUDIO \ - 0xe06d8033L, 0xdb46, 0x11cf, 0xb4, 0xd1, 0x00, 0x80, 0x5f, 0x6c, 0xbb, 0xea -DEFINE_GUIDSTRUCT("e06d8033-db46-11cf-b4d1-00805f6cbbea", KSDATAFORMAT_SUBTYPE_DTS_AUDIO); - # define KSDATAFORMAT_SUBTYPE_DTS_AUDIO DEFINE_GUIDNAMED(KSDATAFORMAT_SUBTYPE_DTS_AUDIO) - - # define STATIC_KSDATAFORMAT_SUBTYPE_SDDS_AUDIO \ - 0xe06d8034L, 0xdb46, 0x11cf, 0xb4, 0xd1, 0x00, 0x80, 0x5f, 0x6c, 0xbb, 0xea -DEFINE_GUIDSTRUCT("e06d8034-db46-11cf-b4d1-00805f6cbbea", KSDATAFORMAT_SUBTYPE_SDDS_AUDIO); - # define KSDATAFORMAT_SUBTYPE_SDDS_AUDIO DEFINE_GUIDNAMED(KSDATAFORMAT_SUBTYPE_SDDS_AUDIO) - - # define STATIC_KSPROPSETID_AudioDecoderOut \ - 0x6ca6e020L, 0x43bd, 0x11d0, 0xbd, 0x6a, 0x00, 0x35, 0x05, 0xc1, 0x03, 0xa9 -DEFINE_GUIDSTRUCT("6ca6e020-43bd-11d0-bd6a-003505c103a9", KSPROPSETID_AudioDecoderOut); - # define KSPROPSETID_AudioDecoderOut DEFINE_GUIDNAMED(KSPROPSETID_AudioDecoderOut) - -typedef enum -{ - KSPROPERTY_AUDDECOUT_MODES, - KSPROPERTY_AUDDECOUT_CUR_MODE -}KSPROPERTY_AUDDECOUT; - - # define KSAUDDECOUTMODE_STEREO_ANALOG 0x0001 - # define KSAUDDECOUTMODE_PCM_51 0x0002 - # define KSAUDDECOUTMODE_SPDIFF 0x0004 - - # define STATIC_KSDATAFORMAT_SUBTYPE_SUBPICTURE \ - 0xe06d802dL, 0xdb46, 0x11cf, 0xb4, 0xd1, 0x00, 0x80, 0x5f, 0x6c, 0xbb, 0xea -DEFINE_GUIDSTRUCT("e06d802d-db46-11cf-b4d1-00805f6cbbea", KSDATAFORMAT_SUBTYPE_SUBPICTURE); - # define KSDATAFORMAT_SUBTYPE_SUBPICTURE DEFINE_GUIDNAMED(KSDATAFORMAT_SUBTYPE_SUBPICTURE) - - # define STATIC_KSPROPSETID_DvdSubPic \ - 0xac390460L, 0x43af, 0x11d0, 0xbd, 0x6a, 0x00, 0x35, 0x05, 0xc1, 0x03, 0xa9 -DEFINE_GUIDSTRUCT("ac390460-43af-11d0-bd6a-003505c103a9", KSPROPSETID_DvdSubPic); - # define KSPROPSETID_DvdSubPic DEFINE_GUIDNAMED(KSPROPSETID_DvdSubPic) - -typedef enum -{ - KSPROPERTY_DVDSUBPIC_PALETTE, - KSPROPERTY_DVDSUBPIC_HLI, - KSPROPERTY_DVDSUBPIC_COMPOSIT_ON -}KSPROPERTY_DVDSUBPIC; - -typedef struct _KS_DVD_YCrCb -{ - UCHAR Reserved; - UCHAR Y; - UCHAR Cr; - UCHAR Cb; -}KS_DVD_YCrCb, * PKS_DVD_YCrCb; - -typedef struct _KS_DVD_YUV -{ - UCHAR Reserved; - UCHAR Y; - UCHAR V; - UCHAR U; -}KS_DVD_YUV, * PKS_DVD_YUV; - -typedef struct _KSPROPERTY_SPPAL -{ - KS_DVD_YUV sppal[16]; -}KSPROPERTY_SPPAL, * PKSPROPERTY_SPPAL; - -typedef struct _KS_COLCON -{ - UCHAR emph1col : 4; - UCHAR emph2col : 4; - UCHAR backcol : 4; - UCHAR patcol : 4; - UCHAR emph1con : 4; - UCHAR emph2con : 4; - UCHAR backcon : 4; - UCHAR patcon : 4; -}KS_COLCON, * PKS_COLCON; - -typedef struct _KSPROPERTY_SPHLI -{ - USHORT HLISS; - USHORT Reserved; - ULONG StartPTM; - ULONG EndPTM; - USHORT StartX; - USHORT StartY; - USHORT StopX; - USHORT StopY; - KS_COLCON ColCon; -}KSPROPERTY_SPHLI, * PKSPROPERTY_SPHLI; - -typedef WINBOOL KSPROPERTY_COMPOSIT_ON, * PKSPROPERTY_COMPOSIT_ON; - - # define STATIC_KSPROPSETID_CopyProt \ - 0x0E8A0A40L, 0x6AEF, 0x11D0, 0x9E, 0xD0, 0x00, 0xA0, 0x24, 0xCA, 0x19, 0xB3 -DEFINE_GUIDSTRUCT("0E8A0A40-6AEF-11D0-9ED0-00A024CA19B3", KSPROPSETID_CopyProt); - # define KSPROPSETID_CopyProt DEFINE_GUIDNAMED(KSPROPSETID_CopyProt) - -typedef enum -{ - KSPROPERTY_DVDCOPY_CHLG_KEY = 0x01, - KSPROPERTY_DVDCOPY_DVD_KEY1, - KSPROPERTY_DVDCOPY_DEC_KEY2, - KSPROPERTY_DVDCOPY_TITLE_KEY, - KSPROPERTY_COPY_MACROVISION, - KSPROPERTY_DVDCOPY_REGION, - KSPROPERTY_DVDCOPY_SET_COPY_STATE, - KSPROPERTY_DVDCOPY_DISC_KEY = 0x80 -}KSPROPERTY_COPYPROT; - -typedef struct _KS_DVDCOPY_CHLGKEY -{ - BYTE ChlgKey[10]; - BYTE Reserved[2]; -}KS_DVDCOPY_CHLGKEY, * PKS_DVDCOPY_CHLGKEY; - -typedef struct _KS_DVDCOPY_BUSKEY -{ - BYTE BusKey[5]; - BYTE Reserved[1]; -}KS_DVDCOPY_BUSKEY, * PKS_DVDCOPY_BUSKEY; - -typedef struct _KS_DVDCOPY_DISCKEY -{ - BYTE DiscKey[2048]; -}KS_DVDCOPY_DISCKEY, * PKS_DVDCOPY_DISCKEY; - -typedef struct _KS_DVDCOPY_REGION -{ - UCHAR Reserved; - UCHAR RegionData; - UCHAR Reserved2[2]; -}KS_DVDCOPY_REGION, * PKS_DVDCOPY_REGION; - -typedef struct _KS_DVDCOPY_TITLEKEY -{ - ULONG KeyFlags; - ULONG ReservedNT[2]; - UCHAR TitleKey[6]; - UCHAR Reserved[2]; -}KS_DVDCOPY_TITLEKEY, * PKS_DVDCOPY_TITLEKEY; - -typedef struct _KS_COPY_MACROVISION -{ - ULONG MACROVISIONLevel; -}KS_COPY_MACROVISION, * PKS_COPY_MACROVISION; - -typedef struct _KS_DVDCOPY_SET_COPY_STATE -{ - ULONG DVDCopyState; -}KS_DVDCOPY_SET_COPY_STATE, * PKS_DVDCOPY_SET_COPY_STATE; - -typedef enum -{ - KS_DVDCOPYSTATE_INITIALIZE, - KS_DVDCOPYSTATE_INITIALIZE_TITLE, - KS_DVDCOPYSTATE_AUTHENTICATION_NOT_REQUIRED, - KS_DVDCOPYSTATE_AUTHENTICATION_REQUIRED, - KS_DVDCOPYSTATE_DONE -}KS_DVDCOPYSTATE; - -typedef enum -{ - KS_MACROVISION_DISABLED, - KS_MACROVISION_LEVEL1, - KS_MACROVISION_LEVEL2, - KS_MACROVISION_LEVEL3 -}KS_COPY_MACROVISION_LEVEL, * PKS_COPY_MACROVISION_LEVEL; - - # define KS_DVD_CGMS_RESERVED_MASK 0x00000078 - - # define KS_DVD_CGMS_COPY_PROTECT_MASK 0x00000018 - # define KS_DVD_CGMS_COPY_PERMITTED 0x00000000 - # define KS_DVD_CGMS_COPY_ONCE 0x00000010 - # define KS_DVD_CGMS_NO_COPY 0x00000018 - - # define KS_DVD_COPYRIGHT_MASK 0x00000040 - # define KS_DVD_NOT_COPYRIGHTED 0x00000000 - # define KS_DVD_COPYRIGHTED 0x00000040 - - # define KS_DVD_SECTOR_PROTECT_MASK 0x00000020 - # define KS_DVD_SECTOR_NOT_PROTECTED 0x00000000 - # define KS_DVD_SECTOR_PROTECTED 0x00000020 - - # define STATIC_KSCATEGORY_TVTUNER \ - 0xa799a800L, 0xa46d, 0x11d0, 0xa1, 0x8c, 0x00, 0xa0, 0x24, 0x01, 0xdc, 0xd4 -DEFINE_GUIDSTRUCT("a799a800-a46d-11d0-a18c-00a02401dcd4", KSCATEGORY_TVTUNER); - # define KSCATEGORY_TVTUNER DEFINE_GUIDNAMED(KSCATEGORY_TVTUNER) - - # define STATIC_KSCATEGORY_CROSSBAR \ - 0xa799a801L, 0xa46d, 0x11d0, 0xa1, 0x8c, 0x00, 0xa0, 0x24, 0x01, 0xdc, 0xd4 -DEFINE_GUIDSTRUCT("a799a801-a46d-11d0-a18c-00a02401dcd4", KSCATEGORY_CROSSBAR); - # define KSCATEGORY_CROSSBAR DEFINE_GUIDNAMED(KSCATEGORY_CROSSBAR) - - # define STATIC_KSCATEGORY_TVAUDIO \ - 0xa799a802L, 0xa46d, 0x11d0, 0xa1, 0x8c, 0x00, 0xa0, 0x24, 0x01, 0xdc, 0xd4 -DEFINE_GUIDSTRUCT("a799a802-a46d-11d0-a18c-00a02401dcd4", KSCATEGORY_TVAUDIO); - # define KSCATEGORY_TVAUDIO DEFINE_GUIDNAMED(KSCATEGORY_TVAUDIO) - - # define STATIC_KSCATEGORY_VPMUX \ - 0xa799a803L, 0xa46d, 0x11d0, 0xa1, 0x8c, 0x00, 0xa0, 0x24, 0x01, 0xdc, 0xd4 -DEFINE_GUIDSTRUCT("a799a803-a46d-11d0-a18c-00a02401dcd4", KSCATEGORY_VPMUX); - # define KSCATEGORY_VPMUX DEFINE_GUIDNAMED(KSCATEGORY_VPMUX) - - # define STATIC_KSCATEGORY_VBICODEC \ - 0x07dad660L, 0x22f1, 0x11d1, 0xa9, 0xf4, 0x00, 0xc0, 0x4f, 0xbb, 0xde, 0x8f -DEFINE_GUIDSTRUCT("07dad660-22f1-11d1-a9f4-00c04fbbde8f", KSCATEGORY_VBICODEC); - # define KSCATEGORY_VBICODEC DEFINE_GUIDNAMED(KSCATEGORY_VBICODEC) - - # define STATIC_KSDATAFORMAT_SUBTYPE_VPVideo \ - 0x5a9b6a40L, 0x1a22, 0x11d1, 0xba, 0xd9, 0x0, 0x60, 0x97, 0x44, 0x11, 0x1a -DEFINE_GUIDSTRUCT("5a9b6a40-1a22-11d1-bad9-00609744111a", KSDATAFORMAT_SUBTYPE_VPVideo); - # define KSDATAFORMAT_SUBTYPE_VPVideo DEFINE_GUIDNAMED(KSDATAFORMAT_SUBTYPE_VPVideo) - - # define STATIC_KSDATAFORMAT_SUBTYPE_VPVBI \ - 0x5a9b6a41L, 0x1a22, 0x11d1, 0xba, 0xd9, 0x0, 0x60, 0x97, 0x44, 0x11, 0x1a -DEFINE_GUIDSTRUCT("5a9b6a41-1a22-11d1-bad9-00609744111a", KSDATAFORMAT_SUBTYPE_VPVBI); - # define KSDATAFORMAT_SUBTYPE_VPVBI DEFINE_GUIDNAMED(KSDATAFORMAT_SUBTYPE_VPVBI) - - # define STATIC_KSDATAFORMAT_SPECIFIER_VIDEOINFO \ - 0x05589f80L, 0xc356, 0x11ce, 0xbf, 0x01, 0x00, 0xaa, 0x00, 0x55, 0x59, 0x5a -DEFINE_GUIDSTRUCT("05589f80-c356-11ce-bf01-00aa0055595a", KSDATAFORMAT_SPECIFIER_VIDEOINFO); - # define KSDATAFORMAT_SPECIFIER_VIDEOINFO DEFINE_GUIDNAMED(KSDATAFORMAT_SPECIFIER_VIDEOINFO) - - # define STATIC_KSDATAFORMAT_SPECIFIER_VIDEOINFO2 \ - 0xf72a76A0L, 0xeb0a, 0x11d0, 0xac, 0xe4, 0x00, 0x00, 0xc0, 0xcc, 0x16, 0xba -DEFINE_GUIDSTRUCT("f72a76A0-eb0a-11d0-ace4-0000c0cc16ba", KSDATAFORMAT_SPECIFIER_VIDEOINFO2); - # define KSDATAFORMAT_SPECIFIER_VIDEOINFO2 DEFINE_GUIDNAMED(KSDATAFORMAT_SPECIFIER_VIDEOINFO2) - - # define STATIC_KSDATAFORMAT_TYPE_ANALOGVIDEO \ - 0x0482dde1L, 0x7817, 0x11cf, 0x8a, 0x03, 0x00, 0xaa, 0x00, 0x6e, 0xcb, 0x65 -DEFINE_GUIDSTRUCT("0482dde1-7817-11cf-8a03-00aa006ecb65", KSDATAFORMAT_TYPE_ANALOGVIDEO); - # define KSDATAFORMAT_TYPE_ANALOGVIDEO DEFINE_GUIDNAMED(KSDATAFORMAT_TYPE_ANALOGVIDEO) - - # define STATIC_KSDATAFORMAT_SPECIFIER_ANALOGVIDEO \ - 0x0482dde0L, 0x7817, 0x11cf, 0x8a, 0x03, 0x00, 0xaa, 0x00, 0x6e, 0xcb, 0x65 -DEFINE_GUIDSTRUCT("0482dde0-7817-11cf-8a03-00aa006ecb65", KSDATAFORMAT_SPECIFIER_ANALOGVIDEO); - # define KSDATAFORMAT_SPECIFIER_ANALOGVIDEO DEFINE_GUIDNAMED(KSDATAFORMAT_SPECIFIER_ANALOGVIDEO) - - # define STATIC_KSDATAFORMAT_TYPE_ANALOGAUDIO \ - 0x0482dee1L, 0x7817, 0x11cf, 0x8a, 0x03, 0x00, 0xaa, 0x00, 0x6e, 0xcb, 0x65 -DEFINE_GUIDSTRUCT("0482DEE1-7817-11cf-8a03-00aa006ecb65", KSDATAFORMAT_TYPE_ANALOGAUDIO); - # define KSDATAFORMAT_TYPE_ANALOGAUDIO DEFINE_GUIDNAMED(KSDATAFORMAT_TYPE_ANALOGAUDIO) - - # define STATIC_KSDATAFORMAT_SPECIFIER_VBI \ - 0xf72a76e0L, 0xeb0a, 0x11d0, 0xac, 0xe4, 0x00, 0x00, 0xc0, 0xcc, 0x16, 0xba -DEFINE_GUIDSTRUCT("f72a76e0-eb0a-11d0-ace4-0000c0cc16ba", KSDATAFORMAT_SPECIFIER_VBI); - # define KSDATAFORMAT_SPECIFIER_VBI DEFINE_GUIDNAMED(KSDATAFORMAT_SPECIFIER_VBI) - - # define STATIC_KSDATAFORMAT_TYPE_VBI \ - 0xf72a76e1L, 0xeb0a, 0x11d0, 0xac, 0xe4, 0x00, 0x00, 0xc0, 0xcc, 0x16, 0xba -DEFINE_GUIDSTRUCT("f72a76e1-eb0a-11d0-ace4-0000c0cc16ba", KSDATAFORMAT_TYPE_VBI); - # define KSDATAFORMAT_TYPE_VBI DEFINE_GUIDNAMED(KSDATAFORMAT_TYPE_VBI) - - # define STATIC_KSDATAFORMAT_SUBTYPE_RAW8 \ - 0xca20d9a0, 0x3e3e, 0x11d1, 0x9b, 0xf9, 0x0, 0xc0, 0x4f, 0xbb, 0xde, 0xbf -DEFINE_GUIDSTRUCT("ca20d9a0-3e3e-11d1-9bf9-00c04fbbdebf", KSDATAFORMAT_SUBTYPE_RAW8); - # define KSDATAFORMAT_SUBTYPE_RAW8 DEFINE_GUIDNAMED(KSDATAFORMAT_SUBTYPE_RAW8) - - # define STATIC_KSDATAFORMAT_SUBTYPE_CC \ - 0x33214cc1, 0x11f, 0x11d2, 0xb4, 0xb1, 0x0, 0xa0, 0xd1, 0x2, 0xcf, 0xbe -DEFINE_GUIDSTRUCT("33214CC1-011F-11D2-B4B1-00A0D102CFBE", KSDATAFORMAT_SUBTYPE_CC); - # define KSDATAFORMAT_SUBTYPE_CC DEFINE_GUIDNAMED(KSDATAFORMAT_SUBTYPE_CC) - - # define STATIC_KSDATAFORMAT_SUBTYPE_NABTS \ - 0xf72a76e2L, 0xeb0a, 0x11d0, 0xac, 0xe4, 0x00, 0x00, 0xc0, 0xcc, 0x16, 0xba -DEFINE_GUIDSTRUCT("f72a76e2-eb0a-11d0-ace4-0000c0cc16ba", KSDATAFORMAT_SUBTYPE_NABTS); - # define KSDATAFORMAT_SUBTYPE_NABTS DEFINE_GUIDNAMED(KSDATAFORMAT_SUBTYPE_NABTS) - - # define STATIC_KSDATAFORMAT_SUBTYPE_TELETEXT \ - 0xf72a76e3L, 0xeb0a, 0x11d0, 0xac, 0xe4, 0x00, 0x00, 0xc0, 0xcc, 0x16, 0xba -DEFINE_GUIDSTRUCT("f72a76e3-eb0a-11d0-ace4-0000c0cc16ba", KSDATAFORMAT_SUBTYPE_TELETEXT); - # define KSDATAFORMAT_SUBTYPE_TELETEXT DEFINE_GUIDNAMED(KSDATAFORMAT_SUBTYPE_TELETEXT) - - # define KS_BI_RGB 0L - # define KS_BI_RLE8 1L - # define KS_BI_RLE4 2L - # define KS_BI_BITFIELDS 3L - -typedef struct tagKS_RGBQUAD -{ - BYTE rgbBlue; - BYTE rgbGreen; - BYTE rgbRed; - BYTE rgbReserved; -}KS_RGBQUAD, * PKS_RGBQUAD; - - # define KS_iPALETTE_COLORS 256 - # define KS_iEGA_COLORS 16 - # define KS_iMASK_COLORS 3 - # define KS_iTRUECOLOR 16 - # define KS_iRED 0 - # define KS_iGREEN 1 - # define KS_iBLUE 2 - # define KS_iPALETTE 8 - # define KS_iMAXBITS 8 - # define KS_SIZE_EGA_PALETTE (KS_iEGA_COLORS * sizeof(KS_RGBQUAD)) - # define KS_SIZE_PALETTE (KS_iPALETTE_COLORS * sizeof(KS_RGBQUAD)) - -typedef struct tagKS_BITMAPINFOHEADER -{ - DWORD biSize; - LONG biWidth; - LONG biHeight; - WORD biPlanes; - WORD biBitCount; - DWORD biCompression; - DWORD biSizeImage; - LONG biXPelsPerMeter; - LONG biYPelsPerMeter; - DWORD biClrUsed; - DWORD biClrImportant; -}KS_BITMAPINFOHEADER, * PKS_BITMAPINFOHEADER; - -typedef struct tag_KS_TRUECOLORINFO -{ - DWORD dwBitMasks[KS_iMASK_COLORS]; - KS_RGBQUAD bmiColors[KS_iPALETTE_COLORS]; -}KS_TRUECOLORINFO, * PKS_TRUECOLORINFO; - - # define KS_WIDTHBYTES(bits) ((DWORD)(((bits) + 31) & (~31)) / 8) - # define KS_DIBWIDTHBYTES(bi) (DWORD)KS_WIDTHBYTES((DWORD)(bi).biWidth * (DWORD)(bi).biBitCount) - # define KS__DIBSIZE(bi) (KS_DIBWIDTHBYTES(bi) * (DWORD)(bi).biHeight) - # define KS_DIBSIZE(bi) ((bi).biHeight < 0 ? (-1) * (KS__DIBSIZE(bi)) : KS__DIBSIZE(bi)) - -typedef LONGLONG REFERENCE_TIME; - -typedef struct tagKS_VIDEOINFOHEADER -{ - RECT rcSource; - RECT rcTarget; - DWORD dwBitRate; - DWORD dwBitErrorRate; - REFERENCE_TIME AvgTimePerFrame; - KS_BITMAPINFOHEADER bmiHeader; -}KS_VIDEOINFOHEADER, * PKS_VIDEOINFOHEADER; - -typedef struct tagKS_VIDEOINFO -{ - RECT rcSource; - RECT rcTarget; - DWORD dwBitRate; - DWORD dwBitErrorRate; - REFERENCE_TIME AvgTimePerFrame; - KS_BITMAPINFOHEADER bmiHeader; - __MINGW_EXTENSION union - { - KS_RGBQUAD bmiColors[KS_iPALETTE_COLORS]; - DWORD dwBitMasks[KS_iMASK_COLORS]; - KS_TRUECOLORINFO TrueColorInfo; - }; -}KS_VIDEOINFO, * PKS_VIDEOINFO; - - # define KS_SIZE_MASKS (KS_iMASK_COLORS * sizeof(DWORD)) - # define KS_SIZE_PREHEADER (FIELD_OFFSET(KS_VIDEOINFOHEADER, bmiHeader)) - - # define KS_SIZE_VIDEOHEADER(pbmi) ((pbmi)->bmiHeader.biSize + KS_SIZE_PREHEADER) - -typedef struct tagKS_VBIINFOHEADER -{ - ULONG StartLine; - ULONG EndLine; - ULONG SamplingFrequency; - ULONG MinLineStartTime; - ULONG MaxLineStartTime; - ULONG ActualLineStartTime; - ULONG ActualLineEndTime; - ULONG VideoStandard; - ULONG SamplesPerLine; - ULONG StrideInBytes; - ULONG BufferSize; -}KS_VBIINFOHEADER, * PKS_VBIINFOHEADER; - - # define KS_VBIDATARATE_NABTS (5727272L) - # define KS_VBIDATARATE_CC (503493L) - # define KS_VBISAMPLINGRATE_4X_NABTS ((long)(4 * KS_VBIDATARATE_NABTS)) - # define KS_VBISAMPLINGRATE_47X_NABTS ((long)(27000000)) - # define KS_VBISAMPLINGRATE_5X_NABTS ((long)(5 * KS_VBIDATARATE_NABTS)) - - # define KS_47NABTS_SCALER (KS_VBISAMPLINGRATE_47X_NABTS / (double)KS_VBIDATARATE_NABTS) - -typedef struct tagKS_AnalogVideoInfo -{ - RECT rcSource; - RECT rcTarget; - DWORD dwActiveWidth; - DWORD dwActiveHeight; - REFERENCE_TIME AvgTimePerFrame; -}KS_ANALOGVIDEOINFO, * PKS_ANALOGVIDEOINFO; - - # define KS_TVTUNER_CHANGE_BEGIN_TUNE 0x0001L - # define KS_TVTUNER_CHANGE_END_TUNE 0x0002L - -typedef struct tagKS_TVTUNER_CHANGE_INFO -{ - DWORD dwFlags; - DWORD dwCountryCode; - DWORD dwAnalogVideoStandard; - DWORD dwChannel; -}KS_TVTUNER_CHANGE_INFO, * PKS_TVTUNER_CHANGE_INFO; - -typedef enum -{ - KS_MPEG2Level_Low, - KS_MPEG2Level_Main, - KS_MPEG2Level_High1440, - KS_MPEG2Level_High -}KS_MPEG2Level; - -typedef enum -{ - KS_MPEG2Profile_Simple, - KS_MPEG2Profile_Main, - KS_MPEG2Profile_SNRScalable, - KS_MPEG2Profile_SpatiallyScalable, - KS_MPEG2Profile_High -}KS_MPEG2Profile; - - # define KS_INTERLACE_IsInterlaced 0x00000001 - # define KS_INTERLACE_1FieldPerSample 0x00000002 - # define KS_INTERLACE_Field1First 0x00000004 - # define KS_INTERLACE_UNUSED 0x00000008 - # define KS_INTERLACE_FieldPatternMask 0x00000030 - # define KS_INTERLACE_FieldPatField1Only 0x00000000 - # define KS_INTERLACE_FieldPatField2Only 0x00000010 - # define KS_INTERLACE_FieldPatBothRegular 0x00000020 - # define KS_INTERLACE_FieldPatBothIrregular 0x00000030 - # define KS_INTERLACE_DisplayModeMask 0x000000c0 - # define KS_INTERLACE_DisplayModeBobOnly 0x00000000 - # define KS_INTERLACE_DisplayModeWeaveOnly 0x00000040 - # define KS_INTERLACE_DisplayModeBobOrWeave 0x00000080 - - # define KS_MPEG2_DoPanScan 0x00000001 - # define KS_MPEG2_DVDLine21Field1 0x00000002 - # define KS_MPEG2_DVDLine21Field2 0x00000004 - # define KS_MPEG2_SourceIsLetterboxed 0x00000008 - # define KS_MPEG2_FilmCameraMode 0x00000010 - # define KS_MPEG2_LetterboxAnalogOut 0x00000020 - # define KS_MPEG2_DSS_UserData 0x00000040 - # define KS_MPEG2_DVB_UserData 0x00000080 - # define KS_MPEG2_27MhzTimebase 0x00000100 - -typedef struct tagKS_VIDEOINFOHEADER2 -{ - RECT rcSource; - RECT rcTarget; - DWORD dwBitRate; - DWORD dwBitErrorRate; - REFERENCE_TIME AvgTimePerFrame; - DWORD dwInterlaceFlags; - DWORD dwCopyProtectFlags; - DWORD dwPictAspectRatioX; - DWORD dwPictAspectRatioY; - DWORD dwReserved1; - DWORD dwReserved2; - KS_BITMAPINFOHEADER bmiHeader; -}KS_VIDEOINFOHEADER2, * PKS_VIDEOINFOHEADER2; - -typedef struct tagKS_MPEG1VIDEOINFO -{ - KS_VIDEOINFOHEADER hdr; - DWORD dwStartTimeCode; - DWORD cbSequenceHeader; - BYTE bSequenceHeader[1]; -}KS_MPEG1VIDEOINFO, * PKS_MPEG1VIDEOINFO; - - # define KS_MAX_SIZE_MPEG1_SEQUENCE_INFO 140 - # define KS_SIZE_MPEG1VIDEOINFO(pv) (FIELD_OFFSET(KS_MPEG1VIDEOINFO, bSequenceHeader[0]) + (pv)->cbSequenceHeader) - # define KS_MPEG1_SEQUENCE_INFO(pv) ((const BYTE*)(pv)->bSequenceHeader) - -typedef struct tagKS_MPEGVIDEOINFO2 -{ - KS_VIDEOINFOHEADER2 hdr; - DWORD dwStartTimeCode; - DWORD cbSequenceHeader; - DWORD dwProfile; - DWORD dwLevel; - DWORD dwFlags; - DWORD bSequenceHeader[1]; -}KS_MPEGVIDEOINFO2, * PKS_MPEGVIDEOINFO2; - - # define KS_SIZE_MPEGVIDEOINFO2(pv) (FIELD_OFFSET(KS_MPEGVIDEOINFO2, bSequenceHeader[0]) + (pv)->cbSequenceHeader) - # define KS_MPEG1_SEQUENCE_INFO(pv) ((const BYTE*)(pv)->bSequenceHeader) - - # define KS_MPEGAUDIOINFO_27MhzTimebase 0x00000001 - -typedef struct tagKS_MPEAUDIOINFO -{ - DWORD dwFlags; - DWORD dwReserved1; - DWORD dwReserved2; - DWORD dwReserved3; -}KS_MPEGAUDIOINFO, * PKS_MPEGAUDIOINFO; - -typedef struct tagKS_DATAFORMAT_VIDEOINFOHEADER -{ - KSDATAFORMAT DataFormat; - KS_VIDEOINFOHEADER VideoInfoHeader; -}KS_DATAFORMAT_VIDEOINFOHEADER, * PKS_DATAFORMAT_VIDEOINFOHEADER; - -typedef struct tagKS_DATAFORMAT_VIDEOINFOHEADER2 -{ - KSDATAFORMAT DataFormat; - KS_VIDEOINFOHEADER2 VideoInfoHeader2; -}KS_DATAFORMAT_VIDEOINFOHEADER2, * PKS_DATAFORMAT_VIDEOINFOHEADER2; - -typedef struct tagKS_DATAFORMAT_VIDEOINFO_PALETTE -{ - KSDATAFORMAT DataFormat; - KS_VIDEOINFO VideoInfo; -}KS_DATAFORMAT_VIDEOINFO_PALETTE, * PKS_DATAFORMAT_VIDEOINFO_PALETTE; - -typedef struct tagKS_DATAFORMAT_VBIINFOHEADER -{ - KSDATAFORMAT DataFormat; - KS_VBIINFOHEADER VBIInfoHeader; -}KS_DATAFORMAT_VBIINFOHEADER, * PKS_DATAFORMAT_VBIINFOHEADER; - -typedef struct _KS_VIDEO_STREAM_CONFIG_CAPS -{ - GUID guid; - ULONG VideoStandard; - SIZE InputSize; - SIZE MinCroppingSize; - SIZE MaxCroppingSize; - int CropGranularityX; - int CropGranularityY; - int CropAlignX; - int CropAlignY; - SIZE MinOutputSize; - SIZE MaxOutputSize; - int OutputGranularityX; - int OutputGranularityY; - int StretchTapsX; - int StretchTapsY; - int ShrinkTapsX; - int ShrinkTapsY; - LONGLONG MinFrameInterval; - LONGLONG MaxFrameInterval; - LONG MinBitsPerSecond; - LONG MaxBitsPerSecond; -}KS_VIDEO_STREAM_CONFIG_CAPS, * PKS_VIDEO_STREAM_CONFIG_CAPS; - -typedef struct tagKS_DATARANGE_VIDEO -{ - KSDATARANGE DataRange; - WINBOOL bFixedSizeSamples; - WINBOOL bTemporalCompression; - DWORD StreamDescriptionFlags; - DWORD MemoryAllocationFlags; - KS_VIDEO_STREAM_CONFIG_CAPS ConfigCaps; - KS_VIDEOINFOHEADER VideoInfoHeader; -}KS_DATARANGE_VIDEO, * PKS_DATARANGE_VIDEO; - -typedef struct tagKS_DATARANGE_VIDEO2 -{ - KSDATARANGE DataRange; - WINBOOL bFixedSizeSamples; - WINBOOL bTemporalCompression; - DWORD StreamDescriptionFlags; - DWORD MemoryAllocationFlags; - KS_VIDEO_STREAM_CONFIG_CAPS ConfigCaps; - KS_VIDEOINFOHEADER2 VideoInfoHeader; -}KS_DATARANGE_VIDEO2, * PKS_DATARANGE_VIDEO2; - -typedef struct tagKS_DATARANGE_MPEG1_VIDEO -{ - KSDATARANGE DataRange; - WINBOOL bFixedSizeSamples; - WINBOOL bTemporalCompression; - DWORD StreamDescriptionFlags; - DWORD MemoryAllocationFlags; - KS_VIDEO_STREAM_CONFIG_CAPS ConfigCaps; - KS_MPEG1VIDEOINFO VideoInfoHeader; -}KS_DATARANGE_MPEG1_VIDEO, * PKS_DATARANGE_MPEG1_VIDEO; - -typedef struct tagKS_DATARANGE_MPEG2_VIDEO -{ - KSDATARANGE DataRange; - WINBOOL bFixedSizeSamples; - WINBOOL bTemporalCompression; - DWORD StreamDescriptionFlags; - DWORD MemoryAllocationFlags; - KS_VIDEO_STREAM_CONFIG_CAPS ConfigCaps; - KS_MPEGVIDEOINFO2 VideoInfoHeader; -}KS_DATARANGE_MPEG2_VIDEO, * PKS_DATARANGE_MPEG2_VIDEO; - -typedef struct tagKS_DATARANGE_VIDEO_PALETTE -{ - KSDATARANGE DataRange; - WINBOOL bFixedSizeSamples; - WINBOOL bTemporalCompression; - DWORD StreamDescriptionFlags; - DWORD MemoryAllocationFlags; - KS_VIDEO_STREAM_CONFIG_CAPS ConfigCaps; - KS_VIDEOINFO VideoInfo; -}KS_DATARANGE_VIDEO_PALETTE, * PKS_DATARANGE_VIDEO_PALETTE; - -typedef struct tagKS_DATARANGE_VIDEO_VBI -{ - KSDATARANGE DataRange; - WINBOOL bFixedSizeSamples; - WINBOOL bTemporalCompression; - DWORD StreamDescriptionFlags; - DWORD MemoryAllocationFlags; - KS_VIDEO_STREAM_CONFIG_CAPS ConfigCaps; - KS_VBIINFOHEADER VBIInfoHeader; -}KS_DATARANGE_VIDEO_VBI, * PKS_DATARANGE_VIDEO_VBI; - -typedef struct tagKS_DATARANGE_ANALOGVIDEO -{ - KSDATARANGE DataRange; - KS_ANALOGVIDEOINFO AnalogVideoInfo; -}KS_DATARANGE_ANALOGVIDEO, * PKS_DATARANGE_ANALOGVIDEO; - - # define KS_VIDEOSTREAM_PREVIEW 0x0001 - # define KS_VIDEOSTREAM_CAPTURE 0x0002 - # define KS_VIDEOSTREAM_VBI 0x0010 - # define KS_VIDEOSTREAM_NABTS 0x0020 - # define KS_VIDEOSTREAM_CC 0x0100 - # define KS_VIDEOSTREAM_EDS 0x0200 - # define KS_VIDEOSTREAM_TELETEXT 0x0400 - # define KS_VIDEOSTREAM_STILL 0x1000 - # define KS_VIDEOSTREAM_IS_VPE 0x8000 - - # define KS_VIDEO_ALLOC_VPE_SYSTEM 0x0001 - # define KS_VIDEO_ALLOC_VPE_DISPLAY 0x0002 - # define KS_VIDEO_ALLOC_VPE_AGP 0x0004 - - # define STATIC_KSPROPSETID_VBICAP_PROPERTIES \ - 0xf162c607, 0x7b35, 0x496f, 0xad, 0x7f, 0x2d, 0xca, 0x3b, 0x46, 0xb7, 0x18 -DEFINE_GUIDSTRUCT("F162C607-7B35-496f-AD7F-2DCA3B46B718", KSPROPSETID_VBICAP_PROPERTIES); - # define KSPROPSETID_VBICAP_PROPERTIES DEFINE_GUIDNAMED(KSPROPSETID_VBICAP_PROPERTIES) - -typedef enum -{ - KSPROPERTY_VBICAP_PROPERTIES_PROTECTION = 0x01 -}KSPROPERTY_VBICAP; - -typedef struct _VBICAP_PROPERTIES_PROTECTION_S -{ - KSPROPERTY Property; - ULONG StreamIndex; - ULONG Status; -}VBICAP_PROPERTIES_PROTECTION_S, * PVBICAP_PROPERTIES_PROTECTION_S; - - # define KS_VBICAP_PROTECTION_MV_PRESENT 0x0001L - # define KS_VBICAP_PROTECTION_MV_HARDWARE 0x0002L - # define KS_VBICAP_PROTECTION_MV_DETECTED 0x0004L - - # define KS_NABTS_GROUPID_ORIGINAL_CONTENT_BASE 0x800 - # define KS_NABTS_GROUPID_ORIGINAL_CONTENT_ADVERTISER_BASE 0x810 - - # define KS_NABTS_GROUPID_PRODUCTION_COMPANY_CONTENT_BASE 0x820 - # define KS_NABTS_GROUPID_PRODUCTION_COMPANY_ADVERTISER_BASE 0x830 - - # define KS_NABTS_GROUPID_SYNDICATED_SHOW_CONTENT_BASE 0x840 - # define KS_NABTS_GROUPID_SYNDICATED_SHOW_ADVERTISER_BASE 0x850 - - # define KS_NABTS_GROUPID_NETWORK_WIDE_CONTENT_BASE 0x860 - # define KS_NABTS_GROUPID_NETWORK_WIDE_ADVERTISER_BASE 0x870 - - # define KS_NABTS_GROUPID_TELEVISION_STATION_CONTENT_BASE 0x880 - # define KS_NABTS_GROUPID_TELEVISION_STATION_ADVERTISER_BASE 0x890 - - # define KS_NABTS_GROUPID_LOCAL_CABLE_SYSTEM_CONTENT_BASE 0x8A0 - # define KS_NABTS_GROUPID_LOCAL_CABLE_SYSTEM_ADVERTISER_BASE 0x8B0 - - # define KS_NABTS_GROUPID_MICROSOFT_RESERVED_TEST_DATA_BASE 0x8F0 - - # define STATIC_KSDATAFORMAT_TYPE_NABTS \ - 0xe757bca0, 0x39ac, 0x11d1, 0xa9, 0xf5, 0x0, 0xc0, 0x4f, 0xbb, 0xde, 0x8f -DEFINE_GUIDSTRUCT("E757BCA0-39AC-11d1-A9F5-00C04FBBDE8F", KSDATAFORMAT_TYPE_NABTS); - # define KSDATAFORMAT_TYPE_NABTS DEFINE_GUIDNAMED(KSDATAFORMAT_TYPE_NABTS) - - # define STATIC_KSDATAFORMAT_SUBTYPE_NABTS_FEC \ - 0xe757bca1, 0x39ac, 0x11d1, 0xa9, 0xf5, 0x0, 0xc0, 0x4f, 0xbb, 0xde, 0x8f -DEFINE_GUIDSTRUCT("E757BCA1-39AC-11d1-A9F5-00C04FBBDE8F", KSDATAFORMAT_SUBTYPE_NABTS_FEC); - # define KSDATAFORMAT_SUBTYPE_NABTS_FEC DEFINE_GUIDNAMED(KSDATAFORMAT_SUBTYPE_NABTS_FEC) - - # define MAX_NABTS_VBI_LINES_PER_FIELD 11 - # define NABTS_LINES_PER_BUNDLE 16 - # define NABTS_PAYLOAD_PER_LINE 28 - # define NABTS_BYTES_PER_LINE 36 - -typedef struct _NABTSFEC_BUFFER -{ - ULONG dataSize; - USHORT groupID; - USHORT Reserved; - UCHAR data[NABTS_LINES_PER_BUNDLE * NABTS_PAYLOAD_PER_LINE]; -}NABTSFEC_BUFFER, * PNABTSFEC_BUFFER; - - # define STATIC_KSPROPSETID_VBICodecFiltering \ - 0xcafeb0caL, 0x8715, 0x11d0, 0xbd, 0x6a, 0x00, 0x35, 0xc0, 0xed, 0xba, 0xbe -DEFINE_GUIDSTRUCT("cafeb0ca-8715-11d0-bd6a-0035c0edbabe", KSPROPSETID_VBICodecFiltering); - # define KSPROPSETID_VBICodecFiltering DEFINE_GUIDNAMED(KSPROPSETID_VBICodecFiltering) - -typedef enum -{ - KSPROPERTY_VBICODECFILTERING_SCANLINES_REQUESTED_BIT_ARRAY = 0x01, - KSPROPERTY_VBICODECFILTERING_SCANLINES_DISCOVERED_BIT_ARRAY, - KSPROPERTY_VBICODECFILTERING_SUBSTREAMS_REQUESTED_BIT_ARRAY, - KSPROPERTY_VBICODECFILTERING_SUBSTREAMS_DISCOVERED_BIT_ARRAY, - KSPROPERTY_VBICODECFILTERING_STATISTICS -}KSPROPERTY_VBICODECFILTERING; - -typedef struct _VBICODECFILTERING_SCANLINES -{ - DWORD DwordBitArray[32]; -}VBICODECFILTERING_SCANLINES, * PVBICODECFILTERING_SCANLINES; - -typedef struct _VBICODECFILTERING_NABTS_SUBSTREAMS -{ - DWORD SubstreamMask[128]; -}VBICODECFILTERING_NABTS_SUBSTREAMS, * PVBICODECFILTERING_NABTS_SUBSTREAMS; - -typedef struct _VBICODECFILTERING_CC_SUBSTREAMS -{ - DWORD SubstreamMask; -}VBICODECFILTERING_CC_SUBSTREAMS, * PVBICODECFILTERING_CC_SUBSTREAMS; - - # define KS_CC_SUBSTREAM_ODD 0x0001L - # define KS_CC_SUBSTREAM_EVEN 0x0002L - - # define KS_CC_SUBSTREAM_FIELD1_MASK 0x00F0L - # define KS_CC_SUBSTREAM_SERVICE_CC1 0x0010L - # define KS_CC_SUBSTREAM_SERVICE_CC2 0x0020L - # define KS_CC_SUBSTREAM_SERVICE_T1 0x0040L - # define KS_CC_SUBSTREAM_SERVICE_T2 0x0080L - - # define KS_CC_SUBSTREAM_FIELD2_MASK 0x1F00L - # define KS_CC_SUBSTREAM_SERVICE_CC3 0x0100L - # define KS_CC_SUBSTREAM_SERVICE_CC4 0x0200L - # define KS_CC_SUBSTREAM_SERVICE_T3 0x0400L - # define KS_CC_SUBSTREAM_SERVICE_T4 0x0800L - # define KS_CC_SUBSTREAM_SERVICE_XDS 0x1000L - - # define CC_MAX_HW_DECODE_LINES 12 -typedef struct _CC_BYTE_PAIR -{ - BYTE Decoded[2]; - USHORT Reserved; -}CC_BYTE_PAIR, * PCC_BYTE_PAIR; - -typedef struct _CC_HW_FIELD -{ - VBICODECFILTERING_SCANLINES ScanlinesRequested; - ULONG fieldFlags; - LONGLONG PictureNumber; - CC_BYTE_PAIR Lines[CC_MAX_HW_DECODE_LINES]; -}CC_HW_FIELD, * PCC_HW_FIELD; - - # ifndef PACK_PRAGMAS_NOT_SUPPORTED - # include - # endif -typedef struct _NABTS_BUFFER_LINE -{ - BYTE Confidence; - BYTE Bytes[NABTS_BYTES_PER_LINE]; -}NABTS_BUFFER_LINE, * PNABTS_BUFFER_LINE; - - # define NABTS_BUFFER_PICTURENUMBER_SUPPORT 1 -typedef struct _NABTS_BUFFER -{ - VBICODECFILTERING_SCANLINES ScanlinesRequested; - LONGLONG PictureNumber; - NABTS_BUFFER_LINE NabtsLines[MAX_NABTS_VBI_LINES_PER_FIELD]; -}NABTS_BUFFER, * PNABTS_BUFFER; - # ifndef PACK_PRAGMAS_NOT_SUPPORTED - # include - # endif - - # define WST_TVTUNER_CHANGE_BEGIN_TUNE 0x1000L - # define WST_TVTUNER_CHANGE_END_TUNE 0x2000L - - # define MAX_WST_VBI_LINES_PER_FIELD 17 - # define WST_BYTES_PER_LINE 42 - -typedef struct _WST_BUFFER_LINE -{ - BYTE Confidence; - BYTE Bytes[WST_BYTES_PER_LINE]; -}WST_BUFFER_LINE, * PWST_BUFFER_LINE; - -typedef struct _WST_BUFFER -{ - VBICODECFILTERING_SCANLINES ScanlinesRequested; - WST_BUFFER_LINE WstLines[MAX_WST_VBI_LINES_PER_FIELD]; -}WST_BUFFER, * PWST_BUFFER; - -typedef struct _VBICODECFILTERING_STATISTICS_COMMON -{ - DWORD InputSRBsProcessed; - DWORD OutputSRBsProcessed; - DWORD SRBsIgnored; - DWORD InputSRBsMissing; - DWORD OutputSRBsMissing; - DWORD OutputFailures; - DWORD InternalErrors; - DWORD ExternalErrors; - DWORD InputDiscontinuities; - DWORD DSPFailures; - DWORD TvTunerChanges; - DWORD VBIHeaderChanges; - DWORD LineConfidenceAvg; - DWORD BytesOutput; -}VBICODECFILTERING_STATISTICS_COMMON, * PVBICODECFILTERING_STATISTICS_COMMON; - -typedef struct _VBICODECFILTERING_STATISTICS_COMMON_PIN -{ - DWORD SRBsProcessed; - DWORD SRBsIgnored; - DWORD SRBsMissing; - DWORD InternalErrors; - DWORD ExternalErrors; - DWORD Discontinuities; - DWORD LineConfidenceAvg; - DWORD BytesOutput; -}VBICODECFILTERING_STATISTICS_COMMON_PIN, * PVBICODECFILTERING_STATISTICS_COMMON_PIN; - -typedef struct _VBICODECFILTERING_STATISTICS_NABTS -{ - VBICODECFILTERING_STATISTICS_COMMON Common; - DWORD FECBundleBadLines; - DWORD FECQueueOverflows; - DWORD FECCorrectedLines; - DWORD FECUncorrectableLines; - DWORD BundlesProcessed; - DWORD BundlesSent2IP; - DWORD FilteredLines; -}VBICODECFILTERING_STATISTICS_NABTS, * PVBICODECFILTERING_STATISTICS_NABTS; - -typedef struct _VBICODECFILTERING_STATISTICS_NABTS_PIN -{ - VBICODECFILTERING_STATISTICS_COMMON_PIN Common; -}VBICODECFILTERING_STATISTICS_NABTS_PIN, * PVBICODECFILTERING_STATISTICS_NABTS_PIN; - -typedef struct _VBICODECFILTERING_STATISTICS_CC -{ - VBICODECFILTERING_STATISTICS_COMMON Common; -}VBICODECFILTERING_STATISTICS_CC, * PVBICODECFILTERING_STATISTICS_CC; - -typedef struct _VBICODECFILTERING_STATISTICS_CC_PIN -{ - VBICODECFILTERING_STATISTICS_COMMON_PIN Common; -}VBICODECFILTERING_STATISTICS_CC_PIN, * PVBICODECFILTERING_STATISTICS_CC_PIN; - -typedef struct _VBICODECFILTERING_STATISTICS_TELETEXT -{ - VBICODECFILTERING_STATISTICS_COMMON Common; -}VBICODECFILTERING_STATISTICS_TELETEXT, * PVBICODECFILTERING_STATISTICS_TELETEXT; - -typedef struct _VBICODECFILTERING_STATISTICS_TELETEXT_PIN -{ - VBICODECFILTERING_STATISTICS_COMMON_PIN Common; -}VBICODECFILTERING_STATISTICS_TELETEXT_PIN, * PVBICODECFILTERING_STATISTICS_TELETEXT_PIN; - -typedef struct -{ - KSPROPERTY Property; - VBICODECFILTERING_SCANLINES Scanlines; -}KSPROPERTY_VBICODECFILTERING_SCANLINES_S, * PKSPROPERTY_VBICODECFILTERING_SCANLINES_S; - -typedef struct -{ - KSPROPERTY Property; - VBICODECFILTERING_NABTS_SUBSTREAMS Substreams; -}KSPROPERTY_VBICODECFILTERING_NABTS_SUBSTREAMS_S, * PKSPROPERTY_VBICODECFILTERING_NABTS_SUBSTREAMS_S; - -typedef struct -{ - KSPROPERTY Property; - VBICODECFILTERING_CC_SUBSTREAMS Substreams; -}KSPROPERTY_VBICODECFILTERING_CC_SUBSTREAMS_S, * PKSPROPERTY_VBICODECFILTERING_CC_SUBSTREAMS_S; - -typedef struct -{ - KSPROPERTY Property; - VBICODECFILTERING_STATISTICS_COMMON Statistics; -}KSPROPERTY_VBICODECFILTERING_STATISTICS_COMMON_S, * PKSPROPERTY_VBICODECFILTERING_STATISTICS_COMMON_S; - -typedef struct -{ - KSPROPERTY Property; - VBICODECFILTERING_STATISTICS_COMMON_PIN Statistics; -}KSPROPERTY_VBICODECFILTERING_STATISTICS_COMMON_PIN_S, * PKSPROPERTY_VBICODECFILTERING_STATISTICS_COMMON_PIN_S; - -typedef struct -{ - KSPROPERTY Property; - VBICODECFILTERING_STATISTICS_NABTS Statistics; -}KSPROPERTY_VBICODECFILTERING_STATISTICS_NABTS_S, * PKSPROPERTY_VBICODECFILTERING_STATISTICS_NABTS_S; - -typedef struct -{ - KSPROPERTY Property; - VBICODECFILTERING_STATISTICS_NABTS_PIN Statistics; -}KSPROPERTY_VBICODECFILTERING_STATISTICS_NABTS_PIN_S, * PKSPROPERTY_VBICODECFILTERING_STATISTICS_NABTS_PIN_S; - -typedef struct -{ - KSPROPERTY Property; - VBICODECFILTERING_STATISTICS_CC Statistics; -}KSPROPERTY_VBICODECFILTERING_STATISTICS_CC_S, * PKSPROPERTY_VBICODECFILTERING_STATISTICS_CC_S; - -typedef struct -{ - KSPROPERTY Property; - VBICODECFILTERING_STATISTICS_CC_PIN Statistics; -}KSPROPERTY_VBICODECFILTERING_STATISTICS_CC_PIN_S, * PKSPROPERTY_VBICODECFILTERING_STATISTICS_CC_PIN_S; - - # define STATIC_PINNAME_VIDEO_CAPTURE \ - 0xfb6c4281, 0x353, 0x11d1, 0x90, 0x5f, 0x0, 0x0, 0xc0, 0xcc, 0x16, 0xba - # define STATIC_PINNAME_CAPTURE STATIC_PINNAME_VIDEO_CAPTURE -DEFINE_GUIDSTRUCT("FB6C4281-0353-11d1-905F-0000C0CC16BA", PINNAME_VIDEO_CAPTURE); - # define PINNAME_VIDEO_CAPTURE DEFINE_GUIDNAMED(PINNAME_VIDEO_CAPTURE) - # define PINNAME_CAPTURE PINNAME_VIDEO_CAPTURE - - # define STATIC_PINNAME_VIDEO_CC_CAPTURE \ - 0x1aad8061, 0x12d, 0x11d2, 0xb4, 0xb1, 0x0, 0xa0, 0xd1, 0x2, 0xcf, 0xbe - # define STATIC_PINNAME_CC_CAPTURE STATIC_PINNAME_VIDEO_CC_CAPTURE -DEFINE_GUIDSTRUCT("1AAD8061-012D-11d2-B4B1-00A0D102CFBE", PINNAME_VIDEO_CC_CAPTURE); - # define PINNAME_VIDEO_CC_CAPTURE DEFINE_GUIDNAMED(PINNAME_VIDEO_CC_CAPTURE) - - # define STATIC_PINNAME_VIDEO_NABTS_CAPTURE \ - 0x29703660, 0x498a, 0x11d2, 0xb4, 0xb1, 0x0, 0xa0, 0xd1, 0x2, 0xcf, 0xbe - # define STATIC_PINNAME_NABTS_CAPTURE STATIC_PINNAME_VIDEO_NABTS_CAPTURE -DEFINE_GUIDSTRUCT("29703660-498A-11d2-B4B1-00A0D102CFBE", PINNAME_VIDEO_NABTS_CAPTURE); - # define PINNAME_VIDEO_NABTS_CAPTURE DEFINE_GUIDNAMED(PINNAME_VIDEO_NABTS_CAPTURE) - - # define STATIC_PINNAME_VIDEO_PREVIEW \ - 0xfb6c4282, 0x353, 0x11d1, 0x90, 0x5f, 0x0, 0x0, 0xc0, 0xcc, 0x16, 0xba - # define STATIC_PINNAME_PREVIEW STATIC_PINNAME_VIDEO_PREVIEW -DEFINE_GUIDSTRUCT("FB6C4282-0353-11d1-905F-0000C0CC16BA", PINNAME_VIDEO_PREVIEW); - # define PINNAME_VIDEO_PREVIEW DEFINE_GUIDNAMED(PINNAME_VIDEO_PREVIEW) - # define PINNAME_PREVIEW PINNAME_VIDEO_PREVIEW - - # define STATIC_PINNAME_VIDEO_ANALOGVIDEOIN \ - 0xfb6c4283, 0x353, 0x11d1, 0x90, 0x5f, 0x0, 0x0, 0xc0, 0xcc, 0x16, 0xba -DEFINE_GUIDSTRUCT("FB6C4283-0353-11d1-905F-0000C0CC16BA", PINNAME_VIDEO_ANALOGVIDEOIN); - # define PINNAME_VIDEO_ANALOGVIDEOIN DEFINE_GUIDNAMED(PINNAME_VIDEO_ANALOGVIDEOIN) - - # define STATIC_PINNAME_VIDEO_VBI \ - 0xfb6c4284, 0x353, 0x11d1, 0x90, 0x5f, 0x0, 0x0, 0xc0, 0xcc, 0x16, 0xba -DEFINE_GUIDSTRUCT("FB6C4284-0353-11d1-905F-0000C0CC16BA", PINNAME_VIDEO_VBI); - # define PINNAME_VIDEO_VBI DEFINE_GUIDNAMED(PINNAME_VIDEO_VBI) - - # define STATIC_PINNAME_VIDEO_VIDEOPORT \ - 0xfb6c4285, 0x353, 0x11d1, 0x90, 0x5f, 0x0, 0x0, 0xc0, 0xcc, 0x16, 0xba -DEFINE_GUIDSTRUCT("FB6C4285-0353-11d1-905F-0000C0CC16BA", PINNAME_VIDEO_VIDEOPORT); - # define PINNAME_VIDEO_VIDEOPORT DEFINE_GUIDNAMED(PINNAME_VIDEO_VIDEOPORT) - - # define STATIC_PINNAME_VIDEO_NABTS \ - 0xfb6c4286, 0x353, 0x11d1, 0x90, 0x5f, 0x0, 0x0, 0xc0, 0xcc, 0x16, 0xba -DEFINE_GUIDSTRUCT("FB6C4286-0353-11d1-905F-0000C0CC16BA", PINNAME_VIDEO_NABTS); - # define PINNAME_VIDEO_NABTS DEFINE_GUIDNAMED(PINNAME_VIDEO_NABTS) - - # define STATIC_PINNAME_VIDEO_EDS \ - 0xfb6c4287, 0x353, 0x11d1, 0x90, 0x5f, 0x0, 0x0, 0xc0, 0xcc, 0x16, 0xba -DEFINE_GUIDSTRUCT("FB6C4287-0353-11d1-905F-0000C0CC16BA", PINNAME_VIDEO_EDS); - # define PINNAME_VIDEO_EDS DEFINE_GUIDNAMED(PINNAME_VIDEO_EDS) - - # define STATIC_PINNAME_VIDEO_TELETEXT \ - 0xfb6c4288, 0x353, 0x11d1, 0x90, 0x5f, 0x0, 0x0, 0xc0, 0xcc, 0x16, 0xba -DEFINE_GUIDSTRUCT("FB6C4288-0353-11d1-905F-0000C0CC16BA", PINNAME_VIDEO_TELETEXT); - # define PINNAME_VIDEO_TELETEXT DEFINE_GUIDNAMED(PINNAME_VIDEO_TELETEXT) - - # define STATIC_PINNAME_VIDEO_CC \ - 0xfb6c4289, 0x353, 0x11d1, 0x90, 0x5f, 0x0, 0x0, 0xc0, 0xcc, 0x16, 0xba -DEFINE_GUIDSTRUCT("FB6C4289-0353-11d1-905F-0000C0CC16BA", PINNAME_VIDEO_CC); - # define PINNAME_VIDEO_CC DEFINE_GUIDNAMED(PINNAME_VIDEO_CC) - - # define STATIC_PINNAME_VIDEO_STILL \ - 0xfb6c428A, 0x353, 0x11d1, 0x90, 0x5f, 0x0, 0x0, 0xc0, 0xcc, 0x16, 0xba -DEFINE_GUIDSTRUCT("FB6C428A-0353-11d1-905F-0000C0CC16BA", PINNAME_VIDEO_STILL); - # define PINNAME_VIDEO_STILL DEFINE_GUIDNAMED(PINNAME_VIDEO_STILL) - - # define STATIC_PINNAME_VIDEO_TIMECODE \ - 0xfb6c428B, 0x353, 0x11d1, 0x90, 0x5f, 0x0, 0x0, 0xc0, 0xcc, 0x16, 0xba -DEFINE_GUIDSTRUCT("FB6C428B-0353-11d1-905F-0000C0CC16BA", PINNAME_VIDEO_TIMECODE); - # define PINNAME_VIDEO_TIMECODE DEFINE_GUIDNAMED(PINNAME_VIDEO_TIMECODE) - - # define STATIC_PINNAME_VIDEO_VIDEOPORT_VBI \ - 0xfb6c428C, 0x353, 0x11d1, 0x90, 0x5f, 0x0, 0x0, 0xc0, 0xcc, 0x16, 0xba -DEFINE_GUIDSTRUCT("FB6C428C-0353-11d1-905F-0000C0CC16BA", PINNAME_VIDEO_VIDEOPORT_VBI); - # define PINNAME_VIDEO_VIDEOPORT_VBI DEFINE_GUIDNAMED(PINNAME_VIDEO_VIDEOPORT_VBI) - - # define KS_VIDEO_FLAG_FRAME 0x0000L - # define KS_VIDEO_FLAG_FIELD1 0x0001L - # define KS_VIDEO_FLAG_FIELD2 0x0002L - - # define KS_VIDEO_FLAG_I_FRAME 0x0000L - # define KS_VIDEO_FLAG_P_FRAME 0x0010L - # define KS_VIDEO_FLAG_B_FRAME 0x0020L - -typedef struct tagKS_FRAME_INFO -{ - ULONG ExtendedHeaderSize; - DWORD dwFrameFlags; - LONGLONG PictureNumber; - LONGLONG DropCount; - HANDLE hDirectDraw; - HANDLE hSurfaceHandle; - RECT DirectDrawRect; - - DWORD Reserved1; - DWORD Reserved2; - DWORD Reserved3; - DWORD Reserved4; -}KS_FRAME_INFO, * PKS_FRAME_INFO; - - # define KS_VBI_FLAG_FIELD1 0x0001L - # define KS_VBI_FLAG_FIELD2 0x0002L - - # define KS_VBI_FLAG_MV_PRESENT 0x0100L - # define KS_VBI_FLAG_MV_HARDWARE 0x0200L - # define KS_VBI_FLAG_MV_DETECTED 0x0400L - - # define KS_VBI_FLAG_TVTUNER_CHANGE 0x0010L - # define KS_VBI_FLAG_VBIINFOHEADER_CHANGE 0x0020L - -typedef struct tagKS_VBI_FRAME_INFO -{ - ULONG ExtendedHeaderSize; - DWORD dwFrameFlags; - LONGLONG PictureNumber; - LONGLONG DropCount; - DWORD dwSamplingFrequency; - KS_TVTUNER_CHANGE_INFO TvTunerChangeInfo; - KS_VBIINFOHEADER VBIInfoHeader; -}KS_VBI_FRAME_INFO, * PKS_VBI_FRAME_INFO; - -typedef enum -{ - KS_AnalogVideo_None = 0x00000000, - KS_AnalogVideo_NTSC_M = 0x00000001, - KS_AnalogVideo_NTSC_M_J = 0x00000002, - KS_AnalogVideo_NTSC_433 = 0x00000004, - KS_AnalogVideo_PAL_B = 0x00000010, - KS_AnalogVideo_PAL_D = 0x00000020, - KS_AnalogVideo_PAL_G = 0x00000040, - KS_AnalogVideo_PAL_H = 0x00000080, - KS_AnalogVideo_PAL_I = 0x00000100, - KS_AnalogVideo_PAL_M = 0x00000200, - KS_AnalogVideo_PAL_N = 0x00000400, - KS_AnalogVideo_PAL_60 = 0x00000800, - KS_AnalogVideo_SECAM_B = 0x00001000, - KS_AnalogVideo_SECAM_D = 0x00002000, - KS_AnalogVideo_SECAM_G = 0x00004000, - KS_AnalogVideo_SECAM_H = 0x00008000, - KS_AnalogVideo_SECAM_K = 0x00010000, - KS_AnalogVideo_SECAM_K1 = 0x00020000, - KS_AnalogVideo_SECAM_L = 0x00040000, - KS_AnalogVideo_SECAM_L1 = 0x00080000, - KS_AnalogVideo_PAL_N_COMBO = 0x00100000 -}KS_AnalogVideoStandard; - - # define KS_AnalogVideo_NTSC_Mask 0x00000007 - # define KS_AnalogVideo_PAL_Mask 0x00100FF0 - # define KS_AnalogVideo_SECAM_Mask 0x000FF000 - - # define STATIC_PROPSETID_ALLOCATOR_CONTROL \ - 0x53171960, 0x148e, 0x11d2, 0x99, 0x79, 0x0, 0x0, 0xc0, 0xcc, 0x16, 0xba -DEFINE_GUIDSTRUCT("53171960-148E-11d2-9979-0000C0CC16BA", PROPSETID_ALLOCATOR_CONTROL); - # define PROPSETID_ALLOCATOR_CONTROL DEFINE_GUIDNAMED(PROPSETID_ALLOCATOR_CONTROL) - -typedef enum -{ - KSPROPERTY_ALLOCATOR_CONTROL_HONOR_COUNT, - KSPROPERTY_ALLOCATOR_CONTROL_SURFACE_SIZE, - KSPROPERTY_ALLOCATOR_CONTROL_CAPTURE_CAPS, - KSPROPERTY_ALLOCATOR_CONTROL_CAPTURE_INTERLEAVE -}KSPROPERTY_ALLOCATOR_CONTROL; - -typedef struct -{ - ULONG CX; - ULONG CY; -}KSPROPERTY_ALLOCATOR_CONTROL_SURFACE_SIZE_S, * PKSPROPERTY_ALLOCATOR_CONTROL_SURFACE_SIZE_S; - -typedef struct -{ - ULONG InterleavedCapSupported; -}KSPROPERTY_ALLOCATOR_CONTROL_CAPTURE_CAPS_S, * PKSPROPERTY_ALLOCATOR_CONTROL_CAPTURE_CAPS_S; - -typedef struct -{ - ULONG InterleavedCapPossible; -}KSPROPERTY_ALLOCATOR_CONTROL_CAPTURE_INTERLEAVE_S, * PKSPROPERTY_ALLOCATOR_CONTROL_CAPTURE_INTERLEAVE_S; - - # define STATIC_PROPSETID_VIDCAP_VIDEOPROCAMP \ - 0xC6E13360L, 0x30AC, 0x11d0, 0xa1, 0x8c, 0x00, 0xA0, 0xC9, 0x11, 0x89, 0x56 -DEFINE_GUIDSTRUCT("C6E13360-30AC-11d0-A18C-00A0C9118956", PROPSETID_VIDCAP_VIDEOPROCAMP); - # define PROPSETID_VIDCAP_VIDEOPROCAMP DEFINE_GUIDNAMED(PROPSETID_VIDCAP_VIDEOPROCAMP) - -typedef enum -{ - KSPROPERTY_VIDEOPROCAMP_BRIGHTNESS, - KSPROPERTY_VIDEOPROCAMP_CONTRAST, - KSPROPERTY_VIDEOPROCAMP_HUE, - KSPROPERTY_VIDEOPROCAMP_SATURATION, - KSPROPERTY_VIDEOPROCAMP_SHARPNESS, - KSPROPERTY_VIDEOPROCAMP_GAMMA, - KSPROPERTY_VIDEOPROCAMP_COLORENABLE, - KSPROPERTY_VIDEOPROCAMP_WHITEBALANCE, - KSPROPERTY_VIDEOPROCAMP_BACKLIGHT_COMPENSATION, - KSPROPERTY_VIDEOPROCAMP_GAIN, - KSPROPERTY_VIDEOPROCAMP_DIGITAL_MULTIPLIER, - KSPROPERTY_VIDEOPROCAMP_DIGITAL_MULTIPLIER_LIMIT, - KSPROPERTY_VIDEOPROCAMP_WHITEBALANCE_COMPONENT, - KSPROPERTY_VIDEOPROCAMP_POWERLINE_FREQUENCY -}KSPROPERTY_VIDCAP_VIDEOPROCAMP; - -typedef struct -{ - KSPROPERTY Property; - LONG Value; - ULONG Flags; - ULONG Capabilities; -}KSPROPERTY_VIDEOPROCAMP_S, * PKSPROPERTY_VIDEOPROCAMP_S; - -typedef struct -{ - KSP_NODE NodeProperty; - LONG Value; - ULONG Flags; - ULONG Capabilities; -}KSPROPERTY_VIDEOPROCAMP_NODE_S, * PKSPROPERTY_VIDEOPROCAMP_NODE_S; - -typedef struct -{ - KSPROPERTY Property; - LONG Value1; - ULONG Flags; - ULONG Capabilities; - LONG Value2; -}KSPROPERTY_VIDEOPROCAMP_S2, * PKSPROPERTY_VIDEOPROCAMP_S2; - -typedef struct -{ - KSP_NODE NodeProperty; - LONG Value1; - ULONG Flags; - ULONG Capabilities; - LONG Value2; -}KSPROPERTY_VIDEOPROCAMP_NODE_S2, * PKSPROPERTY_VIDEOPROCAMP_NODE_S2; - - # define KSPROPERTY_VIDEOPROCAMP_FLAGS_AUTO 0X0001L - # define KSPROPERTY_VIDEOPROCAMP_FLAGS_MANUAL 0X0002L - - # define STATIC_PROPSETID_VIDCAP_SELECTOR \ - 0x1ABDAECA, 0x68B6, 0x4F83, 0x93, 0x71, 0xB4, 0x13, 0x90, 0x7C, 0x7B, 0x9F -DEFINE_GUIDSTRUCT("1ABDAECA-68B6-4F83-9371-B413907C7B9F", PROPSETID_VIDCAP_SELECTOR); - # define PROPSETID_VIDCAP_SELECTOR DEFINE_GUIDNAMED(PROPSETID_VIDCAP_SELECTOR) - -typedef enum -{ - KSPROPERTY_SELECTOR_SOURCE_NODE_ID, - KSPROPERTY_SELECTOR_NUM_SOURCES -}KSPROPERTY_VIDCAP_SELECTOR, * PKSPROPERTY_VIDCAP_SELECTOR; - -typedef struct -{ - KSPROPERTY Property; - LONG Value; - ULONG Flags; - ULONG Capabilities; -}KSPROPERTY_SELECTOR_S, * PKSPROPERTY_SELECTOR_S; - -typedef struct -{ - KSP_NODE NodeProperty; - LONG Value; - ULONG Flags; - ULONG Capabilities; -}KSPROPERTY_SELECTOR_NODE_S, * PKSPROPERTY_SELECTOR_NODE_S; - - # define STATIC_PROPSETID_TUNER \ - 0x6a2e0605L, 0x28e4, 0x11d0, 0xa1, 0x8c, 0x00, 0xa0, 0xc9, 0x11, 0x89, 0x56 -DEFINE_GUIDSTRUCT("6a2e0605-28e4-11d0-a18c-00a0c9118956", PROPSETID_TUNER); - # define PROPSETID_TUNER DEFINE_GUIDNAMED(PROPSETID_TUNER) - -typedef enum -{ - KSPROPERTY_TUNER_CAPS, - KSPROPERTY_TUNER_MODE_CAPS, - KSPROPERTY_TUNER_MODE, - KSPROPERTY_TUNER_STANDARD, - KSPROPERTY_TUNER_FREQUENCY, - KSPROPERTY_TUNER_INPUT, - KSPROPERTY_TUNER_STATUS, - KSPROPERTY_TUNER_IF_MEDIUM -}KSPROPERTY_TUNER; - -typedef enum -{ - KSPROPERTY_TUNER_MODE_TV = 0X0001, - KSPROPERTY_TUNER_MODE_FM_RADIO = 0X0002, - KSPROPERTY_TUNER_MODE_AM_RADIO = 0X0004, - KSPROPERTY_TUNER_MODE_DSS = 0X0008, - KSPROPERTY_TUNER_MODE_ATSC = 0X0010 -}KSPROPERTY_TUNER_MODES; - -typedef enum -{ - KS_TUNER_TUNING_EXACT = 1, - KS_TUNER_TUNING_FINE, - KS_TUNER_TUNING_COARSE -}KS_TUNER_TUNING_FLAGS; - -typedef enum -{ - KS_TUNER_STRATEGY_PLL = 0X01, - KS_TUNER_STRATEGY_SIGNAL_STRENGTH = 0X02, - KS_TUNER_STRATEGY_DRIVER_TUNES = 0X04 -}KS_TUNER_STRATEGY; - -typedef struct -{ - KSPROPERTY Property; - ULONG ModesSupported; - KSPIN_MEDIUM VideoMedium; - KSPIN_MEDIUM TVAudioMedium; - KSPIN_MEDIUM RadioAudioMedium; -}KSPROPERTY_TUNER_CAPS_S, * PKSPROPERTY_TUNER_CAPS_S; - -typedef struct -{ - KSPROPERTY Property; - KSPIN_MEDIUM IFMedium; -}KSPROPERTY_TUNER_IF_MEDIUM_S, * PKSPROPERTY_TUNER_IF_MEDIUM_S; - -typedef struct -{ - KSPROPERTY Property; - ULONG Mode; - ULONG StandardsSupported; - ULONG MinFrequency; - ULONG MaxFrequency; - ULONG TuningGranularity; - ULONG NumberOfInputs; - ULONG SettlingTime; - ULONG Strategy; -}KSPROPERTY_TUNER_MODE_CAPS_S, * PKSPROPERTY_TUNER_MODE_CAPS_S; - -typedef struct -{ - KSPROPERTY Property; - ULONG Mode; -}KSPROPERTY_TUNER_MODE_S, * PKSPROPERTY_TUNER_MODE_S; - -typedef struct -{ - KSPROPERTY Property; - ULONG Frequency; - ULONG LastFrequency; - ULONG TuningFlags; - ULONG VideoSubChannel; - ULONG AudioSubChannel; - ULONG Channel; - ULONG Country; -}KSPROPERTY_TUNER_FREQUENCY_S, * PKSPROPERTY_TUNER_FREQUENCY_S; - -typedef struct -{ - KSPROPERTY Property; - ULONG Standard; -}KSPROPERTY_TUNER_STANDARD_S, * PKSPROPERTY_TUNER_STANDARD_S; - -typedef struct -{ - KSPROPERTY Property; - ULONG InputIndex; -}KSPROPERTY_TUNER_INPUT_S, * PKSPROPERTY_TUNER_INPUT_S; - -typedef struct -{ - KSPROPERTY Property; - ULONG CurrentFrequency; - ULONG PLLOffset; - ULONG SignalStrength; - ULONG Busy; -}KSPROPERTY_TUNER_STATUS_S, * PKSPROPERTY_TUNER_STATUS_S; - - # define STATIC_EVENTSETID_TUNER \ - 0x6a2e0606L, 0x28e4, 0x11d0, 0xa1, 0x8c, 0x00, 0xa0, 0xc9, 0x11, 0x89, 0x56 -DEFINE_GUIDSTRUCT("6a2e0606-28e4-11d0-a18c-00a0c9118956", EVENTSETID_TUNER); - # define EVENTSETID_TUNER DEFINE_GUIDNAMED(EVENTSETID_TUNER) - -typedef enum -{ - KSEVENT_TUNER_CHANGED -}KSEVENT_TUNER; - - # define STATIC_KSNODETYPE_VIDEO_STREAMING \ - 0xDFF229E1L, 0xF70F, 0x11D0, 0xB9, 0x17, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96 -DEFINE_GUIDSTRUCT("DFF229E1-F70F-11D0-B917-00A0C9223196", KSNODETYPE_VIDEO_STREAMING); - # define KSNODETYPE_VIDEO_STREAMING DEFINE_GUIDNAMED(KSNODETYPE_VIDEO_STREAMING) - - # define STATIC_KSNODETYPE_VIDEO_INPUT_TERMINAL \ - 0xDFF229E2L, 0xF70F, 0x11D0, 0xB9, 0x17, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96 -DEFINE_GUIDSTRUCT("DFF229E2-F70F-11D0-B917-00A0C9223196", KSNODETYPE_VIDEO_INPUT_TERMINAL); - # define KSNODETYPE_VIDEO_INPUT_TERMINAL DEFINE_GUIDNAMED(KSNODETYPE_VIDEO_INPUT_TERMINAL) - - # define STATIC_KSNODETYPE_VIDEO_OUTPUT_TERMINAL \ - 0xDFF229E3L, 0xF70F, 0x11D0, 0xB9, 0x17, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96 -DEFINE_GUIDSTRUCT("DFF229E3-F70F-11D0-B917-00A0C9223196", KSNODETYPE_VIDEO_OUTPUT_TERMINAL); - # define KSNODETYPE_VIDEO_OUTPUT_TERMINAL DEFINE_GUIDNAMED(KSNODETYPE_VIDEO_OUTPUT_TERMINAL) - - # define STATIC_KSNODETYPE_VIDEO_SELECTOR \ - 0xDFF229E4L, 0xF70F, 0x11D0, 0xB9, 0x17, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96 -DEFINE_GUIDSTRUCT("DFF229E4-F70F-11D0-B917-00A0C9223196", KSNODETYPE_VIDEO_SELECTOR); - # define KSNODETYPE_VIDEO_SELECTOR DEFINE_GUIDNAMED(KSNODETYPE_VIDEO_SELECTOR) - - # define STATIC_KSNODETYPE_VIDEO_PROCESSING \ - 0xDFF229E5L, 0xF70F, 0x11D0, 0xB9, 0x17, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96 -DEFINE_GUIDSTRUCT("DFF229E5-F70F-11D0-B917-00A0C9223196", KSNODETYPE_VIDEO_PROCESSING); - # define KSNODETYPE_VIDEO_PROCESSING DEFINE_GUIDNAMED(KSNODETYPE_VIDEO_PROCESSING) - - # define STATIC_KSNODETYPE_VIDEO_CAMERA_TERMINAL \ - 0xDFF229E6L, 0xF70F, 0x11D0, 0xB9, 0x17, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96 -DEFINE_GUIDSTRUCT("DFF229E6-F70F-11D0-B917-00A0C9223196", KSNODETYPE_VIDEO_CAMERA_TERMINAL); - # define KSNODETYPE_VIDEO_CAMERA_TERMINAL DEFINE_GUIDNAMED(KSNODETYPE_VIDEO_CAMERA_TERMINAL) - - # define STATIC_KSNODETYPE_VIDEO_INPUT_MTT \ - 0xDFF229E7L, 0xF70F, 0x11D0, 0xB9, 0x17, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96 -DEFINE_GUIDSTRUCT("DFF229E7-F70F-11D0-B917-00A0C9223196", KSNODETYPE_VIDEO_INPUT_MTT); - # define KSNODETYPE_VIDEO_INPUT_MTT DEFINE_GUIDNAMED(KSNODETYPE_VIDEO_INPUT_MTT) - - # define STATIC_KSNODETYPE_VIDEO_OUTPUT_MTT \ - 0xDFF229E8L, 0xF70F, 0x11D0, 0xB9, 0x17, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96 -DEFINE_GUIDSTRUCT("DFF229E8-F70F-11D0-B917-00A0C9223196", KSNODETYPE_VIDEO_OUTPUT_MTT); - # define KSNODETYPE_VIDEO_OUTPUT_MTT DEFINE_GUIDNAMED(KSNODETYPE_VIDEO_OUTPUT_MTT) - - # define STATIC_PROPSETID_VIDCAP_VIDEOENCODER \ - 0x6a2e0610L, 0x28e4, 0x11d0, 0xa1, 0x8c, 0x00, 0xa0, 0xc9, 0x11, 0x89, 0x56 -DEFINE_GUIDSTRUCT("6a2e0610-28e4-11d0-a18c-00a0c9118956", PROPSETID_VIDCAP_VIDEOENCODER); - # define PROPSETID_VIDCAP_VIDEOENCODER DEFINE_GUIDNAMED(PROPSETID_VIDCAP_VIDEOENCODER) - -typedef enum -{ - KSPROPERTY_VIDEOENCODER_CAPS, - KSPROPERTY_VIDEOENCODER_STANDARD, - KSPROPERTY_VIDEOENCODER_COPYPROTECTION, - KSPROPERTY_VIDEOENCODER_CC_ENABLE -}KSPROPERTY_VIDCAP_VIDEOENCODER; - -typedef struct -{ - KSPROPERTY Property; - LONG Value; - ULONG Flags; - ULONG Capabilities; -}KSPROPERTY_VIDEOENCODER_S, * PKSPROPERTY_VIDEOENCODER_S; - - # define STATIC_PROPSETID_VIDCAP_VIDEODECODER \ - 0xC6E13350L, 0x30AC, 0x11d0, 0xA1, 0x8C, 0x00, 0xA0, 0xC9, 0x11, 0x89, 0x56 -DEFINE_GUIDSTRUCT("C6E13350-30AC-11d0-A18C-00A0C9118956", PROPSETID_VIDCAP_VIDEODECODER); - # define PROPSETID_VIDCAP_VIDEODECODER DEFINE_GUIDNAMED(PROPSETID_VIDCAP_VIDEODECODER) - -typedef enum -{ - KSPROPERTY_VIDEODECODER_CAPS, - KSPROPERTY_VIDEODECODER_STANDARD, - KSPROPERTY_VIDEODECODER_STATUS, - KSPROPERTY_VIDEODECODER_OUTPUT_ENABLE, - KSPROPERTY_VIDEODECODER_VCR_TIMING -}KSPROPERTY_VIDCAP_VIDEODECODER; - -typedef enum -{ - KS_VIDEODECODER_FLAGS_CAN_DISABLE_OUTPUT = 0X0001, - KS_VIDEODECODER_FLAGS_CAN_USE_VCR_LOCKING = 0X0002, - KS_VIDEODECODER_FLAGS_CAN_INDICATE_LOCKED = 0X0004 -}KS_VIDEODECODER_FLAGS; - -typedef struct -{ - KSPROPERTY Property; - ULONG StandardsSupported; - ULONG Capabilities; - ULONG SettlingTime; - ULONG HSyncPerVSync; -}KSPROPERTY_VIDEODECODER_CAPS_S, * PKSPROPERTY_VIDEODECODER_CAPS_S; - -typedef struct -{ - KSPROPERTY Property; - ULONG NumberOfLines; - ULONG SignalLocked; -}KSPROPERTY_VIDEODECODER_STATUS_S, * PKSPROPERTY_VIDEODECODER_STATUS_S; - -typedef struct -{ - KSPROPERTY Property; - ULONG Value; -}KSPROPERTY_VIDEODECODER_S, * PKSPROPERTY_VIDEODECODER_S; - - # define STATIC_EVENTSETID_VIDEODECODER \ - 0x6a2e0621L, 0x28e4, 0x11d0, 0xa1, 0x8c, 0x00, 0xa0, 0xc9, 0x11, 0x89, 0x56 -DEFINE_GUIDSTRUCT("6a2e0621-28e4-11d0-a18c-00a0c9118956", EVENTSETID_VIDEODECODER); - # define EVENTSETID_VIDEODECODER DEFINE_GUIDNAMED(EVENTSETID_VIDEODECODER) - -typedef enum -{ - KSEVENT_VIDEODECODER_CHANGED -}KSEVENT_VIDEODECODER; - - # define STATIC_PROPSETID_VIDCAP_CAMERACONTROL \ - 0xC6E13370L, 0x30AC, 0x11d0, 0xa1, 0x8C, 0x00, 0xA0, 0xC9, 0x11, 0x89, 0x56 -DEFINE_GUIDSTRUCT("C6E13370-30AC-11d0-A18C-00A0C9118956", PROPSETID_VIDCAP_CAMERACONTROL); - # define PROPSETID_VIDCAP_CAMERACONTROL DEFINE_GUIDNAMED(PROPSETID_VIDCAP_CAMERACONTROL) - -typedef enum -{ - KSPROPERTY_CAMERACONTROL_PAN, - KSPROPERTY_CAMERACONTROL_TILT, - KSPROPERTY_CAMERACONTROL_ROLL, - KSPROPERTY_CAMERACONTROL_ZOOM, - KSPROPERTY_CAMERACONTROL_EXPOSURE, - KSPROPERTY_CAMERACONTROL_IRIS, - KSPROPERTY_CAMERACONTROL_FOCUS, - KSPROPERTY_CAMERACONTROL_SCANMODE, - KSPROPERTY_CAMERACONTROL_PRIVACY, - KSPROPERTY_CAMERACONTROL_PANTILT, - KSPROPERTY_CAMERACONTROL_PAN_RELATIVE, - KSPROPERTY_CAMERACONTROL_TILT_RELATIVE, - KSPROPERTY_CAMERACONTROL_ROLL_RELATIVE, - KSPROPERTY_CAMERACONTROL_ZOOM_RELATIVE, - KSPROPERTY_CAMERACONTROL_EXPOSURE_RELATIVE, - KSPROPERTY_CAMERACONTROL_IRIS_RELATIVE, - KSPROPERTY_CAMERACONTROL_FOCUS_RELATIVE, - KSPROPERTY_CAMERACONTROL_PANTILT_RELATIVE, - KSPROPERTY_CAMERACONTROL_FOCAL_LENGTH -}KSPROPERTY_VIDCAP_CAMERACONTROL; - -typedef struct -{ - KSPROPERTY Property; - LONG Value; - ULONG Flags; - ULONG Capabilities; -}KSPROPERTY_CAMERACONTROL_S, * PKSPROPERTY_CAMERACONTROL_S; - -typedef struct -{ - KSP_NODE NodeProperty; - LONG Value; - ULONG Flags; - ULONG Capabilities; -}KSPROPERTY_CAMERACONTROL_NODE_S, PKSPROPERTY_CAMERACONTROL_NODE_S; - -typedef struct -{ - KSPROPERTY Property; - LONG Value1; - ULONG Flags; - ULONG Capabilities; - LONG Value2; -}KSPROPERTY_CAMERACONTROL_S2, * PKSPROPERTY_CAMERACONTROL_S2; - -typedef struct -{ - KSP_NODE NodeProperty; - LONG Value1; - ULONG Flags; - ULONG Capabilities; - LONG Value2; -}KSPROPERTY_CAMERACONTROL_NODE_S2, * PKSPROPERTY_CAMERACONTROL_NODE_S2; - -typedef struct -{ - KSPROPERTY Property; - LONG lOcularFocalLength; - LONG lObjectiveFocalLengthMin; - LONG lObjectiveFocalLengthMax; -}KSPROPERTY_CAMERACONTROL_FOCAL_LENGTH_S, * PKSPROPERTY_CAMERACONTROL_FOCAL_LENGTH_S; - -typedef struct -{ - KSNODEPROPERTY NodeProperty; - LONG lOcularFocalLength; - LONG lObjectiveFocalLengthMin; - LONG lObjectiveFocalLengthMax; -}KSPROPERTY_CAMERACONTROL_NODE_FOCAL_LENGTH_S, * PKSPROPERTY_CAMERACONTROL_NODE_FOCAL_LENGTH_S; - - # define KSPROPERTY_CAMERACONTROL_FLAGS_AUTO 0X0001L - # define KSPROPERTY_CAMERACONTROL_FLAGS_MANUAL 0X0002L - - # define KSPROPERTY_CAMERACONTROL_FLAGS_ABSOLUTE 0X0000L - # define KSPROPERTY_CAMERACONTROL_FLAGS_RELATIVE 0X0010L - - # ifndef __EDevCtrl__ - # define __EDevCtrl__ - - # define STATIC_PROPSETID_EXT_DEVICE \ - 0xB5730A90L, 0x1A2C, 0x11cf, 0x8c, 0x23, 0x00, 0xAA, 0x00, 0x6B, 0x68, 0x14 -DEFINE_GUIDSTRUCT("B5730A90-1A2C-11cf-8C23-00AA006B6814", PROPSETID_EXT_DEVICE); - # define PROPSETID_EXT_DEVICE DEFINE_GUIDNAMED(PROPSETID_EXT_DEVICE) - -typedef enum -{ - KSPROPERTY_EXTDEVICE_ID, - KSPROPERTY_EXTDEVICE_VERSION, - KSPROPERTY_EXTDEVICE_POWER_STATE, - KSPROPERTY_EXTDEVICE_PORT, - KSPROPERTY_EXTDEVICE_CAPABILITIES -}KSPROPERTY_EXTDEVICE; - -typedef struct tagDEVCAPS -{ - LONG CanRecord; - LONG CanRecordStrobe; - LONG HasAudio; - LONG HasVideo; - LONG UsesFiles; - LONG CanSave; - LONG DeviceType; - LONG TCRead; - LONG TCWrite; - LONG CTLRead; - LONG IndexRead; - LONG Preroll; - LONG Postroll; - LONG SyncAcc; - LONG NormRate; - LONG CanPreview; - LONG CanMonitorSrc; - LONG CanTest; - LONG VideoIn; - LONG AudioIn; - LONG Calibrate; - LONG SeekType; - LONG SimulatedHardware; -}DEVCAPS, * PDEVCAPS; - -typedef struct -{ - KSPROPERTY Property; - union - { - DEVCAPS Capabilities; - ULONG DevPort; - ULONG PowerState; - WCHAR pawchString[MAX_PATH]; - DWORD NodeUniqueID[2]; - }u; -}KSPROPERTY_EXTDEVICE_S, * PKSPROPERTY_EXTDEVICE_S; - - # define STATIC_PROPSETID_EXT_TRANSPORT \ - 0xA03CD5F0L, 0x3045, 0x11cf, 0x8c, 0x44, 0x00, 0xAA, 0x00, 0x6B, 0x68, 0x14 -DEFINE_GUIDSTRUCT("A03CD5F0-3045-11cf-8C44-00AA006B6814", PROPSETID_EXT_TRANSPORT); - # define PROPSETID_EXT_TRANSPORT DEFINE_GUIDNAMED(PROPSETID_EXT_TRANSPORT) - -typedef enum -{ - KSPROPERTY_EXTXPORT_CAPABILITIES, - KSPROPERTY_EXTXPORT_INPUT_SIGNAL_MODE, - KSPROPERTY_EXTXPORT_OUTPUT_SIGNAL_MODE, - KSPROPERTY_EXTXPORT_LOAD_MEDIUM, - KSPROPERTY_EXTXPORT_MEDIUM_INFO, - KSPROPERTY_EXTXPORT_STATE, - KSPROPERTY_EXTXPORT_STATE_NOTIFY, - KSPROPERTY_EXTXPORT_TIMECODE_SEARCH, - KSPROPERTY_EXTXPORT_ATN_SEARCH, - KSPROPERTY_EXTXPORT_RTC_SEARCH, - KSPROPERTY_RAW_AVC_CMD -}KSPROPERTY_EXTXPORT; - -typedef struct tagTRANSPORTSTATUS -{ - LONG Mode; - LONG LastError; - LONG RecordInhibit; - LONG ServoLock; - LONG MediaPresent; - LONG MediaLength; - LONG MediaSize; - LONG MediaTrackCount; - LONG MediaTrackLength; - LONG MediaTrackSide; - LONG MediaType; - LONG LinkMode; - LONG NotifyOn; -}TRANSPORTSTATUS, * PTRANSPORTSTATUS; - -typedef struct tagTRANSPORTBASICPARMS -{ - LONG TimeFormat; - LONG TimeReference; - LONG Superimpose; - LONG EndStopAction; - LONG RecordFormat; - LONG StepFrames; - LONG SetpField; - LONG Preroll; - LONG RecPreroll; - LONG Postroll; - LONG EditDelay; - LONG PlayTCDelay; - LONG RecTCDelay; - LONG EditField; - LONG FrameServo; - LONG ColorFrameServo; - LONG ServoRef; - LONG WarnGenlock; - LONG SetTracking; - TCHAR VolumeName[40]; - LONG Ballistic[20]; - LONG Speed; - LONG CounterFormat; - LONG TunerChannel; - LONG TunerNumber; - LONG TimerEvent; - LONG TimerStartDay; - LONG TimerStartTime; - LONG TimerStopDay; - LONG TimerStopTime; -}TRANSPORTBASICPARMS, * PTRANSPORTBASICPARMS; - -typedef struct tagTRANSPORTVIDEOPARMS -{ - LONG OutputMode; - LONG Input; -}TRANSPORTVIDEOPARMS, * PTRANSPORTVIDEOPARMS; - -typedef struct tagTRANSPORTAUDIOPARMS -{ - LONG EnableOutput; - LONG EnableRecord; - LONG EnableSelsync; - LONG Input; - LONG MonitorSource; -}TRANSPORTAUDIOPARMS, * PTRANSPORTAUDIOPARMS; - -typedef struct -{ - WINBOOL MediaPresent; - ULONG MediaType; - WINBOOL RecordInhibit; -}MEDIUM_INFO, * PMEDIUM_INFO; - -typedef struct -{ - ULONG Mode; - ULONG State; -}TRANSPORT_STATE, * PTRANSPORT_STATE; - -typedef struct -{ - KSPROPERTY Property; - union - { - ULONG Capabilities; - ULONG SignalMode; - ULONG LoadMedium; - MEDIUM_INFO MediumInfo; - TRANSPORT_STATE XPrtState; - struct - { - BYTE frame; - BYTE second; - BYTE minute; - BYTE hour; - }Timecode; - DWORD dwTimecode; - DWORD dwAbsTrackNumber; - struct - { - ULONG PayloadSize; - BYTE Payload[512]; - }RawAVC; - }u; -}KSPROPERTY_EXTXPORT_S, * PKSPROPERTY_EXTXPORT_S; - -typedef struct -{ - KSP_NODE NodeProperty; - union - { - ULONG Capabilities; - ULONG SignalMode; - ULONG LoadMedium; - MEDIUM_INFO MediumInfo; - TRANSPORT_STATE XPrtState; - struct - { - BYTE frame; - BYTE second; - BYTE minute; - BYTE hour; - }Timecode; - DWORD dwTimecode; - DWORD dwAbsTrackNumber; - struct - { - ULONG PayloadSize; - BYTE Payload[512]; - }RawAVC; - }u; -}KSPROPERTY_EXTXPORT_NODE_S, * PKSPROPERTY_EXTXPORT_NODE_S; - - # define STATIC_PROPSETID_TIMECODE_READER \ - 0x9B496CE1L, 0x811B, 0x11cf, 0x8C, 0x77, 0x00, 0xAA, 0x00, 0x6B, 0x68, 0x14 -DEFINE_GUIDSTRUCT("9B496CE1-811B-11cf-8C77-00AA006B6814", PROPSETID_TIMECODE_READER); - # define PROPSETID_TIMECODE_READER DEFINE_GUIDNAMED(PROPSETID_TIMECODE_READER) - -typedef enum -{ - KSPROPERTY_TIMECODE_READER, - KSPROPERTY_ATN_READER, - KSPROPERTY_RTC_READER -}KSPROPERTY_TIMECODE; - - # ifndef TIMECODE_DEFINED - # define TIMECODE_DEFINED -typedef union _timecode -{ - struct - { - WORD wFrameRate; - WORD wFrameFract; - DWORD dwFrames; - }; - DWORDLONG qw; -}TIMECODE; -typedef TIMECODE* PTIMECODE; - -typedef struct tagTIMECODE_SAMPLE -{ - LONGLONG qwTick; - TIMECODE timecode; - DWORD dwUser; - DWORD dwFlags; -}TIMECODE_SAMPLE; - -typedef TIMECODE_SAMPLE* PTIMECODE_SAMPLE; - # endif /* TIMECODE_DEFINED */ - -typedef struct -{ - KSPROPERTY Property; - TIMECODE_SAMPLE TimecodeSamp; -}KSPROPERTY_TIMECODE_S, * PKSPROPERTY_TIMECODE_S; - -typedef struct -{ - KSP_NODE NodeProperty; - TIMECODE_SAMPLE TimecodeSamp; -}KSPROPERTY_TIMECODE_NODE_S, * PKSPROPERTY_TIMECODE_NODE_S; - - # define STATIC_KSEVENTSETID_EXTDEV_Command \ - 0x109c7988L, 0xb3cb, 0x11d2, 0xb4, 0x8e, 0x00, 0x60, 0x97, 0xb3, 0x39, 0x1b -DEFINE_GUIDSTRUCT("109c7988-b3cb-11d2-b48e-006097b3391b", KSEVENTSETID_EXTDEV_Command); - # define KSEVENTSETID_EXTDEV_Command DEFINE_GUIDNAMED(KSEVENTSETID_EXTDEV_Command) - -typedef enum -{ - KSEVENT_EXTDEV_COMMAND_NOTIFY_INTERIM_READY, - KSEVENT_EXTDEV_COMMAND_CONTROL_INTERIM_READY, - KSEVENT_EXTDEV_COMMAND_BUSRESET, - KSEVENT_EXTDEV_TIMECODE_UPDATE, - KSEVENT_EXTDEV_OPERATION_MODE_UPDATE, - KSEVENT_EXTDEV_TRANSPORT_STATE_UPDATE, - KSEVENT_EXTDEV_NOTIFY_REMOVAL, - KSEVENT_EXTDEV_NOTIFY_MEDIUM_CHANGE -}KSEVENT_DEVCMD; - # endif /* __EDevCtrl__ */ - - # define STATIC_PROPSETID_VIDCAP_CROSSBAR \ - 0x6a2e0640L, 0x28e4, 0x11d0, 0xa1, 0x8c, 0x00, 0xa0, 0xc9, 0x11, 0x89, 0x56 -DEFINE_GUIDSTRUCT("6a2e0640-28e4-11d0-a18c-00a0c9118956", PROPSETID_VIDCAP_CROSSBAR); - # define PROPSETID_VIDCAP_CROSSBAR DEFINE_GUIDNAMED(PROPSETID_VIDCAP_CROSSBAR) - -typedef enum -{ - KSPROPERTY_CROSSBAR_CAPS, - KSPROPERTY_CROSSBAR_PININFO, - KSPROPERTY_CROSSBAR_CAN_ROUTE, - KSPROPERTY_CROSSBAR_ROUTE -}KSPROPERTY_VIDCAP_CROSSBAR; - -typedef struct -{ - KSPROPERTY Property; - ULONG NumberOfInputs; - ULONG NumberOfOutputs; -}KSPROPERTY_CROSSBAR_CAPS_S, * PKSPROPERTY_CROSSBAR_CAPS_S; - -typedef struct -{ - KSPROPERTY Property; - KSPIN_DATAFLOW Direction; - ULONG Index; - ULONG PinType; - ULONG RelatedPinIndex; - KSPIN_MEDIUM Medium; -}KSPROPERTY_CROSSBAR_PININFO_S, * PKSPROPERTY_CROSSBAR_PININFO_S; - -typedef struct -{ - KSPROPERTY Property; - ULONG IndexInputPin; - ULONG IndexOutputPin; - ULONG CanRoute; -}KSPROPERTY_CROSSBAR_ROUTE_S, * PKSPROPERTY_CROSSBAR_ROUTE_S; - - # define STATIC_EVENTSETID_CROSSBAR \ - 0x6a2e0641L, 0x28e4, 0x11d0, 0xa1, 0x8c, 0x00, 0xa0, 0xc9, 0x11, 0x89, 0x56 -DEFINE_GUIDSTRUCT("6a2e0641-28e4-11d0-a18c-00a0c9118956", EVENTSETID_CROSSBAR); - # define EVENTSETID_CROSSBAR DEFINE_GUIDNAMED(EVENTSETID_CROSSBAR) - -typedef enum -{ - KSEVENT_CROSSBAR_CHANGED -}KSEVENT_CROSSBAR; - -typedef enum -{ - KS_PhysConn_Video_Tuner = 1, - KS_PhysConn_Video_Composite, - KS_PhysConn_Video_SVideo, - KS_PhysConn_Video_RGB, - KS_PhysConn_Video_YRYBY, - KS_PhysConn_Video_SerialDigital, - KS_PhysConn_Video_ParallelDigital, - KS_PhysConn_Video_SCSI, - KS_PhysConn_Video_AUX, - KS_PhysConn_Video_1394, - KS_PhysConn_Video_USB, - KS_PhysConn_Video_VideoDecoder, - KS_PhysConn_Video_VideoEncoder, - KS_PhysConn_Video_SCART, - KS_PhysConn_Audio_Tuner = 4096, - KS_PhysConn_Audio_Line, - KS_PhysConn_Audio_Mic, - KS_PhysConn_Audio_AESDigital, - KS_PhysConn_Audio_SPDIFDigital, - KS_PhysConn_Audio_SCSI, - KS_PhysConn_Audio_AUX, - KS_PhysConn_Audio_1394, - KS_PhysConn_Audio_USB, - KS_PhysConn_Audio_AudioDecoder -}KS_PhysicalConnectorType; - - # define STATIC_PROPSETID_VIDCAP_TVAUDIO \ - 0x6a2e0650L, 0x28e4, 0x11d0, 0xa1, 0x8c, 0x00, 0xa0, 0xc9, 0x11, 0x89, 0x56 -DEFINE_GUIDSTRUCT("6a2e0650-28e4-11d0-a18c-00a0c9118956", PROPSETID_VIDCAP_TVAUDIO); - # define PROPSETID_VIDCAP_TVAUDIO DEFINE_GUIDNAMED(PROPSETID_VIDCAP_TVAUDIO) - -typedef enum -{ - KSPROPERTY_TVAUDIO_CAPS, - KSPROPERTY_TVAUDIO_MODE, - KSPROPERTY_TVAUDIO_CURRENTLY_AVAILABLE_MODES -}KSPROPERTY_VIDCAP_TVAUDIO; - - # define KS_TVAUDIO_MODE_MONO 0x0001 - # define KS_TVAUDIO_MODE_STEREO 0x0002 - # define KS_TVAUDIO_MODE_LANG_A 0x0010 - # define KS_TVAUDIO_MODE_LANG_B 0x0020 - # define KS_TVAUDIO_MODE_LANG_C 0x0040 - -typedef struct -{ - KSPROPERTY Property; - ULONG Capabilities; - KSPIN_MEDIUM InputMedium; - KSPIN_MEDIUM OutputMedium; -}KSPROPERTY_TVAUDIO_CAPS_S, * PKSPROPERTY_TVAUDIO_CAPS_S; - -typedef struct -{ - KSPROPERTY Property; - ULONG Mode; -}KSPROPERTY_TVAUDIO_S, * PKSPROPERTY_TVAUDIO_S; - - # define STATIC_KSEVENTSETID_VIDCAP_TVAUDIO \ - 0x6a2e0651L, 0x28e4, 0x11d0, 0xa1, 0x8c, 0x00, 0xa0, 0xc9, 0x11, 0x89, 0x56 -DEFINE_GUIDSTRUCT("6a2e0651-28e4-11d0-a18c-00a0c9118956", KSEVENTSETID_VIDCAP_TVAUDIO); - # define KSEVENTSETID_VIDCAP_TVAUDIO DEFINE_GUIDNAMED(KSEVENTSETID_VIDCAP_TVAUDIO) - -typedef enum -{ - KSEVENT_TVAUDIO_CHANGED -}KSEVENT_TVAUDIO; - - # define STATIC_PROPSETID_VIDCAP_VIDEOCOMPRESSION \ - 0xC6E13343L, 0x30AC, 0x11d0, 0xA1, 0x8C, 0x00, 0xA0, 0xC9, 0x11, 0x89, 0x56 -DEFINE_GUIDSTRUCT("C6E13343-30AC-11d0-A18C-00A0C9118956", PROPSETID_VIDCAP_VIDEOCOMPRESSION); - # define PROPSETID_VIDCAP_VIDEOCOMPRESSION DEFINE_GUIDNAMED(PROPSETID_VIDCAP_VIDEOCOMPRESSION) - -typedef enum -{ - KSPROPERTY_VIDEOCOMPRESSION_GETINFO, - KSPROPERTY_VIDEOCOMPRESSION_KEYFRAME_RATE, - KSPROPERTY_VIDEOCOMPRESSION_PFRAMES_PER_KEYFRAME, - KSPROPERTY_VIDEOCOMPRESSION_QUALITY, - KSPROPERTY_VIDEOCOMPRESSION_OVERRIDE_KEYFRAME, - KSPROPERTY_VIDEOCOMPRESSION_OVERRIDE_FRAME_SIZE, - KSPROPERTY_VIDEOCOMPRESSION_WINDOWSIZE -}KSPROPERTY_VIDCAP_VIDEOCOMPRESSION; - -typedef enum -{ - KS_CompressionCaps_CanQuality = 1, - KS_CompressionCaps_CanCrunch = 2, - KS_CompressionCaps_CanKeyFrame = 4, - KS_CompressionCaps_CanBFrame = 8, - KS_CompressionCaps_CanWindow = 0x10 -}KS_CompressionCaps; - -typedef enum -{ - KS_StreamingHint_FrameInterval = 0x0100, - KS_StreamingHint_KeyFrameRate = 0x0200, - KS_StreamingHint_PFrameRate = 0x0400, - KS_StreamingHint_CompQuality = 0x0800, - KS_StreamingHint_CompWindowSize = 0x1000 -}KS_VideoStreamingHints; - -typedef struct -{ - KSPROPERTY Property; - ULONG StreamIndex; - LONG DefaultKeyFrameRate; - LONG DefaultPFrameRate; - LONG DefaultQuality; - LONG NumberOfQualitySettings; - LONG Capabilities; -}KSPROPERTY_VIDEOCOMPRESSION_GETINFO_S, * PKSPROPERTY_VIDEOCOMPRESSION_GETINFO_S; - -typedef struct -{ - KSPROPERTY Property; - ULONG StreamIndex; - LONG Value; -}KSPROPERTY_VIDEOCOMPRESSION_S, * PKSPROPERTY_VIDEOCOMPRESSION_S; - -typedef struct -{ - KSPROPERTY Property; - ULONG StreamIndex; - LONG Value; - ULONG Flags; -}KSPROPERTY_VIDEOCOMPRESSION_S1, * PKSPROPERTY_VIDEOCOMPRESSION_S1; - - # define STATIC_KSDATAFORMAT_SUBTYPE_OVERLAY \ - 0xe436eb7fL, 0x524f, 0x11ce, 0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70 -DEFINE_GUIDSTRUCT("e436eb7f-524f-11ce-9f53-0020af0ba770", KSDATAFORMAT_SUBTYPE_OVERLAY); - # define KSDATAFORMAT_SUBTYPE_OVERLAY DEFINE_GUIDNAMED(KSDATAFORMAT_SUBTYPE_OVERLAY) - - # define STATIC_KSPROPSETID_OverlayUpdate \ - 0x490EA5CFL, 0x7681, 0x11D1, 0xA2, 0x1C, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96 -DEFINE_GUIDSTRUCT("490EA5CF-7681-11D1-A21C-00A0C9223196", KSPROPSETID_OverlayUpdate); - # define KSPROPSETID_OverlayUpdate DEFINE_GUIDNAMED(KSPROPSETID_OverlayUpdate) - -typedef enum -{ - KSPROPERTY_OVERLAYUPDATE_INTERESTS, - KSPROPERTY_OVERLAYUPDATE_CLIPLIST = 0x1, - KSPROPERTY_OVERLAYUPDATE_PALETTE = 0x2, - KSPROPERTY_OVERLAYUPDATE_COLORKEY = 0x4, - KSPROPERTY_OVERLAYUPDATE_VIDEOPOSITION = 0x8, - KSPROPERTY_OVERLAYUPDATE_DISPLAYCHANGE = 0x10, - KSPROPERTY_OVERLAYUPDATE_COLORREF = 0x10000000 -}KSPROPERTY_OVERLAYUPDATE; - -typedef struct -{ - ULONG PelsWidth; - ULONG PelsHeight; - ULONG BitsPerPel; - WCHAR DeviceID[1]; -}KSDISPLAYCHANGE, * PKSDISPLAYCHANGE; - - # define DEFINE_KSPROPERTY_ITEM_OVERLAYUPDATE_INTERESTS(Handler) \ - DEFINE_KSPROPERTY_ITEM( \ - KSPROPERTY_OVERLAYUPDATE_INTERESTS, \ - (Handler), \ - sizeof(KSPROPERTY), \ - sizeof(ULONG), \ - NULL, NULL, 0, NULL, NULL, 0) - - # define DEFINE_KSPROPERTY_ITEM_OVERLAYUPDATE_PALETTE(Handler) \ - DEFINE_KSPROPERTY_ITEM( \ - KSPROPERTY_OVERLAYUPDATE_PALETTE, \ - NULL, \ - sizeof(KSPROPERTY), \ - 0, \ - (Handler), \ - NULL, 0, NULL, NULL, 0) - - # define DEFINE_KSPROPERTY_ITEM_OVERLAYUPDATE_COLORKEY(Handler) \ - DEFINE_KSPROPERTY_ITEM( \ - KSPROPERTY_OVERLAYUPDATE_COLORKEY, \ - NULL, \ - sizeof(KSPROPERTY), \ - sizeof(COLORKEY), \ - (Handler), \ - NULL, 0, NULL, NULL, 0) - - # define DEFINE_KSPROPERTY_ITEM_OVERLAYUPDATE_CLIPLIST(Handler) \ - DEFINE_KSPROPERTY_ITEM( \ - KSPROPERTY_OVERLAYUPDATE_CLIPLIST, \ - NULL, \ - sizeof(KSPROPERTY), \ - 2 * sizeof(RECT) + sizeof(RGNDATAHEADER), \ - (Handler), \ - NULL, 0, NULL, NULL, 0) - - # define DEFINE_KSPROPERTY_ITEM_OVERLAYUPDATE_VIDEOPOSITION(Handler) \ - DEFINE_KSPROPERTY_ITEM( \ - KSPROPERTY_OVERLAYUPDATE_VIDEOPOSITION, \ - NULL, \ - sizeof(KSPROPERTY), \ - 2 * sizeof(RECT), \ - (Handler), \ - NULL, 0, NULL, NULL, 0) - - # define DEFINE_KSPROPERTY_ITEM_OVERLAYUPDATE_DISPLAYCHANGE(Handler) \ - DEFINE_KSPROPERTY_ITEM( \ - KSPROPERTY_OVERLAYUPDATE_DISPLAYCHANGE, \ - NULL, \ - sizeof(KSPROPERTY), \ - sizeof(KSDISPLAYCHANGE), \ - (Handler), \ - NULL, 0, NULL, NULL, 0) - - # define DEFINE_KSPROPERTY_ITEM_OVERLAYUPDATE_COLORREF(Handler) \ - DEFINE_KSPROPERTY_ITEM( \ - KSPROPERTY_OVERLAYUPDATE_COLORREF, \ - (Handler), \ - sizeof(KSPROPERTY), \ - sizeof(COLORREF), \ - NULL, \ - NULL, 0, NULL, NULL, 0) - - # define STATIC_PROPSETID_VIDCAP_VIDEOCONTROL \ - 0x6a2e0670L, 0x28e4, 0x11d0, 0xa1, 0x8c, 0x00, 0xa0, 0xc9, 0x11, 0x89, 0x56 -DEFINE_GUIDSTRUCT("6a2e0670-28e4-11d0-a18c-00a0c9118956", PROPSETID_VIDCAP_VIDEOCONTROL); - # define PROPSETID_VIDCAP_VIDEOCONTROL DEFINE_GUIDNAMED(PROPSETID_VIDCAP_VIDEOCONTROL) - -typedef enum -{ - KSPROPERTY_VIDEOCONTROL_CAPS, - KSPROPERTY_VIDEOCONTROL_ACTUAL_FRAME_RATE, - KSPROPERTY_VIDEOCONTROL_FRAME_RATES, - KSPROPERTY_VIDEOCONTROL_MODE -}KSPROPERTY_VIDCAP_VIDEOCONTROL; - -typedef enum -{ - KS_VideoControlFlag_FlipHorizontal = 0x0001, - KS_VideoControlFlag_FlipVertical = 0x0002, - KS_Obsolete_VideoControlFlag_ExternalTriggerEnable = 0x0010, - KS_Obsolete_VideoControlFlag_Trigger = 0x0020, - KS_VideoControlFlag_ExternalTriggerEnable = 0x0004, - KS_VideoControlFlag_Trigger = 0x0008 -}KS_VideoControlFlags; - -typedef struct -{ - KSPROPERTY Property; - ULONG StreamIndex; - ULONG VideoControlCaps; -}KSPROPERTY_VIDEOCONTROL_CAPS_S, * PKSPROPERTY_VIDEOCONTROL_CAPS_S; - -typedef struct -{ - KSPROPERTY Property; - ULONG StreamIndex; - LONG Mode; -}KSPROPERTY_VIDEOCONTROL_MODE_S, * PKSPROPERTY_VIDEOCONTROL_MODE_S; - -typedef struct -{ - KSPROPERTY Property; - ULONG StreamIndex; - ULONG RangeIndex; - SIZE Dimensions; - LONGLONG CurrentActualFrameRate; - LONGLONG CurrentMaxAvailableFrameRate; -}KSPROPERTY_VIDEOCONTROL_ACTUAL_FRAME_RATE_S, * PKSPROPERTY_VIDEOCONTROL_ACTUAL_FRAME_RATE_S; - -typedef struct -{ - KSPROPERTY Property; - ULONG StreamIndex; - ULONG RangeIndex; - SIZE Dimensions; -}KSPROPERTY_VIDEOCONTROL_FRAME_RATES_S, * PKSPROPERTY_VIDEOCONTROL_FRAME_RATES_S; - - # define STATIC_PROPSETID_VIDCAP_DROPPEDFRAMES \ - 0xC6E13344L, 0x30AC, 0x11d0, 0xa1, 0x8c, 0x00, 0xa0, 0xc9, 0x11, 0x89, 0x56 -DEFINE_GUIDSTRUCT("C6E13344-30AC-11d0-A18C-00A0C9118956", PROPSETID_VIDCAP_DROPPEDFRAMES); - # define PROPSETID_VIDCAP_DROPPEDFRAMES DEFINE_GUIDNAMED(PROPSETID_VIDCAP_DROPPEDFRAMES) - -typedef enum -{ - KSPROPERTY_DROPPEDFRAMES_CURRENT -}KSPROPERTY_VIDCAP_DROPPEDFRAMES; - -typedef struct -{ - KSPROPERTY Property; - LONGLONG PictureNumber; - LONGLONG DropCount; - ULONG AverageFrameSize; -}KSPROPERTY_DROPPEDFRAMES_CURRENT_S, * PKSPROPERTY_DROPPEDFRAMES_CURRENT_S; - - # define STATIC_KSPROPSETID_VPConfig \ - 0xbc29a660L, 0x30e3, 0x11d0, 0x9e, 0x69, 0x00, 0xc0, 0x4f, 0xd7, 0xc1, 0x5b -DEFINE_GUIDSTRUCT("bc29a660-30e3-11d0-9e69-00c04fd7c15b", KSPROPSETID_VPConfig); - # define KSPROPSETID_VPConfig DEFINE_GUIDNAMED(KSPROPSETID_VPConfig) - - # define STATIC_KSPROPSETID_VPVBIConfig \ - 0xec529b00L, 0x1a1f, 0x11d1, 0xba, 0xd9, 0x0, 0x60, 0x97, 0x44, 0x11, 0x1a -DEFINE_GUIDSTRUCT("ec529b00-1a1f-11d1-bad9-00609744111a", KSPROPSETID_VPVBIConfig); - # define KSPROPSETID_VPVBIConfig DEFINE_GUIDNAMED(KSPROPSETID_VPVBIConfig) - -typedef enum -{ - KSPROPERTY_VPCONFIG_NUMCONNECTINFO, - KSPROPERTY_VPCONFIG_GETCONNECTINFO, - KSPROPERTY_VPCONFIG_SETCONNECTINFO, - KSPROPERTY_VPCONFIG_VPDATAINFO, - KSPROPERTY_VPCONFIG_MAXPIXELRATE, - KSPROPERTY_VPCONFIG_INFORMVPINPUT, - KSPROPERTY_VPCONFIG_NUMVIDEOFORMAT, - KSPROPERTY_VPCONFIG_GETVIDEOFORMAT, - KSPROPERTY_VPCONFIG_SETVIDEOFORMAT, - KSPROPERTY_VPCONFIG_INVERTPOLARITY, - KSPROPERTY_VPCONFIG_DECIMATIONCAPABILITY, - KSPROPERTY_VPCONFIG_SCALEFACTOR, - KSPROPERTY_VPCONFIG_DDRAWHANDLE, - KSPROPERTY_VPCONFIG_VIDEOPORTID, - KSPROPERTY_VPCONFIG_DDRAWSURFACEHANDLE, - KSPROPERTY_VPCONFIG_SURFACEPARAMS -}KSPROPERTY_VPCONFIG; - - # define STATIC_CLSID_KsIBasicAudioInterfaceHandler \ - 0xb9f8ac3e, 0x0f71, 0x11d2, 0xb7, 0x2c, 0x00, 0xc0, 0x4f, 0xb6, 0xbd, 0x3d -DEFINE_GUIDSTRUCT("b9f8ac3e-0f71-11d2-b72c-00c04fb6bd3d", CLSID_KsIBasicAudioInterfaceHandler); - # define CLSID_KsIBasicAudioInterfaceHandler DEFINE_GUIDNAMED(CLSID_KsIBasicAudioInterfaceHandler) - - # ifdef __IVPType__ -typedef struct -{ - AMVPSIZE Size; - DWORD MaxPixelsPerSecond; - DWORD Reserved; -}KSVPMAXPIXELRATE, * PKSVPMAXPIXELRATE; - -typedef struct -{ - KSPROPERTY Property; - AMVPSIZE Size; -}KSVPSIZE_PROP, * PKSVPSIZE_PROP; - -typedef struct -{ - DWORD dwPitch; - DWORD dwXOrigin; - DWORD dwYOrigin; -}KSVPSURFACEPARAMS, * PKSVPSURFACEPARAMS; - # else /* __IVPType__ */ - - # ifndef __DDRAW_INCLUDED__ - # define DDPF_FOURCC 0x00000004l - -typedef struct _DDPIXELFORMAT -{ - DWORD dwSize; - DWORD dwFlags; - DWORD dwFourCC; - __MINGW_EXTENSION union - { - DWORD dwRGBBitCount; - DWORD dwYUVBitCount; - DWORD dwZBufferBitDepth; - DWORD dwAlphaBitDepth; - }; - __MINGW_EXTENSION union - { - DWORD dwRBitMask; - DWORD dwYBitMask; - }; - __MINGW_EXTENSION union - { - DWORD dwGBitMask; - DWORD dwUBitMask; - }; - __MINGW_EXTENSION union - { - DWORD dwBBitMask; - DWORD dwVBitMask; - }; - __MINGW_EXTENSION union - { - DWORD dwRGBAlphaBitMask; - DWORD dwYUVAlphaBitMask; - DWORD dwRGBZBitMask; - DWORD dwYUVZBitMask; - }; -}DDPIXELFORMAT, * LPDDPIXELFORMAT; - # endif /* __DDRAW_INCLUDED__ */ - - # ifndef __DVP_INCLUDED__ -typedef struct _DDVIDEOPORTCONNECT -{ - DWORD dwSize; - DWORD dwPortWidth; - GUID guidTypeID; - DWORD dwFlags; - ULONG_PTR dwReserved1; -}DDVIDEOPORTCONNECT, * LPDDVIDEOPORTCONNECT; - - # define DDVPTYPE_E_HREFH_VREFH \ - 0x54F39980L, 0xDA60, 0x11CF, 0x9B, 0x06, 0x00, 0xA0, 0xC9, 0x03, 0xA3, 0xB8 - - # define DDVPTYPE_E_HREFL_VREFL \ - 0xE09C77E0L, 0xDA60, 0x11CF, 0x9B, 0x06, 0x00, 0xA0, 0xC9, 0x03, 0xA3, 0xB8 - # endif /* __DVP_INCLUDED__ */ - -typedef enum -{ - KS_PixAspectRatio_NTSC4x3, - KS_PixAspectRatio_NTSC16x9, - KS_PixAspectRatio_PAL4x3, - KS_PixAspectRatio_PAL16x9 -}KS_AMPixAspectRatio; - -typedef enum -{ - KS_AMVP_DO_NOT_CARE, - KS_AMVP_BEST_BANDWIDTH, - KS_AMVP_INPUT_SAME_AS_OUTPUT -}KS_AMVP_SELECTFORMATBY; - -typedef enum -{ - KS_AMVP_MODE_WEAVE, - KS_AMVP_MODE_BOBINTERLEAVED, - KS_AMVP_MODE_BOBNONINTERLEAVED, - KS_AMVP_MODE_SKIPEVEN, - KS_AMVP_MODE_SKIPODD -}KS_AMVP_MODE; - -typedef struct tagKS_AMVPDIMINFO -{ - DWORD dwFieldWidth; - DWORD dwFieldHeight; - DWORD dwVBIWidth; - DWORD dwVBIHeight; - RECT rcValidRegion; -}KS_AMVPDIMINFO, * PKS_AMVPDIMINFO; - -typedef struct tagKS_AMVPDATAINFO -{ - DWORD dwSize; - DWORD dwMicrosecondsPerField; - KS_AMVPDIMINFO amvpDimInfo; - DWORD dwPictAspectRatioX; - DWORD dwPictAspectRatioY; - WINBOOL bEnableDoubleClock; - WINBOOL bEnableVACT; - WINBOOL bDataIsInterlaced; - LONG lHalfLinesOdd; - WINBOOL bFieldPolarityInverted; - DWORD dwNumLinesInVREF; - LONG lHalfLinesEven; - DWORD dwReserved1; -}KS_AMVPDATAINFO, * PKS_AMVPDATAINFO; - -typedef struct tagKS_AMVPSIZE -{ - DWORD dwWidth; - DWORD dwHeight; -}KS_AMVPSIZE, * PKS_AMVPSIZE; - -typedef struct -{ - KS_AMVPSIZE Size; - DWORD MaxPixelsPerSecond; - DWORD Reserved; -}KSVPMAXPIXELRATE, * PKSVPMAXPIXELRATE; - -typedef struct -{ - KSPROPERTY Property; - KS_AMVPSIZE Size; -}KSVPSIZE_PROP, * PKSVPSIZE_PROP; - -typedef struct -{ - DWORD dwPitch; - DWORD dwXOrigin; - DWORD dwYOrigin; -}KSVPSURFACEPARAMS, * PKSVPSURFACEPARAMS; - # endif /* __IVPType__ */ - - # define STATIC_KSEVENTSETID_VPNotify \ - 0x20c5598eL, 0xd3c8, 0x11d0, 0x8d, 0xfc, 0x00, 0xc0, 0x4f, 0xd7, 0xc0, 0x8b -DEFINE_GUIDSTRUCT("20c5598e-d3c8-11d0-8dfc-00c04fd7c08b", KSEVENTSETID_VPNotify); - # define KSEVENTSETID_VPNotify DEFINE_GUIDNAMED(KSEVENTSETID_VPNotify) - -typedef enum -{ - KSEVENT_VPNOTIFY_FORMATCHANGE -}KSEVENT_VPNOTIFY; - - # define STATIC_KSEVENTSETID_VIDCAPTOSTI \ - 0xdb47de20, 0xf628, 0x11d1, 0xba, 0x41, 0x0, 0xa0, 0xc9, 0xd, 0x2b, 0x5 -DEFINE_GUIDSTRUCT("DB47DE20-F628-11d1-BA41-00A0C90D2B05", KSEVENTSETID_VIDCAPTOSTI); - # define KSEVENTSETID_VIDCAPNotify DEFINE_GUIDNAMED(KSEVENTSETID_VIDCAPTOSTI) - -typedef enum -{ - KSEVENT_VIDCAPTOSTI_EXT_TRIGGER, - KSEVENT_VIDCAP_AUTO_UPDATE, - KSEVENT_VIDCAP_SEARCH -}KSEVENT_VIDCAPTOSTI; - -typedef enum -{ - KSPROPERTY_EXTENSION_UNIT_INFO, - KSPROPERTY_EXTENSION_UNIT_CONTROL, - KSPROPERTY_EXTENSION_UNIT_PASS_THROUGH = 0xffff -}KSPROPERTY_EXTENSION_UNIT, * PKSPROPERTY_EXTENSION_UNIT; - - # define STATIC_KSEVENTSETID_VPVBINotify \ - 0xec529b01L, 0x1a1f, 0x11d1, 0xba, 0xd9, 0x0, 0x60, 0x97, 0x44, 0x11, 0x1a -DEFINE_GUIDSTRUCT("ec529b01-1a1f-11d1-bad9-00609744111a", KSEVENTSETID_VPVBINotify); - # define KSEVENTSETID_VPVBINotify DEFINE_GUIDNAMED(KSEVENTSETID_VPVBINotify) - -typedef enum -{ - KSEVENT_VPVBINOTIFY_FORMATCHANGE -}KSEVENT_VPVBINOTIFY; - - # define STATIC_KSDATAFORMAT_TYPE_AUXLine21Data \ - 0x670aea80L, 0x3a82, 0x11d0, 0xb7, 0x9b, 0x00, 0xaa, 0x00, 0x37, 0x67, 0xa7 -DEFINE_GUIDSTRUCT("670aea80-3a82-11d0-b79b-00aa003767a7", KSDATAFORMAT_TYPE_AUXLine21Data); - # define KSDATAFORMAT_TYPE_AUXLine21Data DEFINE_GUIDNAMED(KSDATAFORMAT_TYPE_AUXLine21Data) - - # define STATIC_KSDATAFORMAT_SUBTYPE_Line21_BytePair \ - 0x6e8d4a22L, 0x310c, 0x11d0, 0xb7, 0x9a, 0x00, 0xaa, 0x00, 0x37, 0x67, 0xa7 -DEFINE_GUIDSTRUCT("6e8d4a22-310c-11d0-b79a-00aa003767a7", KSDATAFORMAT_SUBTYPE_Line21_BytePair); - # define KSDATAFORMAT_SUBTYPE_Line21_BytePair DEFINE_GUIDNAMED(KSDATAFORMAT_SUBTYPE_Line21_BytePair) - - # define STATIC_KSDATAFORMAT_SUBTYPE_Line21_GOPPacket \ - 0x6e8d4a23L, 0x310c, 0x11d0, 0xb7, 0x9a, 0x00, 0xaa, 0x00, 0x37, 0x67, 0xa7 -DEFINE_GUIDSTRUCT("6e8d4a23-310c-11d0-b79a-00aa003767a7", KSDATAFORMAT_SUBTYPE_Line21_GOPPacket); - # define KSDATAFORMAT_SUBTYPE_Line21_GOPPacket DEFINE_GUIDNAMED(KSDATAFORMAT_SUBTYPE_Line21_GOPPacket) - -typedef struct _KSGOP_USERDATA -{ - ULONG sc; - ULONG reserved1; - BYTE cFields; - CHAR l21Data[3]; -}KSGOP_USERDATA, * PKSGOP_USERDATA; - - # define STATIC_KSDATAFORMAT_TYPE_DVD_ENCRYPTED_PACK \ - 0xed0b916a, 0x044d, 0x11d1, 0xaa, 0x78, 0x00, 0xc0, 0x4f, 0xc3, 0x1d, 0x60 -DEFINE_GUIDSTRUCT("ed0b916a-044d-11d1-aa78-00c04fc31d60", KSDATAFORMAT_TYPE_DVD_ENCRYPTED_PACK); - # define KSDATAFORMAT_TYPE_DVD_ENCRYPTED_PACK DEFINE_GUIDNAMED(KSDATAFORMAT_TYPE_DVD_ENCRYPTED_PACK) - - # define KS_AM_UseNewCSSKey 0x1 - - # define STATIC_KSPROPSETID_TSRateChange \ - 0xa503c5c0, 0x1d1d, 0x11d1, 0xad, 0x80, 0x44, 0x45, 0x53, 0x54, 0x0, 0x0 -DEFINE_GUIDSTRUCT("A503C5C0-1D1D-11D1-AD80-444553540000", KSPROPSETID_TSRateChange); - # define KSPROPSETID_TSRateChange DEFINE_GUIDNAMED(KSPROPSETID_TSRateChange) - -typedef enum -{ - KS_AM_RATE_SimpleRateChange = 1, - KS_AM_RATE_ExactRateChange = 2, - KS_AM_RATE_MaxFullDataRate = 3, - KS_AM_RATE_Step = 4 -}KS_AM_PROPERTY_TS_RATE_CHANGE; - -typedef struct -{ - REFERENCE_TIME StartTime; - LONG Rate; -}KS_AM_SimpleRateChange, * PKS_AM_SimpleRateChange; - -typedef struct -{ - REFERENCE_TIME OutputZeroTime; - LONG Rate; -}KS_AM_ExactRateChange, * PKS_AM_ExactRateChange; - -typedef LONG KS_AM_MaxFullDataRate; -typedef DWORD KS_AM_Step; - - # define STATIC_KSCATEGORY_ENCODER \ - 0x19689bf6, 0xc384, 0x48fd, 0xad, 0x51, 0x90, 0xe5, 0x8c, 0x79, 0xf7, 0xb -DEFINE_GUIDSTRUCT("19689BF6-C384-48fd-AD51-90E58C79F70B", KSCATEGORY_ENCODER); - # define KSCATEGORY_ENCODER DEFINE_GUIDNAMED(KSCATEGORY_ENCODER) - - # define STATIC_KSCATEGORY_MULTIPLEXER \ - 0x7a5de1d3, 0x1a1, 0x452c, 0xb4, 0x81, 0x4f, 0xa2, 0xb9, 0x62, 0x71, 0xe8 -DEFINE_GUIDSTRUCT("7A5DE1D3-01A1-452c-B481-4FA2B96271E8", KSCATEGORY_MULTIPLEXER); - # define KSCATEGORY_MULTIPLEXER DEFINE_GUIDNAMED(KSCATEGORY_MULTIPLEXER) - - # ifndef __ENCODER_API_GUIDS__ - # define __ENCODER_API_GUIDS__ - - # define STATIC_ENCAPIPARAM_BITRATE \ - 0x49cc4c43, 0xca83, 0x4ad4, 0xa9, 0xaf, 0xf3, 0x69, 0x6a, 0xf6, 0x66, 0xdf -DEFINE_GUIDSTRUCT("49CC4C43-CA83-4ad4-A9AF-F3696AF666DF", ENCAPIPARAM_BITRATE); - # define ENCAPIPARAM_BITRATE DEFINE_GUIDNAMED(ENCAPIPARAM_BITRATE) - - # define STATIC_ENCAPIPARAM_PEAK_BITRATE \ - 0x703f16a9, 0x3d48, 0x44a1, 0xb0, 0x77, 0x1, 0x8d, 0xff, 0x91, 0x5d, 0x19 -DEFINE_GUIDSTRUCT("703F16A9-3D48-44a1-B077-018DFF915D19", ENCAPIPARAM_PEAK_BITRATE); - # define ENCAPIPARAM_PEAK_BITRATE DEFINE_GUIDNAMED(ENCAPIPARAM_PEAK_BITRATE) - - # define STATIC_ENCAPIPARAM_BITRATE_MODE \ - 0xee5fb25c, 0xc713, 0x40d1, 0x9d, 0x58, 0xc0, 0xd7, 0x24, 0x1e, 0x25, 0xf -DEFINE_GUIDSTRUCT("EE5FB25C-C713-40d1-9D58-C0D7241E250F", ENCAPIPARAM_BITRATE_MODE); - # define ENCAPIPARAM_BITRATE_MODE DEFINE_GUIDNAMED(ENCAPIPARAM_BITRATE_MODE) - - # define STATIC_CODECAPI_CHANGELISTS \ - 0x62b12acf, 0xf6b0, 0x47d9, 0x94, 0x56, 0x96, 0xf2, 0x2c, 0x4e, 0x0b, 0x9d -DEFINE_GUIDSTRUCT("62B12ACF-F6B0-47D9-9456-96F22C4E0B9D", CODECAPI_CHANGELISTS); - # define CODECAPI_CHANGELISTS DEFINE_GUIDNAMED(CODECAPI_CHANGELISTS) - - # define STATIC_CODECAPI_VIDEO_ENCODER \ - 0x7112e8e1, 0x3d03, 0x47ef, 0x8e, 0x60, 0x03, 0xf1, 0xcf, 0x53, 0x73, 0x01 -DEFINE_GUIDSTRUCT("7112E8E1-3D03-47EF-8E60-03F1CF537301", CODECAPI_VIDEO_ENCODER); - # define CODECAPI_VIDEO_ENCODER DEFINE_GUIDNAMED(CODECAPI_VIDEO_ENCODER) - - # define STATIC_CODECAPI_AUDIO_ENCODER \ - 0xb9d19a3e, 0xf897, 0x429c, 0xbc, 0x46, 0x81, 0x38, 0xb7, 0x27, 0x2b, 0x2d -DEFINE_GUIDSTRUCT("B9D19A3E-F897-429C-BC46-8138B7272B2D", CODECAPI_AUDIO_ENCODER); - # define CODECAPI_AUDIO_ENCODER DEFINE_GUIDNAMED(CODECAPI_AUDIO_ENCODER) - - # define STATIC_CODECAPI_SETALLDEFAULTS \ - 0x6c5e6a7c, 0xacf8, 0x4f55, 0xa9, 0x99, 0x1a, 0x62, 0x81, 0x09, 0x05, 0x1b -DEFINE_GUIDSTRUCT("6C5E6A7C-ACF8-4F55-A999-1A628109051B", CODECAPI_SETALLDEFAULTS); - # define CODECAPI_SETALLDEFAULTS DEFINE_GUIDNAMED(CODECAPI_SETALLDEFAULTS) - - # define STATIC_CODECAPI_ALLSETTINGS \ - 0x6a577e92, 0x83e1, 0x4113, 0xad, 0xc2, 0x4f, 0xce, 0xc3, 0x2f, 0x83, 0xa1 -DEFINE_GUIDSTRUCT("6A577E92-83E1-4113-ADC2-4FCEC32F83A1", CODECAPI_ALLSETTINGS); - # define CODECAPI_ALLSETTINGS DEFINE_GUIDNAMED(CODECAPI_ALLSETTINGS) - - # define STATIC_CODECAPI_SUPPORTSEVENTS \ - 0x0581af97, 0x7693, 0x4dbd, 0x9d, 0xca, 0x3f, 0x9e, 0xbd, 0x65, 0x85, 0xa1 -DEFINE_GUIDSTRUCT("0581AF97-7693-4DBD-9DCA-3F9EBD6585A1", CODECAPI_SUPPORTSEVENTS); - # define CODECAPI_SUPPORTSEVENTS DEFINE_GUIDNAMED(CODECAPI_SUPPORTSEVENTS) - - # define STATIC_CODECAPI_CURRENTCHANGELIST \ - 0x1cb14e83, 0x7d72, 0x4657, 0x83, 0xfd, 0x47, 0xa2, 0xc5, 0xb9, 0xd1, 0x3d -DEFINE_GUIDSTRUCT("1CB14E83-7D72-4657-83FD-47A2C5B9D13D", CODECAPI_CURRENTCHANGELIST); - # define CODECAPI_CURRENTCHANGELIST DEFINE_GUIDNAMED(CODECAPI_CURRENTCHANGELIST) - # endif /* __ENCODER_API_GUIDS__ */ - - # ifndef __ENCODER_API_DEFINES__ - # define __ENCODER_API_DEFINES__ -typedef enum -{ - ConstantBitRate = 0, - VariableBitRateAverage, - VariableBitRatePeak -}VIDEOENCODER_BITRATE_MODE; - # endif /* __ENCODER_API_DEFINES__ */ - - # define STATIC_KSPROPSETID_Jack \ - 0x4509f757, 0x2d46, 0x4637, 0x8e, 0x62, 0xce, 0x7d, 0xb9, 0x44, 0xf5, 0x7b -DEFINE_GUIDSTRUCT("4509F757-2D46-4637-8E62-CE7DB944F57B", KSPROPSETID_Jack); - # define KSPROPSETID_Jack DEFINE_GUIDNAMED(KSPROPSETID_Jack) - -typedef enum -{ - KSPROPERTY_JACK_DESCRIPTION = 1, - KSPROPERTY_JACK_DESCRIPTION2, - KSPROPERTY_JACK_SINK_INFO -}KSPROPERTY_JACK; - -typedef enum -{ - eConnTypeUnknown, - eConnType3Point5mm, - eConnTypeQuarter, - eConnTypeAtapiInternal, - eConnTypeRCA, - eConnTypeOptical, - eConnTypeOtherDigital, - eConnTypeOtherAnalog, - eConnTypeMultichannelAnalogDIN, - eConnTypeXlrProfessional, - eConnTypeRJ11Modem, - eConnTypeCombination -}EPcxConnectionType; - -typedef enum -{ - eGeoLocRear = 0x1, - eGeoLocFront, - eGeoLocLeft, - eGeoLocRight, - eGeoLocTop, - eGeoLocBottom, - eGeoLocRearPanel, - eGeoLocRiser, - eGeoLocInsideMobileLid, - eGeoLocDrivebay, - eGeoLocHDMI, - eGeoLocOutsideMobileLid, - eGeoLocATAPI, - eGeoLocReserved5, - eGeoLocReserved6, - EPcxGeoLocation_enum_count -}EPcxGeoLocation; - -typedef enum -{ - eGenLocPrimaryBox = 0, - eGenLocInternal, - eGenLocSeparate, - eGenLocOther, - EPcxGenLocation_enum_count -}EPcxGenLocation; - -typedef enum -{ - ePortConnJack = 0, - ePortConnIntegratedDevice, - ePortConnBothIntegratedAndJack, - ePortConnUnknown -}EPxcPortConnection; - -typedef struct -{ - DWORD ChannelMapping; - COLORREF Color; - EPcxConnectionType ConnectionType; - EPcxGeoLocation GeoLocation; - EPcxGenLocation GenLocation; - EPxcPortConnection PortConnection; - BOOL IsConnected; -}KSJACK_DESCRIPTION, * PKSJACK_DESCRIPTION; - -typedef enum -{ - KSJACK_SINK_CONNECTIONTYPE_HDMI = 0, - KSJACK_SINK_CONNECTIONTYPE_DISPLAYPORT, -}KSJACK_SINK_CONNECTIONTYPE; - - # define MAX_SINK_DESCRIPTION_NAME_LENGTH 32 -typedef struct _tagKSJACK_SINK_INFORMATION -{ - KSJACK_SINK_CONNECTIONTYPE ConnType; - WORD ManufacturerId; - WORD ProductId; - WORD AudioLatency; - BOOL HDCPCapable; - BOOL AICapable; - UCHAR SinkDescriptionLength; - WCHAR SinkDescription[MAX_SINK_DESCRIPTION_NAME_LENGTH]; - LUID PortId; -}KSJACK_SINK_INFORMATION, * PKSJACK_SINK_INFORMATION; - - # define JACKDESC2_PRESENCE_DETECT_CAPABILITY 0x00000001 - # define JACKDESC2_DYNAMIC_FORMAT_CHANGE_CAPABILITY 0x00000002 - -typedef struct _tagKSJACK_DESCRIPTION2 -{ - DWORD DeviceStateInfo; - DWORD JackCapabilities; -}KSJACK_DESCRIPTION2, * PKSJACK_DESCRIPTION2; - -#endif /* _KSMEDIA_ */ - From 745fbe3fa6aa313b4e9d40cce465e57d07111afc Mon Sep 17 00:00:00 2001 From: Gary Scavone Date: Sun, 30 Mar 2014 13:04:40 -0400 Subject: [PATCH 04/45] Removed another reference to kernel streaming support in readme. --- readme | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme b/readme index 4d56ed58..545ffc61 100644 --- a/readme +++ b/readme @@ -13,7 +13,7 @@ If you checked out the code from git, please run "autoconf" before "./configure" OVERVIEW: -RtMidi is a set of C++ classes (RtMidiIn, RtMidiOut, and API specific classes) that provide a common API (Application Programming Interface) for realtime MIDI input/output across Linux (ALSA, JACK), Macintosh OS X (CoreMidi, JACK), and Windows (Multimedia Library, Kernel Streming) operating systems. RtMidi significantly simplifies the process of interacting with computer MIDI hardware and software. It was designed with the following goals: +RtMidi is a set of C++ classes (RtMidiIn, RtMidiOut, and API specific classes) that provide a common API (Application Programming Interface) for realtime MIDI input/output across Linux (ALSA, JACK), Macintosh OS X (CoreMIDI, JACK), and Windows (Multimedia Library) operating systems. RtMidi significantly simplifies the process of interacting with computer MIDI hardware and software. It was designed with the following goals: - object oriented C++ design - simple, common API across all supported platforms From 774c66488cf9e2a1de119feb72529a0b144f4d08 Mon Sep 17 00:00:00 2001 From: Gary Scavone Date: Sun, 30 Mar 2014 13:09:19 -0400 Subject: [PATCH 05/45] Removed reference to WINKS in midiprobe.cpp --- tests/midiprobe.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/midiprobe.cpp b/tests/midiprobe.cpp index 6576e152..d9611edd 100644 --- a/tests/midiprobe.cpp +++ b/tests/midiprobe.cpp @@ -15,7 +15,6 @@ int main() std::map apiMap; apiMap[RtMidi::MACOSX_CORE] = "OS-X CoreMidi"; apiMap[RtMidi::WINDOWS_MM] = "Windows MultiMedia"; - apiMap[RtMidi::WINDOWS_KS] = "Windows Kernel Straming"; apiMap[RtMidi::UNIX_JACK] = "Jack Client"; apiMap[RtMidi::LINUX_ALSA] = "Linux ALSA"; apiMap[RtMidi::RTMIDI_DUMMY] = "RtMidi Dummy"; From 7a3f04cd2c6461a9efc25dc064201806679d31a2 Mon Sep 17 00:00:00 2001 From: Gary Scavone Date: Mon, 31 Mar 2014 11:05:38 -0400 Subject: [PATCH 06/45] Corrected documentation regarding API default order in RtMidi.h --- RtMidi.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/RtMidi.h b/RtMidi.h index 61418350..9a878884 100644 --- a/RtMidi.h +++ b/RtMidi.h @@ -219,8 +219,8 @@ class RtMidiIn : public RtMidi incoming messages will be ignored. If no API argument is specified and multiple API support has been - compiled, the default order of use is JACK, ALSA (Linux) and JACK, - CORE (OS-X). + compiled, the default order of use is ALSA, JACK (Linux) and CORE, + JACK (OS-X). \param api An optional API id can be specified. \param clientName An optional client name can be specified. This @@ -354,8 +354,8 @@ class RtMidiOut : public RtMidi An exception will be thrown if a MIDI system initialization error occurs. If no API argument is specified and multiple API support has been - compiled, the default order of use is JACK, ALSA (Linux) and JACK, - CORE (OS-X). + compiled, the default order of use is ALSA, JACK (Linux) and CORE, + JACK (OS-X). */ RtMidiOut( RtMidi::Api api=UNSPECIFIED, const std::string clientName = std::string( "RtMidi Output Client") ); From cab384786f2a0f567756f59b7e8b5e9f57093dff Mon Sep 17 00:00:00 2001 From: Tobias Schlemmer Date: Fri, 2 May 2014 21:34:53 +0200 Subject: [PATCH 07/45] Revert "Removed reference to WINKS in midiprobe.cpp" This reverts commit 774c66488cf9e2a1de119feb72529a0b144f4d08. --- tests/midiprobe.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/midiprobe.cpp b/tests/midiprobe.cpp index d9611edd..6576e152 100644 --- a/tests/midiprobe.cpp +++ b/tests/midiprobe.cpp @@ -15,6 +15,7 @@ int main() std::map apiMap; apiMap[RtMidi::MACOSX_CORE] = "OS-X CoreMidi"; apiMap[RtMidi::WINDOWS_MM] = "Windows MultiMedia"; + apiMap[RtMidi::WINDOWS_KS] = "Windows Kernel Straming"; apiMap[RtMidi::UNIX_JACK] = "Jack Client"; apiMap[RtMidi::LINUX_ALSA] = "Linux ALSA"; apiMap[RtMidi::RTMIDI_DUMMY] = "RtMidi Dummy"; From ac1829ec28a7c1f006fce878d193c004a5888ef9 Mon Sep 17 00:00:00 2001 From: Tobias Schlemmer Date: Fri, 2 May 2014 21:35:05 +0200 Subject: [PATCH 08/45] Revert "Removed another reference to kernel streaming support in readme." This reverts commit 745fbe3fa6aa313b4e9d40cce465e57d07111afc. --- readme | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme b/readme index 545ffc61..4d56ed58 100644 --- a/readme +++ b/readme @@ -13,7 +13,7 @@ If you checked out the code from git, please run "autoconf" before "./configure" OVERVIEW: -RtMidi is a set of C++ classes (RtMidiIn, RtMidiOut, and API specific classes) that provide a common API (Application Programming Interface) for realtime MIDI input/output across Linux (ALSA, JACK), Macintosh OS X (CoreMIDI, JACK), and Windows (Multimedia Library) operating systems. RtMidi significantly simplifies the process of interacting with computer MIDI hardware and software. It was designed with the following goals: +RtMidi is a set of C++ classes (RtMidiIn, RtMidiOut, and API specific classes) that provide a common API (Application Programming Interface) for realtime MIDI input/output across Linux (ALSA, JACK), Macintosh OS X (CoreMidi, JACK), and Windows (Multimedia Library, Kernel Streming) operating systems. RtMidi significantly simplifies the process of interacting with computer MIDI hardware and software. It was designed with the following goals: - object oriented C++ design - simple, common API across all supported platforms From 88d7dbd30611ff242043f57efe27f0ce3d736cb9 Mon Sep 17 00:00:00 2001 From: Tobias Schlemmer Date: Fri, 2 May 2014 21:35:14 +0200 Subject: [PATCH 09/45] Revert "Deleted include directory with kernel streaming files." This reverts commit 290db6cd3ead705fd117a72d589426d22ba23f8e. --- include/ks.h | 3577 +++++++++++++++++++++++++++++++++ include/ksmedia.h | 4824 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 8401 insertions(+) create mode 100644 include/ks.h create mode 100644 include/ksmedia.h diff --git a/include/ks.h b/include/ks.h new file mode 100644 index 00000000..1f8b8b45 --- /dev/null +++ b/include/ks.h @@ -0,0 +1,3577 @@ +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the w64 mingw-runtime package. + * No warranty is given. + */ +#ifndef _KS_ +#define _KS_ + +#include + +#if __GNUC__ >= 3 + # pragma GCC system_header +#endif + +#ifndef __MINGW_EXTENSION + # if defined(__GNUC__) || defined(__GNUG__) + # define __MINGW_EXTENSION __extension__ + # else + # define __MINGW_EXTENSION + # endif +#endif + +#ifdef __TCS__ + # define _KS_NO_ANONYMOUS_STRUCTURES_ 1 +#endif + +#ifdef _KS_NO_ANONYMOUS_STRUCTURES_ + # define _KS_ANON_STRUCT(X) struct X +#else + # define _KS_ANON_STRUCT(X) __MINGW_EXTENSION struct +#endif + +#ifndef _NTRTL_ + # ifndef DEFINE_GUIDEX + # define DEFINE_GUIDEX(name) EXTERN_C const GUID name + # endif + # ifndef STATICGUIDOF + # define STATICGUIDOF(guid) STATIC_ ## guid + # endif +#endif /* _NTRTL_ */ + +#ifndef SIZEOF_ARRAY + # define SIZEOF_ARRAY(ar) (sizeof(ar) / sizeof((ar)[0])) +#endif + +#define DEFINE_GUIDSTRUCT(g, n) DEFINE_GUIDEX(n) +#define DEFINE_GUIDNAMED(n) n + +#define STATIC_GUID_NULL \ + 0x00000000L, 0x0000, 0x0000, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } + +DEFINE_GUIDSTRUCT("00000000-0000-0000-0000-000000000000", GUID_NULL); +#define GUID_NULL DEFINE_GUIDNAMED(GUID_NULL) + +#define IOCTL_KS_PROPERTY CTL_CODE(FILE_DEVICE_KS, 0x000, METHOD_NEITHER, FILE_ANY_ACCESS) +#define IOCTL_KS_ENABLE_EVENT CTL_CODE(FILE_DEVICE_KS, 0x001, METHOD_NEITHER, FILE_ANY_ACCESS) +#define IOCTL_KS_DISABLE_EVENT CTL_CODE(FILE_DEVICE_KS, 0x002, METHOD_NEITHER, FILE_ANY_ACCESS) +#define IOCTL_KS_METHOD CTL_CODE(FILE_DEVICE_KS, 0x003, METHOD_NEITHER, FILE_ANY_ACCESS) +#define IOCTL_KS_WRITE_STREAM CTL_CODE(FILE_DEVICE_KS, 0x004, METHOD_NEITHER, FILE_WRITE_ACCESS) +#define IOCTL_KS_READ_STREAM CTL_CODE(FILE_DEVICE_KS, 0x005, METHOD_NEITHER, FILE_READ_ACCESS) +#define IOCTL_KS_RESET_STATE CTL_CODE(FILE_DEVICE_KS, 0x006, METHOD_NEITHER, FILE_ANY_ACCESS) + +typedef enum +{ + KSRESET_BEGIN, + KSRESET_END +}KSRESET; + +typedef enum +{ + KSSTATE_STOP, + KSSTATE_ACQUIRE, + KSSTATE_PAUSE, + KSSTATE_RUN +}KSSTATE, * PKSSTATE; + +#define KSPRIORITY_LOW 0x00000001 +#define KSPRIORITY_NORMAL 0x40000000 +#define KSPRIORITY_HIGH 0x80000000 +#define KSPRIORITY_EXCLUSIVE 0xFFFFFFFF + +typedef struct +{ + ULONG PriorityClass; + ULONG PrioritySubClass; +}KSPRIORITY, * PKSPRIORITY; + +typedef struct +{ + __MINGW_EXTENSION union + { + _KS_ANON_STRUCT(_IDENTIFIER) + { + GUID Set; + ULONG Id; + ULONG Flags; + }; + LONGLONG Alignment; + }; +}KSIDENTIFIER, * PKSIDENTIFIER; + +typedef KSIDENTIFIER KSPROPERTY, * PKSPROPERTY, KSMETHOD, * PKSMETHOD, KSEVENT, * PKSEVENT; + +#define KSMETHOD_TYPE_NONE 0x00000000 +#define KSMETHOD_TYPE_READ 0x00000001 +#define KSMETHOD_TYPE_WRITE 0x00000002 +#define KSMETHOD_TYPE_MODIFY 0x00000003 +#define KSMETHOD_TYPE_SOURCE 0x00000004 + +#define KSMETHOD_TYPE_SEND 0x00000001 +#define KSMETHOD_TYPE_SETSUPPORT 0x00000100 +#define KSMETHOD_TYPE_BASICSUPPORT 0x00000200 + +#define KSMETHOD_TYPE_TOPOLOGY 0x10000000 + +#define KSPROPERTY_TYPE_GET 0x00000001 +#define KSPROPERTY_TYPE_SET 0x00000002 +#define KSPROPERTY_TYPE_SETSUPPORT 0x00000100 +#define KSPROPERTY_TYPE_BASICSUPPORT 0x00000200 +#define KSPROPERTY_TYPE_RELATIONS 0x00000400 +#define KSPROPERTY_TYPE_SERIALIZESET 0x00000800 +#define KSPROPERTY_TYPE_UNSERIALIZESET 0x00001000 +#define KSPROPERTY_TYPE_SERIALIZERAW 0x00002000 +#define KSPROPERTY_TYPE_UNSERIALIZERAW 0x00004000 +#define KSPROPERTY_TYPE_SERIALIZESIZE 0x00008000 +#define KSPROPERTY_TYPE_DEFAULTVALUES 0x00010000 + +#define KSPROPERTY_TYPE_TOPOLOGY 0x10000000 + +typedef struct +{ + KSPROPERTY Property; + ULONG NodeId; + ULONG Reserved; +}KSP_NODE, * PKSP_NODE; + +typedef struct +{ + KSMETHOD Method; + ULONG NodeId; + ULONG Reserved; +}KSM_NODE, * PKSM_NODE; + +typedef struct +{ + KSEVENT Event; + ULONG NodeId; + ULONG Reserved; +}KSE_NODE, * PKSE_NODE; + +#define STATIC_KSPROPTYPESETID_General \ + 0x97E99BA0L, 0xBDEA, 0x11CF, 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00 +DEFINE_GUIDSTRUCT("97E99BA0-BDEA-11CF-A5D6-28DB04C10000", KSPROPTYPESETID_General); +#define KSPROPTYPESETID_General DEFINE_GUIDNAMED(KSPROPTYPESETID_General) + +typedef struct +{ + ULONG Size; + ULONG Count; +}KSMULTIPLE_ITEM, * PKSMULTIPLE_ITEM; + +typedef struct +{ + ULONG AccessFlags; + ULONG DescriptionSize; + KSIDENTIFIER PropTypeSet; + ULONG MembersListCount; + ULONG Reserved; +}KSPROPERTY_DESCRIPTION, * PKSPROPERTY_DESCRIPTION; + +#define KSPROPERTY_MEMBER_RANGES 0x00000001 +#define KSPROPERTY_MEMBER_STEPPEDRANGES 0x00000002 +#define KSPROPERTY_MEMBER_VALUES 0x00000003 + +#define KSPROPERTY_MEMBER_FLAG_DEFAULT 0x00000001 +#define KSPROPERTY_MEMBER_FLAG_BASICSUPPORT_MULTICHANNEL 0x00000002 +#define KSPROPERTY_MEMBER_FLAG_BASICSUPPORT_UNIFORM 0x00000004 + +typedef struct +{ + ULONG MembersFlags; + ULONG MembersSize; + ULONG MembersCount; + ULONG Flags; +}KSPROPERTY_MEMBERSHEADER, * PKSPROPERTY_MEMBERSHEADER; + +typedef union +{ + _KS_ANON_STRUCT(_SIGNED) + { + LONG SignedMinimum; + LONG SignedMaximum; + }; + _KS_ANON_STRUCT(_UNSIGNED) + { + ULONG UnsignedMinimum; + ULONG UnsignedMaximum; + }; +}KSPROPERTY_BOUNDS_LONG, * PKSPROPERTY_BOUNDS_LONG; + +typedef union +{ + _KS_ANON_STRUCT(_SIGNED64) + { + LONGLONG SignedMinimum; + LONGLONG SignedMaximum; + }; + _KS_ANON_STRUCT(_UNSIGNED64) + { + DWORDLONG UnsignedMinimum; + DWORDLONG UnsignedMaximum; + }; +}KSPROPERTY_BOUNDS_LONGLONG, * PKSPROPERTY_BOUNDS_LONGLONG; + +typedef struct +{ + ULONG SteppingDelta; + ULONG Reserved; + KSPROPERTY_BOUNDS_LONG Bounds; +}KSPROPERTY_STEPPING_LONG, * PKSPROPERTY_STEPPING_LONG; + +typedef struct +{ + DWORDLONG SteppingDelta; + KSPROPERTY_BOUNDS_LONGLONG Bounds; +}KSPROPERTY_STEPPING_LONGLONG, * PKSPROPERTY_STEPPING_LONGLONG; + +#if defined(_NTDDK_) +typedef struct _KSDEVICE_DESCRIPTOR KSDEVICE_DESCRIPTOR, * PKSDEVICE_DESCRIPTOR; +typedef struct _KSDEVICE_DISPATCH KSDEVICE_DISPATCH, * PKSDEVICE_DISPATCH; +typedef struct _KSDEVICE KSDEVICE, * PKSDEVICE; +typedef struct _KSFILTERFACTORY KSFILTERFACTORY, * PKSFILTERFACTORY; +typedef struct _KSFILTER_DESCRIPTOR KSFILTER_DESCRIPTOR, * PKSFILTER_DESCRIPTOR; +typedef struct _KSFILTER_DISPATCH KSFILTER_DISPATCH, * PKSFILTER_DISPATCH; +typedef struct _KSFILTER KSFILTER, * PKSFILTER; +typedef struct _KSPIN_DESCRIPTOR_EX KSPIN_DESCRIPTOR_EX, * PKSPIN_DESCRIPTOR_EX; +typedef struct _KSPIN_DISPATCH KSPIN_DISPATCH, * PKSPIN_DISPATCH; +typedef struct _KSCLOCK_DISPATCH KSCLOCK_DISPATCH, * PKSCLOCK_DISPATCH; +typedef struct _KSALLOCATOR_DISPATCH KSALLOCATOR_DISPATCH, * PKSALLOCATOR_DISPATCH; +typedef struct _KSPIN KSPIN, * PKSPIN; +typedef struct _KSNODE_DESCRIPTOR KSNODE_DESCRIPTOR, * PKSNODE_DESCRIPTOR; +typedef struct _KSSTREAM_POINTER_OFFSET KSSTREAM_POINTER_OFFSET, * PKSSTREAM_POINTER_OFFSET; +typedef struct _KSSTREAM_POINTER KSSTREAM_POINTER, * PKSSTREAM_POINTER; +typedef struct _KSMAPPING KSMAPPING, * PKSMAPPING; +typedef struct _KSPROCESSPIN KSPROCESSPIN, * PKSPROCESSPIN; +typedef struct _KSPROCESSPIN_INDEXENTRY KSPROCESSPIN_INDEXENTRY, * PKSPROCESSPIN_INDEXENTRY; +#endif /* _NTDDK_ */ + +typedef PVOID PKSWORKER; + +typedef struct +{ + ULONG NotificationType; + __MINGW_EXTENSION union + { + struct + { + HANDLE Event; + ULONG_PTR Reserved[2]; + }EventHandle; + struct + { + HANDLE Semaphore; + ULONG Reserved; + LONG Adjustment; + }SemaphoreHandle; +#if defined(_NTDDK_) + struct + { + PVOID Event; + KPRIORITY Increment; + ULONG_PTR Reserved; + }EventObject; + struct + { + PVOID Semaphore; + KPRIORITY Increment; + LONG Adjustment; + }SemaphoreObject; + struct + { + PKDPC Dpc; + ULONG ReferenceCount; + ULONG_PTR Reserved; + }Dpc; + struct + { + PWORK_QUEUE_ITEM WorkQueueItem; + WORK_QUEUE_TYPE WorkQueueType; + ULONG_PTR Reserved; + }WorkItem; + struct + { + PWORK_QUEUE_ITEM WorkQueueItem; + PKSWORKER KsWorkerObject; + ULONG_PTR Reserved; + }KsWorkItem; +#endif /* _NTDDK_ */ + struct + { + PVOID Unused; + LONG_PTR Alignment[2]; + }Alignment; + }; +}KSEVENTDATA, * PKSEVENTDATA; + +#define KSEVENTF_EVENT_HANDLE 0x00000001 +#define KSEVENTF_SEMAPHORE_HANDLE 0x00000002 +#if defined(_NTDDK_) + # define KSEVENTF_EVENT_OBJECT 0x00000004 + # define KSEVENTF_SEMAPHORE_OBJECT 0x00000008 + # define KSEVENTF_DPC 0x00000010 + # define KSEVENTF_WORKITEM 0x00000020 + # define KSEVENTF_KSWORKITEM 0x00000080 +#endif /* _NTDDK_ */ + +#define KSEVENT_TYPE_ENABLE 0x00000001 +#define KSEVENT_TYPE_ONESHOT 0x00000002 +#define KSEVENT_TYPE_ENABLEBUFFERED 0x00000004 +#define KSEVENT_TYPE_SETSUPPORT 0x00000100 +#define KSEVENT_TYPE_BASICSUPPORT 0x00000200 +#define KSEVENT_TYPE_QUERYBUFFER 0x00000400 + +#define KSEVENT_TYPE_TOPOLOGY 0x10000000 + +typedef struct +{ + KSEVENT Event; + PKSEVENTDATA EventData; + PVOID Reserved; +}KSQUERYBUFFER, * PKSQUERYBUFFER; + +typedef struct +{ + ULONG Size; + ULONG Flags; + __MINGW_EXTENSION union + { + HANDLE ObjectHandle; + PVOID ObjectPointer; + }; + PVOID Reserved; + KSEVENT Event; + KSEVENTDATA EventData; +}KSRELATIVEEVENT; + +#define KSRELATIVEEVENT_FLAG_HANDLE 0x00000001 +#define KSRELATIVEEVENT_FLAG_POINTER 0x00000002 + +typedef struct +{ + KSEVENTDATA EventData; + LONGLONG MarkTime; +}KSEVENT_TIME_MARK, * PKSEVENT_TIME_MARK; + +typedef struct +{ + KSEVENTDATA EventData; + LONGLONG TimeBase; + LONGLONG Interval; +}KSEVENT_TIME_INTERVAL, * PKSEVENT_TIME_INTERVAL; + +typedef struct +{ + LONGLONG TimeBase; + LONGLONG Interval; +}KSINTERVAL, * PKSINTERVAL; + +#define STATIC_KSPROPSETID_General \ + 0x1464EDA5L, 0x6A8F, 0x11D1, 0x9A, 0xA7, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96 +DEFINE_GUIDSTRUCT("1464EDA5-6A8F-11D1-9AA7-00A0C9223196", KSPROPSETID_General); +#define KSPROPSETID_General DEFINE_GUIDNAMED(KSPROPSETID_General) + +typedef enum +{ + KSPROPERTY_GENERAL_COMPONENTID +}KSPROPERTY_GENERAL; + +typedef struct +{ + GUID Manufacturer; + GUID Product; + GUID Component; + GUID Name; + ULONG Version; + ULONG Revision; +}KSCOMPONENTID, * PKSCOMPONENTID; + +#define DEFINE_KSPROPERTY_ITEM_GENERAL_COMPONENTID(Handler) \ + DEFINE_KSPROPERTY_ITEM( \ + KSPROPERTY_GENERAL_COMPONENTID, \ + (Handler), \ + sizeof(KSPROPERTY), \ + sizeof(KSCOMPONENTID), \ + NULL, NULL, 0, NULL, NULL, 0) + +#define STATIC_KSMETHODSETID_StreamIo \ + 0x65D003CAL, 0x1523, 0x11D2, 0xB2, 0x7A, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96 +DEFINE_GUIDSTRUCT("65D003CA-1523-11D2-B27A-00A0C9223196", KSMETHODSETID_StreamIo); +#define KSMETHODSETID_StreamIo DEFINE_GUIDNAMED(KSMETHODSETID_StreamIo) + +typedef enum +{ + KSMETHOD_STREAMIO_READ, + KSMETHOD_STREAMIO_WRITE +}KSMETHOD_STREAMIO; + +#define DEFINE_KSMETHOD_ITEM_STREAMIO_READ(Handler) \ + DEFINE_KSMETHOD_ITEM( \ + KSMETHOD_STREAMIO_READ, \ + KSMETHOD_TYPE_WRITE, \ + (Handler), \ + sizeof(KSMETHOD), \ + 0, \ + NULL) + +#define DEFINE_KSMETHOD_ITEM_STREAMIO_WRITE(Handler) \ + DEFINE_KSMETHOD_ITEM( \ + KSMETHOD_STREAMIO_WRITE, \ + KSMETHOD_TYPE_READ, \ + (Handler), \ + sizeof(KSMETHOD), \ + 0, \ + NULL) + +#define STATIC_KSPROPSETID_MediaSeeking \ + 0xEE904F0CL, 0xD09B, 0x11D0, 0xAB, 0xE9, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96 +DEFINE_GUIDSTRUCT("EE904F0C-D09B-11D0-ABE9-00A0C9223196", KSPROPSETID_MediaSeeking); +#define KSPROPSETID_MediaSeeking DEFINE_GUIDNAMED(KSPROPSETID_MediaSeeking) + +typedef enum +{ + KSPROPERTY_MEDIASEEKING_CAPABILITIES, + KSPROPERTY_MEDIASEEKING_FORMATS, + KSPROPERTY_MEDIASEEKING_TIMEFORMAT, + KSPROPERTY_MEDIASEEKING_POSITION, + KSPROPERTY_MEDIASEEKING_STOPPOSITION, + KSPROPERTY_MEDIASEEKING_POSITIONS, + KSPROPERTY_MEDIASEEKING_DURATION, + KSPROPERTY_MEDIASEEKING_AVAILABLE, + KSPROPERTY_MEDIASEEKING_PREROLL, + KSPROPERTY_MEDIASEEKING_CONVERTTIMEFORMAT +}KSPROPERTY_MEDIASEEKING; + +typedef enum +{ + KS_SEEKING_NoPositioning, + KS_SEEKING_AbsolutePositioning, + KS_SEEKING_RelativePositioning, + KS_SEEKING_IncrementalPositioning, + KS_SEEKING_PositioningBitsMask = 0x3, + KS_SEEKING_SeekToKeyFrame, + KS_SEEKING_ReturnTime = 0x8 +}KS_SEEKING_FLAGS; + +typedef enum +{ + KS_SEEKING_CanSeekAbsolute = 0x1, + KS_SEEKING_CanSeekForwards = 0x2, + KS_SEEKING_CanSeekBackwards = 0x4, + KS_SEEKING_CanGetCurrentPos = 0x8, + KS_SEEKING_CanGetStopPos = 0x10, + KS_SEEKING_CanGetDuration = 0x20, + KS_SEEKING_CanPlayBackwards = 0x40 +}KS_SEEKING_CAPABILITIES; + +typedef struct +{ + LONGLONG Current; + LONGLONG Stop; + KS_SEEKING_FLAGS CurrentFlags; + KS_SEEKING_FLAGS StopFlags; +}KSPROPERTY_POSITIONS, * PKSPROPERTY_POSITIONS; + +typedef struct +{ + LONGLONG Earliest; + LONGLONG Latest; +}KSPROPERTY_MEDIAAVAILABLE, * PKSPROPERTY_MEDIAAVAILABLE; + +typedef struct +{ + KSPROPERTY Property; + GUID SourceFormat; + GUID TargetFormat; + LONGLONG Time; +}KSP_TIMEFORMAT, * PKSP_TIMEFORMAT; + +#define DEFINE_KSPROPERTY_ITEM_MEDIASEEKING_CAPABILITIES(Handler) \ + DEFINE_KSPROPERTY_ITEM( \ + KSPROPERTY_MEDIASEEKING_CAPABILITIES, \ + (Handler), \ + sizeof(KSPROPERTY), \ + sizeof(KS_SEEKING_CAPABILITIES), \ + NULL, NULL, 0, NULL, NULL, 0) + +#define DEFINE_KSPROPERTY_ITEM_MEDIASEEKING_FORMATS(Handler) \ + DEFINE_KSPROPERTY_ITEM( \ + KSPROPERTY_MEDIASEEKING_FORMATS, \ + (Handler), \ + sizeof(KSPROPERTY), \ + 0, \ + NULL, NULL, 0, NULL, NULL, 0) + +#define DEFINE_KSPROPERTY_ITEM_MEDIASEEKING_TIMEFORMAT(GetHandler, SetHandler) \ + DEFINE_KSPROPERTY_ITEM( \ + KSPROPERTY_MEDIASEEKING_TIMEFORMAT, \ + (GetHandler), \ + sizeof(KSPROPERTY), \ + sizeof(GUID), \ + (SetHandler), \ + NULL, 0, NULL, NULL, 0) + +#define DEFINE_KSPROPERTY_ITEM_MEDIASEEKING_POSITION(Handler) \ + DEFINE_KSPROPERTY_ITEM( \ + KSPROPERTY_MEDIASEEKING_POSITION, \ + (Handler), \ + sizeof(KSPROPERTY), \ + sizeof(LONGLONG), \ + NULL, NULL, 0, NULL, NULL, 0) + +#define DEFINE_KSPROPERTY_ITEM_MEDIASEEKING_STOPPOSITION(Handler) \ + DEFINE_KSPROPERTY_ITEM( \ + KSPROPERTY_MEDIASEEKING_STOPPOSITION, \ + (Handler), \ + sizeof(KSPROPERTY), \ + sizeof(LONGLONG), \ + NULL, NULL, 0, NULL, NULL, 0) + +#define DEFINE_KSPROPERTY_ITEM_MEDIASEEKING_POSITIONS(Handler) \ + DEFINE_KSPROPERTY_ITEM( \ + KSPROPERTY_MEDIASEEKING_POSITIONS, \ + NULL, \ + sizeof(KSPROPERTY), \ + sizeof(KSPROPERTY_POSITIONS), \ + (Handler), \ + NULL, 0, NULL, NULL, 0) + +#define DEFINE_KSPROPERTY_ITEM_MEDIASEEKING_DURATION(Handler) \ + DEFINE_KSPROPERTY_ITEM( \ + KSPROPERTY_MEDIASEEKING_DURATION, \ + (Handler), \ + sizeof(KSPROPERTY), \ + sizeof(LONGLONG), \ + NULL, NULL, 0, NULL, NULL, 0) + +#define DEFINE_KSPROPERTY_ITEM_MEDIASEEKING_AVAILABLE(Handler) \ + DEFINE_KSPROPERTY_ITEM( \ + KSPROPERTY_MEDIASEEKING_AVAILABLE, \ + (Handler), \ + sizeof(KSPROPERTY), \ + sizeof(KSPROPERTY_MEDIAAVAILABLE), \ + NULL, NULL, 0, NULL, NULL, 0) + +#define DEFINE_KSPROPERTY_ITEM_MEDIASEEKING_PREROLL(Handler) \ + DEFINE_KSPROPERTY_ITEM( \ + KSPROPERTY_MEDIASEEKING_PREROLL, \ + (Handler), \ + sizeof(KSPROPERTY), \ + sizeof(LONGLONG), \ + NULL, NULL, 0, NULL, NULL, 0) + +#define DEFINE_KSPROPERTY_ITEM_MEDIASEEKING_CONVERTTIMEFORMAT(Handler) \ + DEFINE_KSPROPERTY_ITEM( \ + KSPROPERTY_MEDIASEEKING_CONVERTTIMEFORMAT, \ + (Handler), \ + sizeof(KSP_TIMEFORMAT), \ + sizeof(LONGLONG), \ + NULL, NULL, 0, NULL, NULL, 0) + +#define STATIC_KSPROPSETID_Topology \ + 0x720D4AC0L, 0x7533, 0x11D0, { 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00 } +DEFINE_GUIDSTRUCT("720D4AC0-7533-11D0-A5D6-28DB04C10000", KSPROPSETID_Topology); +#define KSPROPSETID_Topology DEFINE_GUIDNAMED(KSPROPSETID_Topology) + +typedef enum +{ + KSPROPERTY_TOPOLOGY_CATEGORIES, + KSPROPERTY_TOPOLOGY_NODES, + KSPROPERTY_TOPOLOGY_CONNECTIONS, + KSPROPERTY_TOPOLOGY_NAME +}KSPROPERTY_TOPOLOGY; + +#define DEFINE_KSPROPERTY_ITEM_TOPOLOGY_CATEGORIES(Handler) \ + DEFINE_KSPROPERTY_ITEM( \ + KSPROPERTY_TOPOLOGY_CATEGORIES, \ + (Handler), \ + sizeof(KSPROPERTY), \ + 0, \ + NULL, NULL, 0, NULL, NULL, 0) + +#define DEFINE_KSPROPERTY_ITEM_TOPOLOGY_NODES(Handler) \ + DEFINE_KSPROPERTY_ITEM( \ + KSPROPERTY_TOPOLOGY_NODES, \ + (Handler), \ + sizeof(KSPROPERTY), \ + 0, \ + NULL, NULL, 0, NULL, NULL, 0) + +#define DEFINE_KSPROPERTY_ITEM_TOPOLOGY_CONNECTIONS(Handler) \ + DEFINE_KSPROPERTY_ITEM( \ + KSPROPERTY_TOPOLOGY_CONNECTIONS, \ + (Handler), \ + sizeof(KSPROPERTY), \ + 0, \ + NULL, NULL, 0, NULL, NULL, 0) + +#define DEFINE_KSPROPERTY_ITEM_TOPOLOGY_NAME(Handler) \ + DEFINE_KSPROPERTY_ITEM( \ + KSPROPERTY_TOPOLOGY_NAME, \ + (Handler), \ + sizeof(KSP_NODE), \ + 0, \ + NULL, NULL, 0, NULL, NULL, 0) + +#define DEFINE_KSPROPERTY_TOPOLOGYSET(TopologySet, Handler) \ + DEFINE_KSPROPERTY_TABLE(TopologySet) { \ + DEFINE_KSPROPERTY_ITEM_TOPOLOGY_CATEGORIES(Handler), \ + DEFINE_KSPROPERTY_ITEM_TOPOLOGY_NODES(Handler), \ + DEFINE_KSPROPERTY_ITEM_TOPOLOGY_CONNECTIONS(Handler), \ + DEFINE_KSPROPERTY_ITEM_TOPOLOGY_NAME(Handler) \ + } + +#define STATIC_KSCATEGORY_BRIDGE \ + 0x085AFF00L, 0x62CE, 0x11CF, 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00 +DEFINE_GUIDSTRUCT("085AFF00-62CE-11CF-A5D6-28DB04C10000", KSCATEGORY_BRIDGE); +#define KSCATEGORY_BRIDGE DEFINE_GUIDNAMED(KSCATEGORY_BRIDGE) + +#define STATIC_KSCATEGORY_CAPTURE \ + 0x65E8773DL, 0x8F56, 0x11D0, { 0xA3, 0xB9, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96 } +DEFINE_GUIDSTRUCT("65E8773D-8F56-11D0-A3B9-00A0C9223196", KSCATEGORY_CAPTURE); +#define KSCATEGORY_CAPTURE DEFINE_GUIDNAMED(KSCATEGORY_CAPTURE) + +#define STATIC_KSCATEGORY_RENDER \ + 0x65E8773EL, 0x8F56, 0x11D0, { 0xA3, 0xB9, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96 } +DEFINE_GUIDSTRUCT("65E8773E-8F56-11D0-A3B9-00A0C9223196", KSCATEGORY_RENDER); +#define KSCATEGORY_RENDER DEFINE_GUIDNAMED(KSCATEGORY_RENDER) + +#define STATIC_KSCATEGORY_MIXER \ + 0xAD809C00L, 0x7B88, 0x11D0, 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00 +DEFINE_GUIDSTRUCT("AD809C00-7B88-11D0-A5D6-28DB04C10000", KSCATEGORY_MIXER); +#define KSCATEGORY_MIXER DEFINE_GUIDNAMED(KSCATEGORY_MIXER) + +#define STATIC_KSCATEGORY_SPLITTER \ + 0x0A4252A0L, 0x7E70, 0x11D0, 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00 +DEFINE_GUIDSTRUCT("0A4252A0-7E70-11D0-A5D6-28DB04C10000", KSCATEGORY_SPLITTER); +#define KSCATEGORY_SPLITTER DEFINE_GUIDNAMED(KSCATEGORY_SPLITTER) + +#define STATIC_KSCATEGORY_DATACOMPRESSOR \ + 0x1E84C900L, 0x7E70, 0x11D0, 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00 +DEFINE_GUIDSTRUCT("1E84C900-7E70-11D0-A5D6-28DB04C10000", KSCATEGORY_DATACOMPRESSOR); +#define KSCATEGORY_DATACOMPRESSOR DEFINE_GUIDNAMED(KSCATEGORY_DATACOMPRESSOR) + +#define STATIC_KSCATEGORY_DATADECOMPRESSOR \ + 0x2721AE20L, 0x7E70, 0x11D0, 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00 +DEFINE_GUIDSTRUCT("2721AE20-7E70-11D0-A5D6-28DB04C10000", KSCATEGORY_DATADECOMPRESSOR); +#define KSCATEGORY_DATADECOMPRESSOR DEFINE_GUIDNAMED(KSCATEGORY_DATADECOMPRESSOR) + +#define STATIC_KSCATEGORY_DATATRANSFORM \ + 0x2EB07EA0L, 0x7E70, 0x11D0, 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00 +DEFINE_GUIDSTRUCT("2EB07EA0-7E70-11D0-A5D6-28DB04C10000", KSCATEGORY_DATATRANSFORM); +#define KSCATEGORY_DATATRANSFORM DEFINE_GUIDNAMED(KSCATEGORY_DATATRANSFORM) + +#define STATIC_KSCATEGORY_COMMUNICATIONSTRANSFORM \ + 0xCF1DDA2CL, 0x9743, 0x11D0, 0xA3, 0xEE, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96 +DEFINE_GUIDSTRUCT("CF1DDA2C-9743-11D0-A3EE-00A0C9223196", KSCATEGORY_COMMUNICATIONSTRANSFORM); +#define KSCATEGORY_COMMUNICATIONSTRANSFORM DEFINE_GUIDNAMED(KSCATEGORY_COMMUNICATIONSTRANSFORM) + +#define STATIC_KSCATEGORY_INTERFACETRANSFORM \ + 0xCF1DDA2DL, 0x9743, 0x11D0, 0xA3, 0xEE, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96 +DEFINE_GUIDSTRUCT("CF1DDA2D-9743-11D0-A3EE-00A0C9223196", KSCATEGORY_INTERFACETRANSFORM); +#define KSCATEGORY_INTERFACETRANSFORM DEFINE_GUIDNAMED(KSCATEGORY_INTERFACETRANSFORM) + +#define STATIC_KSCATEGORY_MEDIUMTRANSFORM \ + 0xCF1DDA2EL, 0x9743, 0x11D0, 0xA3, 0xEE, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96 +DEFINE_GUIDSTRUCT("CF1DDA2E-9743-11D0-A3EE-00A0C9223196", KSCATEGORY_MEDIUMTRANSFORM); +#define KSCATEGORY_MEDIUMTRANSFORM DEFINE_GUIDNAMED(KSCATEGORY_MEDIUMTRANSFORM) + +#define STATIC_KSCATEGORY_FILESYSTEM \ + 0x760FED5EL, 0x9357, 0x11D0, 0xA3, 0xCC, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96 +DEFINE_GUIDSTRUCT("760FED5E-9357-11D0-A3CC-00A0C9223196", KSCATEGORY_FILESYSTEM); +#define KSCATEGORY_FILESYSTEM DEFINE_GUIDNAMED(KSCATEGORY_FILESYSTEM) + +#define STATIC_KSCATEGORY_CLOCK \ + 0x53172480L, 0x4791, 0x11D0, 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00 +DEFINE_GUIDSTRUCT("53172480-4791-11D0-A5D6-28DB04C10000", KSCATEGORY_CLOCK); +#define KSCATEGORY_CLOCK DEFINE_GUIDNAMED(KSCATEGORY_CLOCK) + +#define STATIC_KSCATEGORY_PROXY \ + 0x97EBAACAL, 0x95BD, 0x11D0, 0xA3, 0xEA, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96 +DEFINE_GUIDSTRUCT("97EBAACA-95BD-11D0-A3EA-00A0C9223196", KSCATEGORY_PROXY); +#define KSCATEGORY_PROXY DEFINE_GUIDNAMED(KSCATEGORY_PROXY) + +#define STATIC_KSCATEGORY_QUALITY \ + 0x97EBAACBL, 0x95BD, 0x11D0, 0xA3, 0xEA, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96 +DEFINE_GUIDSTRUCT("97EBAACB-95BD-11D0-A3EA-00A0C9223196", KSCATEGORY_QUALITY); +#define KSCATEGORY_QUALITY DEFINE_GUIDNAMED(KSCATEGORY_QUALITY) + +typedef struct +{ + ULONG FromNode; + ULONG FromNodePin; + ULONG ToNode; + ULONG ToNodePin; +}KSTOPOLOGY_CONNECTION, * PKSTOPOLOGY_CONNECTION; + +typedef struct +{ + ULONG CategoriesCount; + const GUID* Categories; + ULONG TopologyNodesCount; + const GUID* TopologyNodes; + ULONG TopologyConnectionsCount; + const KSTOPOLOGY_CONNECTION* TopologyConnections; + const GUID* TopologyNodesNames; + ULONG Reserved; +}KSTOPOLOGY, * PKSTOPOLOGY; + +#define KSFILTER_NODE ((ULONG)-1) +#define KSALL_NODES ((ULONG)-1) + +typedef struct +{ + ULONG CreateFlags; + ULONG Node; +}KSNODE_CREATE, * PKSNODE_CREATE; + +#define STATIC_KSTIME_FORMAT_NONE STATIC_GUID_NULL +#define KSTIME_FORMAT_NONE GUID_NULL + +#define STATIC_KSTIME_FORMAT_FRAME \ + 0x7b785570L, 0x8c82, 0x11cf, 0xbc, 0x0c, 0x00, 0xaa, 0x00, 0xac, 0x74, 0xf6 +DEFINE_GUIDSTRUCT("7b785570-8c82-11cf-bc0c-00aa00ac74f6", KSTIME_FORMAT_FRAME); +#define KSTIME_FORMAT_FRAME DEFINE_GUIDNAMED(KSTIME_FORMAT_FRAME) + +#define STATIC_KSTIME_FORMAT_BYTE \ + 0x7b785571L, 0x8c82, 0x11cf, 0xbc, 0x0c, 0x00, 0xaa, 0x00, 0xac, 0x74, 0xf6 +DEFINE_GUIDSTRUCT("7b785571-8c82-11cf-bc0c-00aa00ac74f6", KSTIME_FORMAT_BYTE); +#define KSTIME_FORMAT_BYTE DEFINE_GUIDNAMED(KSTIME_FORMAT_BYTE) + +#define STATIC_KSTIME_FORMAT_SAMPLE \ + 0x7b785572L, 0x8c82, 0x11cf, 0xbc, 0x0c, 0x00, 0xaa, 0x00, 0xac, 0x74, 0xf6 +DEFINE_GUIDSTRUCT("7b785572-8c82-11cf-bc0c-00aa00ac74f6", KSTIME_FORMAT_SAMPLE); +#define KSTIME_FORMAT_SAMPLE DEFINE_GUIDNAMED(KSTIME_FORMAT_SAMPLE) + +#define STATIC_KSTIME_FORMAT_FIELD \ + 0x7b785573L, 0x8c82, 0x11cf, 0xbc, 0x0c, 0x00, 0xaa, 0x00, 0xac, 0x74, 0xf6 +DEFINE_GUIDSTRUCT("7b785573-8c82-11cf-bc0c-00aa00ac74f6", KSTIME_FORMAT_FIELD); +#define KSTIME_FORMAT_FIELD DEFINE_GUIDNAMED(KSTIME_FORMAT_FIELD) + +#define STATIC_KSTIME_FORMAT_MEDIA_TIME \ + 0x7b785574L, 0x8c82, 0x11cf, 0xbc, 0x0c, 0x00, 0xaa, 0x00, 0xac, 0x74, 0xf6 +DEFINE_GUIDSTRUCT("7b785574-8c82-11cf-bc0c-00aa00ac74f6", KSTIME_FORMAT_MEDIA_TIME); +#define KSTIME_FORMAT_MEDIA_TIME DEFINE_GUIDNAMED(KSTIME_FORMAT_MEDIA_TIME) + +typedef KSIDENTIFIER KSPIN_INTERFACE, * PKSPIN_INTERFACE; + +#define STATIC_KSINTERFACESETID_Standard \ + 0x1A8766A0L, 0x62CE, 0x11CF, { 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00 } +DEFINE_GUIDSTRUCT("1A8766A0-62CE-11CF-A5D6-28DB04C10000", KSINTERFACESETID_Standard); +#define KSINTERFACESETID_Standard DEFINE_GUIDNAMED(KSINTERFACESETID_Standard) + +typedef enum +{ + KSINTERFACE_STANDARD_STREAMING, + KSINTERFACE_STANDARD_LOOPED_STREAMING, + KSINTERFACE_STANDARD_CONTROL +}KSINTERFACE_STANDARD; + +#define STATIC_KSINTERFACESETID_FileIo \ + 0x8C6F932CL, 0xE771, 0x11D0, 0xB8, 0xFF, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96 +DEFINE_GUIDSTRUCT("8C6F932C-E771-11D0-B8FF-00A0C9223196", KSINTERFACESETID_FileIo); +#define KSINTERFACESETID_FileIo DEFINE_GUIDNAMED(KSINTERFACESETID_FileIo) + +typedef enum +{ + KSINTERFACE_FILEIO_STREAMING +}KSINTERFACE_FILEIO; + +#define KSMEDIUM_TYPE_ANYINSTANCE 0 + +#define STATIC_KSMEDIUMSETID_Standard \ + 0x4747B320L, 0x62CE, 0x11CF, { 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00 } +DEFINE_GUIDSTRUCT("4747B320-62CE-11CF-A5D6-28DB04C10000", KSMEDIUMSETID_Standard); +#define KSMEDIUMSETID_Standard DEFINE_GUIDNAMED(KSMEDIUMSETID_Standard) + +#define KSMEDIUM_STANDARD_DEVIO KSMEDIUM_TYPE_ANYINSTANCE + +#define STATIC_KSPROPSETID_Pin \ + 0x8C134960L, 0x51AD, 0x11CF, { 0x87, 0x8A, 0x94, 0xF8, 0x01, 0xC1, 0x00, 0x00 } +DEFINE_GUIDSTRUCT("8C134960-51AD-11CF-878A-94F801C10000", KSPROPSETID_Pin); +#define KSPROPSETID_Pin DEFINE_GUIDNAMED(KSPROPSETID_Pin) + +typedef enum +{ + KSPROPERTY_PIN_CINSTANCES, + KSPROPERTY_PIN_CTYPES, + KSPROPERTY_PIN_DATAFLOW, + KSPROPERTY_PIN_DATARANGES, + KSPROPERTY_PIN_DATAINTERSECTION, + KSPROPERTY_PIN_INTERFACES, + KSPROPERTY_PIN_MEDIUMS, + KSPROPERTY_PIN_COMMUNICATION, + KSPROPERTY_PIN_GLOBALCINSTANCES, + KSPROPERTY_PIN_NECESSARYINSTANCES, + KSPROPERTY_PIN_PHYSICALCONNECTION, + KSPROPERTY_PIN_CATEGORY, + KSPROPERTY_PIN_NAME, + KSPROPERTY_PIN_CONSTRAINEDDATARANGES, + KSPROPERTY_PIN_PROPOSEDATAFORMAT +}KSPROPERTY_PIN; + +typedef struct +{ + KSPROPERTY Property; + ULONG PinId; + ULONG Reserved; +}KSP_PIN, * PKSP_PIN; + +#define KSINSTANCE_INDETERMINATE ((ULONG)-1) + +typedef struct +{ + ULONG PossibleCount; + ULONG CurrentCount; +}KSPIN_CINSTANCES, * PKSPIN_CINSTANCES; + +typedef enum +{ + KSPIN_DATAFLOW_IN = 1, + KSPIN_DATAFLOW_OUT +}KSPIN_DATAFLOW, * PKSPIN_DATAFLOW; + +#define KSDATAFORMAT_BIT_TEMPORAL_COMPRESSION 0 +#define KSDATAFORMAT_TEMPORAL_COMPRESSION (1 << KSDATAFORMAT_BIT_TEMPORAL_COMPRESSION) +#define KSDATAFORMAT_BIT_ATTRIBUTES 1 +#define KSDATAFORMAT_ATTRIBUTES (1 << KSDATAFORMAT_BIT_ATTRIBUTES) + +#define KSDATARANGE_BIT_ATTRIBUTES 1 +#define KSDATARANGE_ATTRIBUTES (1 << KSDATARANGE_BIT_ATTRIBUTES) +#define KSDATARANGE_BIT_REQUIRED_ATTRIBUTES 2 +#define KSDATARANGE_REQUIRED_ATTRIBUTES (1 << KSDATARANGE_BIT_REQUIRED_ATTRIBUTES) + +typedef union +{ + __MINGW_EXTENSION struct + { + ULONG FormatSize; + ULONG Flags; + ULONG SampleSize; + ULONG Reserved; + GUID MajorFormat; + GUID SubFormat; + GUID Specifier; + }; + LONGLONG Alignment; +}KSDATAFORMAT, * PKSDATAFORMAT, KSDATARANGE, * PKSDATARANGE; + +#define KSATTRIBUTE_REQUIRED 0x00000001 + +typedef struct +{ + ULONG Size; + ULONG Flags; + GUID Attribute; +}KSATTRIBUTE, * PKSATTRIBUTE; + +#if defined(_NTDDK_) +typedef struct +{ + ULONG Count; + PKSATTRIBUTE* Attributes; +}KSATTRIBUTE_LIST, * PKSATTRIBUTE_LIST; +#endif /* _NTDDK_ */ + +typedef enum +{ + KSPIN_COMMUNICATION_NONE, + KSPIN_COMMUNICATION_SINK, + KSPIN_COMMUNICATION_SOURCE, + KSPIN_COMMUNICATION_BOTH, + KSPIN_COMMUNICATION_BRIDGE +}KSPIN_COMMUNICATION, * PKSPIN_COMMUNICATION; + +typedef KSIDENTIFIER KSPIN_MEDIUM, * PKSPIN_MEDIUM; + +typedef struct +{ + KSPIN_INTERFACE Interface; + KSPIN_MEDIUM Medium; + ULONG PinId; + HANDLE PinToHandle; + KSPRIORITY Priority; +}KSPIN_CONNECT, * PKSPIN_CONNECT; + +typedef struct +{ + ULONG Size; + ULONG Pin; + WCHAR SymbolicLinkName[1]; +}KSPIN_PHYSICALCONNECTION, * PKSPIN_PHYSICALCONNECTION; + +#if defined(_NTDDK_) +typedef NTSTATUS (*PFNKSINTERSECTHANDLER)(PIRP Irp, PKSP_PIN Pin, + PKSDATARANGE DataRange, + PVOID Data); +typedef NTSTATUS (*PFNKSINTERSECTHANDLEREX)(PVOID Context, PIRP Irp, + PKSP_PIN Pin, + PKSDATARANGE DataRange, + PKSDATARANGE MatchingDataRange, + ULONG DataBufferSize, + PVOID Data, + PULONG DataSize); +#endif /* _NTDDK_ */ + +#define DEFINE_KSPIN_INTERFACE_TABLE(tablename) \ + const KSPIN_INTERFACE tablename[] = + +#define DEFINE_KSPIN_INTERFACE_ITEM(guid, _interFace) \ + { \ + STATICGUIDOF(guid), \ + (_interFace), \ + 0 \ + } + +#define DEFINE_KSPIN_MEDIUM_TABLE(tablename) \ + const KSPIN_MEDIUM tablename[] = + +#define DEFINE_KSPIN_MEDIUM_ITEM(guid, medium) \ + DEFINE_KSPIN_INTERFACE_ITEM(guid, medium) + +#define DEFINE_KSPROPERTY_ITEM_PIN_CINSTANCES(Handler) \ + DEFINE_KSPROPERTY_ITEM( \ + KSPROPERTY_PIN_CINSTANCES, \ + (Handler), \ + sizeof(KSP_PIN), \ + sizeof(KSPIN_CINSTANCES), \ + NULL, NULL, 0, NULL, NULL, 0) + +#define DEFINE_KSPROPERTY_ITEM_PIN_CTYPES(Handler) \ + DEFINE_KSPROPERTY_ITEM( \ + KSPROPERTY_PIN_CTYPES, \ + (Handler), \ + sizeof(KSPROPERTY), \ + sizeof(ULONG), \ + NULL, NULL, 0, NULL, NULL, 0) + +#define DEFINE_KSPROPERTY_ITEM_PIN_DATAFLOW(Handler) \ + DEFINE_KSPROPERTY_ITEM( \ + KSPROPERTY_PIN_DATAFLOW, \ + (Handler), \ + sizeof(KSP_PIN), \ + sizeof(KSPIN_DATAFLOW), \ + NULL, NULL, 0, NULL, NULL, 0) + +#define DEFINE_KSPROPERTY_ITEM_PIN_DATARANGES(Handler) \ + DEFINE_KSPROPERTY_ITEM( \ + KSPROPERTY_PIN_DATARANGES, \ + (Handler), \ + sizeof(KSP_PIN), \ + 0, \ + NULL, NULL, 0, NULL, NULL, 0) + +#define DEFINE_KSPROPERTY_ITEM_PIN_DATAINTERSECTION(Handler) \ + DEFINE_KSPROPERTY_ITEM( \ + KSPROPERTY_PIN_DATAINTERSECTION, \ + (Handler), \ + sizeof(KSP_PIN) + sizeof(KSMULTIPLE_ITEM), \ + 0, \ + NULL, NULL, 0, NULL, NULL, 0) + +#define DEFINE_KSPROPERTY_ITEM_PIN_INTERFACES(Handler) \ + DEFINE_KSPROPERTY_ITEM( \ + KSPROPERTY_PIN_INTERFACES, \ + (Handler), \ + sizeof(KSP_PIN), \ + 0, \ + NULL, NULL, 0, NULL, NULL, 0) + +#define DEFINE_KSPROPERTY_ITEM_PIN_MEDIUMS(Handler) \ + DEFINE_KSPROPERTY_ITEM( \ + KSPROPERTY_PIN_MEDIUMS, \ + (Handler), \ + sizeof(KSP_PIN), \ + 0, \ + NULL, NULL, 0, NULL, NULL, 0) + +#define DEFINE_KSPROPERTY_ITEM_PIN_COMMUNICATION(Handler) \ + DEFINE_KSPROPERTY_ITEM( \ + KSPROPERTY_PIN_COMMUNICATION, \ + (Handler), \ + sizeof(KSP_PIN), \ + sizeof(KSPIN_COMMUNICATION), \ + NULL, NULL, 0, NULL, NULL, 0) + +#define DEFINE_KSPROPERTY_ITEM_PIN_GLOBALCINSTANCES(Handler) \ + DEFINE_KSPROPERTY_ITEM( \ + KSPROPERTY_PIN_GLOBALCINSTANCES, \ + (Handler), \ + sizeof(KSP_PIN), \ + sizeof(KSPIN_CINSTANCES), \ + NULL, NULL, 0, NULL, NULL, 0) + +#define DEFINE_KSPROPERTY_ITEM_PIN_NECESSARYINSTANCES(Handler) \ + DEFINE_KSPROPERTY_ITEM( \ + KSPROPERTY_PIN_NECESSARYINSTANCES, \ + (Handler), \ + sizeof(KSP_PIN), \ + sizeof(ULONG), \ + NULL, NULL, 0, NULL, NULL, 0) + +#define DEFINE_KSPROPERTY_ITEM_PIN_PHYSICALCONNECTION(Handler) \ + DEFINE_KSPROPERTY_ITEM( \ + KSPROPERTY_PIN_PHYSICALCONNECTION, \ + (Handler), \ + sizeof(KSP_PIN), \ + 0, \ + NULL, NULL, 0, NULL, NULL, 0) + +#define DEFINE_KSPROPERTY_ITEM_PIN_CATEGORY(Handler) \ + DEFINE_KSPROPERTY_ITEM( \ + KSPROPERTY_PIN_CATEGORY, \ + (Handler), \ + sizeof(KSP_PIN), \ + sizeof(GUID), \ + NULL, NULL, 0, NULL, NULL, 0) + +#define DEFINE_KSPROPERTY_ITEM_PIN_NAME(Handler) \ + DEFINE_KSPROPERTY_ITEM( \ + KSPROPERTY_PIN_NAME, \ + (Handler), \ + sizeof(KSP_PIN), \ + 0, \ + NULL, NULL, 0, NULL, NULL, 0) + +#define DEFINE_KSPROPERTY_ITEM_PIN_CONSTRAINEDDATARANGES(Handler) \ + DEFINE_KSPROPERTY_ITEM( \ + KSPROPERTY_PIN_CONSTRAINEDDATARANGES, \ + (Handler), \ + sizeof(KSP_PIN), \ + 0, \ + NULL, NULL, 0, NULL, NULL, 0) + +#define DEFINE_KSPROPERTY_ITEM_PIN_PROPOSEDATAFORMAT(Handler) \ + DEFINE_KSPROPERTY_ITEM( \ + KSPROPERTY_PIN_PROPOSEDATAFORMAT, \ + NULL, \ + sizeof(KSP_PIN), \ + sizeof(KSDATAFORMAT), \ + (Handler), NULL, 0, NULL, NULL, 0) + +#define DEFINE_KSPROPERTY_PINSET(PinSet, PropGeneral, PropInstances, PropIntersection) \ + DEFINE_KSPROPERTY_TABLE(PinSet) { \ + DEFINE_KSPROPERTY_ITEM_PIN_CINSTANCES(PropInstances), \ + DEFINE_KSPROPERTY_ITEM_PIN_CTYPES(PropGeneral), \ + DEFINE_KSPROPERTY_ITEM_PIN_DATAFLOW(PropGeneral), \ + DEFINE_KSPROPERTY_ITEM_PIN_DATARANGES(PropGeneral), \ + DEFINE_KSPROPERTY_ITEM_PIN_DATAINTERSECTION(PropIntersection), \ + DEFINE_KSPROPERTY_ITEM_PIN_INTERFACES(PropGeneral), \ + DEFINE_KSPROPERTY_ITEM_PIN_MEDIUMS(PropGeneral), \ + DEFINE_KSPROPERTY_ITEM_PIN_COMMUNICATION(PropGeneral), \ + DEFINE_KSPROPERTY_ITEM_PIN_CATEGORY(PropGeneral), \ + DEFINE_KSPROPERTY_ITEM_PIN_NAME(PropGeneral) \ + } + +#define DEFINE_KSPROPERTY_PINSETCONSTRAINED(PinSet, PropGeneral, PropInstances, PropIntersection) \ + DEFINE_KSPROPERTY_TABLE(PinSet) { \ + DEFINE_KSPROPERTY_ITEM_PIN_CINSTANCES(PropInstances), \ + DEFINE_KSPROPERTY_ITEM_PIN_CTYPES(PropGeneral), \ + DEFINE_KSPROPERTY_ITEM_PIN_DATAFLOW(PropGeneral), \ + DEFINE_KSPROPERTY_ITEM_PIN_DATARANGES(PropGeneral), \ + DEFINE_KSPROPERTY_ITEM_PIN_DATAINTERSECTION(PropIntersection), \ + DEFINE_KSPROPERTY_ITEM_PIN_INTERFACES(PropGeneral), \ + DEFINE_KSPROPERTY_ITEM_PIN_MEDIUMS(PropGeneral), \ + DEFINE_KSPROPERTY_ITEM_PIN_COMMUNICATION(PropGeneral), \ + DEFINE_KSPROPERTY_ITEM_PIN_CATEGORY(PropGeneral), \ + DEFINE_KSPROPERTY_ITEM_PIN_NAME(PropGeneral), \ + DEFINE_KSPROPERTY_ITEM_PIN_CONSTRAINEDDATARANGES(PropGeneral) \ + } + +#define STATIC_KSNAME_Filter \ + 0x9b365890L, 0x165f, 0x11d0, 0xa1, 0x95, 0x00, 0x20, 0xaf, 0xd1, 0x56, 0xe4 +DEFINE_GUIDSTRUCT("9b365890-165f-11d0-a195-0020afd156e4", KSNAME_Filter); +#define KSNAME_Filter DEFINE_GUIDNAMED(KSNAME_Filter) + +#define KSSTRING_Filter L"{9B365890-165F-11D0-A195-0020AFD156E4}" + +#define STATIC_KSNAME_Pin \ + 0x146F1A80L, 0x4791, 0x11D0, 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00 +DEFINE_GUIDSTRUCT("146F1A80-4791-11D0-A5D6-28DB04C10000", KSNAME_Pin); +#define KSNAME_Pin DEFINE_GUIDNAMED(KSNAME_Pin) + +#define KSSTRING_Pin L"{146F1A80-4791-11D0-A5D6-28DB04C10000}" + +#define STATIC_KSNAME_Clock \ + 0x53172480L, 0x4791, 0x11D0, 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00 +DEFINE_GUIDSTRUCT("53172480-4791-11D0-A5D6-28DB04C10000", KSNAME_Clock); +#define KSNAME_Clock DEFINE_GUIDNAMED(KSNAME_Clock) + +#define KSSTRING_Clock L"{53172480-4791-11D0-A5D6-28DB04C10000}" + +#define STATIC_KSNAME_Allocator \ + 0x642F5D00L, 0x4791, 0x11D0, 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00 +DEFINE_GUIDSTRUCT("642F5D00-4791-11D0-A5D6-28DB04C10000", KSNAME_Allocator); +#define KSNAME_Allocator DEFINE_GUIDNAMED(KSNAME_Allocator) + +#define KSSTRING_Allocator L"{642F5D00-4791-11D0-A5D6-28DB04C10000}" + +#define KSSTRING_AllocatorEx L"{091BB63B-603F-11D1-B067-00A0C9062802}" + +#define STATIC_KSNAME_TopologyNode \ + 0x0621061AL, 0xEE75, 0x11D0, 0xB9, 0x15, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96 +DEFINE_GUIDSTRUCT("0621061A-EE75-11D0-B915-00A0C9223196", KSNAME_TopologyNode); +#define KSNAME_TopologyNode DEFINE_GUIDNAMED(KSNAME_TopologyNode) + +#define KSSTRING_TopologyNode L"{0621061A-EE75-11D0-B915-00A0C9223196}" + +#if defined(_NTDDK_) +typedef struct +{ + ULONG InterfacesCount; + const KSPIN_INTERFACE* Interfaces; + ULONG MediumsCount; + const KSPIN_MEDIUM* Mediums; + ULONG DataRangesCount; + const PKSDATARANGE* DataRanges; + KSPIN_DATAFLOW DataFlow; + KSPIN_COMMUNICATION Communication; + const GUID* Category; + const GUID* Name; + __MINGW_EXTENSION union + { + LONGLONG Reserved; + __MINGW_EXTENSION struct + { + ULONG ConstrainedDataRangesCount; + PKSDATARANGE* ConstrainedDataRanges; + }; + }; +}KSPIN_DESCRIPTOR, * PKSPIN_DESCRIPTOR; +typedef const KSPIN_DESCRIPTOR* PCKSPIN_DESCRIPTOR; + + # define DEFINE_KSPIN_DESCRIPTOR_TABLE(tablename) \ + const KSPIN_DESCRIPTOR tablename[] = + + # define DEFINE_KSPIN_DESCRIPTOR_ITEM(InterfacesCount, Interfaces, MediumsCount, Mediums, DataRangesCount, DataRanges, DataFlow, Communication) \ + { \ + InterfacesCount, Interfaces, MediumsCount, Mediums, \ + DataRangesCount, DataRanges, DataFlow, Communication, \ + NULL, NULL, 0 \ + } + + # define DEFINE_KSPIN_DESCRIPTOR_ITEMEX(InterfacesCount, Interfaces, MediumsCount, Mediums, DataRangesCount, DataRanges, DataFlow, Communication, Category, Name) \ + { \ + InterfacesCount, Interfaces, MediumsCount, Mediums, \ + DataRangesCount, DataRanges, DataFlow, Communication, \ + Category, Name, 0 \ + } +#endif /* _NTDDK_ */ + +#define STATIC_KSDATAFORMAT_TYPE_WILDCARD STATIC_GUID_NULL +#define KSDATAFORMAT_TYPE_WILDCARD GUID_NULL + +#define STATIC_KSDATAFORMAT_SUBTYPE_WILDCARD STATIC_GUID_NULL +#define KSDATAFORMAT_SUBTYPE_WILDCARD GUID_NULL + +#define STATIC_KSDATAFORMAT_TYPE_STREAM \ + 0xE436EB83L, 0x524F, 0x11CE, 0x9F, 0x53, 0x00, 0x20, 0xAF, 0x0B, 0xA7, 0x70 +DEFINE_GUIDSTRUCT("E436EB83-524F-11CE-9F53-0020AF0BA770", KSDATAFORMAT_TYPE_STREAM); +#define KSDATAFORMAT_TYPE_STREAM DEFINE_GUIDNAMED(KSDATAFORMAT_TYPE_STREAM) + +#define STATIC_KSDATAFORMAT_SUBTYPE_NONE \ + 0xE436EB8EL, 0x524F, 0x11CE, 0x9F, 0x53, 0x00, 0x20, 0xAF, 0x0B, 0xA7, 0x70 +DEFINE_GUIDSTRUCT("E436EB8E-524F-11CE-9F53-0020AF0BA770", KSDATAFORMAT_SUBTYPE_NONE); +#define KSDATAFORMAT_SUBTYPE_NONE DEFINE_GUIDNAMED(KSDATAFORMAT_SUBTYPE_NONE) + +#define STATIC_KSDATAFORMAT_SPECIFIER_WILDCARD STATIC_GUID_NULL +#define KSDATAFORMAT_SPECIFIER_WILDCARD GUID_NULL + +#define STATIC_KSDATAFORMAT_SPECIFIER_FILENAME \ + 0xAA797B40L, 0xE974, 0x11CF, 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00 +DEFINE_GUIDSTRUCT("AA797B40-E974-11CF-A5D6-28DB04C10000", KSDATAFORMAT_SPECIFIER_FILENAME); +#define KSDATAFORMAT_SPECIFIER_FILENAME DEFINE_GUIDNAMED(KSDATAFORMAT_SPECIFIER_FILENAME) + +#define STATIC_KSDATAFORMAT_SPECIFIER_FILEHANDLE \ + 0x65E8773CL, 0x8F56, 0x11D0, 0xA3, 0xB9, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96 +DEFINE_GUIDSTRUCT("65E8773C-8F56-11D0-A3B9-00A0C9223196", KSDATAFORMAT_SPECIFIER_FILEHANDLE); +#define KSDATAFORMAT_SPECIFIER_FILEHANDLE DEFINE_GUIDNAMED(KSDATAFORMAT_SPECIFIER_FILEHANDLE) + +#define STATIC_KSDATAFORMAT_SPECIFIER_NONE \ + 0x0F6417D6L, 0xC318, 0x11D0, { 0xA4, 0x3F, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96 } +DEFINE_GUIDSTRUCT("0F6417D6-C318-11D0-A43F-00A0C9223196", KSDATAFORMAT_SPECIFIER_NONE); +#define KSDATAFORMAT_SPECIFIER_NONE DEFINE_GUIDNAMED(KSDATAFORMAT_SPECIFIER_NONE) + +#define STATIC_KSPROPSETID_Quality \ + 0xD16AD380L, 0xAC1A, 0x11CF, 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00 +DEFINE_GUIDSTRUCT("D16AD380-AC1A-11CF-A5D6-28DB04C10000", KSPROPSETID_Quality); +#define KSPROPSETID_Quality DEFINE_GUIDNAMED(KSPROPSETID_Quality) + +typedef enum +{ + KSPROPERTY_QUALITY_REPORT, + KSPROPERTY_QUALITY_ERROR +}KSPROPERTY_QUALITY; + +#define DEFINE_KSPROPERTY_ITEM_QUALITY_REPORT(GetHandler, SetHandler) \ + DEFINE_KSPROPERTY_ITEM( \ + KSPROPERTY_QUALITY_REPORT, \ + (GetHandler), \ + sizeof(KSPROPERTY), \ + sizeof(KSQUALITY), \ + (SetHandler), \ + NULL, 0, NULL, NULL, 0) + +#define DEFINE_KSPROPERTY_ITEM_QUALITY_ERROR(GetHandler, SetHandler) \ + DEFINE_KSPROPERTY_ITEM( \ + KSPROPERTY_QUALITY_ERROR, \ + (GetHandler), \ + sizeof(KSPROPERTY), \ + sizeof(KSERROR), \ + (SetHandler), \ + NULL, 0, NULL, NULL, 0) + +#define STATIC_KSPROPSETID_Connection \ + 0x1D58C920L, 0xAC9B, 0x11CF, { 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00 } +DEFINE_GUIDSTRUCT("1D58C920-AC9B-11CF-A5D6-28DB04C10000", KSPROPSETID_Connection); +#define KSPROPSETID_Connection DEFINE_GUIDNAMED(KSPROPSETID_Connection) + +typedef enum +{ + KSPROPERTY_CONNECTION_STATE, + KSPROPERTY_CONNECTION_PRIORITY, + KSPROPERTY_CONNECTION_DATAFORMAT, + KSPROPERTY_CONNECTION_ALLOCATORFRAMING, + KSPROPERTY_CONNECTION_PROPOSEDATAFORMAT, + KSPROPERTY_CONNECTION_ACQUIREORDERING, + KSPROPERTY_CONNECTION_ALLOCATORFRAMING_EX, + KSPROPERTY_CONNECTION_STARTAT +}KSPROPERTY_CONNECTION; + +#define DEFINE_KSPROPERTY_ITEM_CONNECTION_STATE(GetHandler, SetHandler) \ + DEFINE_KSPROPERTY_ITEM( \ + KSPROPERTY_CONNECTION_STATE, \ + (GetHandler), \ + sizeof(KSPROPERTY), \ + sizeof(KSSTATE), \ + (SetHandler), \ + NULL, 0, NULL, NULL, 0) + +#define DEFINE_KSPROPERTY_ITEM_CONNECTION_PRIORITY(GetHandler, SetHandler) \ + DEFINE_KSPROPERTY_ITEM( \ + KSPROPERTY_CONNECTION_PRIORITY, \ + (GetHandler), \ + sizeof(KSPROPERTY), \ + sizeof(KSPRIORITY), \ + (SetHandler), \ + NULL, 0, NULL, NULL, 0) + +#define DEFINE_KSPROPERTY_ITEM_CONNECTION_DATAFORMAT(GetHandler, SetHandler) \ + DEFINE_KSPROPERTY_ITEM( \ + KSPROPERTY_CONNECTION_DATAFORMAT, \ + (GetHandler), \ + sizeof(KSPROPERTY), \ + 0, \ + (SetHandler), \ + NULL, 0, NULL, NULL, 0) + +#define DEFINE_KSPROPERTY_ITEM_CONNECTION_ALLOCATORFRAMING(Handler) \ + DEFINE_KSPROPERTY_ITEM( \ + KSPROPERTY_CONNECTION_ALLOCATORFRAMING, \ + (Handler), \ + sizeof(KSPROPERTY), \ + sizeof(KSALLOCATOR_FRAMING), \ + NULL, NULL, 0, NULL, NULL, 0) + +#define DEFINE_KSPROPERTY_ITEM_CONNECTION_ALLOCATORFRAMING_EX(Handler) \ + DEFINE_KSPROPERTY_ITEM( \ + KSPROPERTY_CONNECTION_ALLOCATORFRAMING_EX, \ + (Handler), \ + sizeof(KSPROPERTY), \ + 0, \ + NULL, NULL, 0, NULL, NULL, 0) + +#define DEFINE_KSPROPERTY_ITEM_CONNECTION_PROPOSEDATAFORMAT(Handler) \ + DEFINE_KSPROPERTY_ITEM( \ + KSPROPERTY_CONNECTION_PROPOSEDATAFORMAT, \ + NULL, \ + sizeof(KSPROPERTY), \ + sizeof(KSDATAFORMAT), \ + (Handler), \ + NULL, 0, NULL, NULL, 0) + +#define DEFINE_KSPROPERTY_ITEM_CONNECTION_ACQUIREORDERING(Handler) \ + DEFINE_KSPROPERTY_ITEM( \ + KSPROPERTY_CONNECTION_ACQUIREORDERING, \ + (Handler), \ + sizeof(KSPROPERTY), \ + sizeof(int), \ + NULL, NULL, 0, NULL, NULL, 0) + +#define DEFINE_KSPROPERTY_ITEM_CONNECTION_STARTAT(Handler) \ + DEFINE_KSPROPERTY_ITEM( \ + KSPROPERTY_CONNECTION_STARTAT, \ + NULL, \ + sizeof(KSPROPERTY), \ + sizeof(KSRELATIVEEVENT), \ + (Handler), \ + NULL, 0, NULL, NULL, 0) + +#define KSALLOCATOR_REQUIREMENTF_INPLACE_MODIFIER 0x00000001 +#define KSALLOCATOR_REQUIREMENTF_SYSTEM_MEMORY 0x00000002 +#define KSALLOCATOR_REQUIREMENTF_FRAME_INTEGRITY 0x00000004 +#define KSALLOCATOR_REQUIREMENTF_MUST_ALLOCATE 0x00000008 +#define KSALLOCATOR_REQUIREMENTF_PREFERENCES_ONLY 0x80000000 + +#define KSALLOCATOR_OPTIONF_COMPATIBLE 0x00000001 +#define KSALLOCATOR_OPTIONF_SYSTEM_MEMORY 0x00000002 +#define KSALLOCATOR_OPTIONF_VALID 0x00000003 + +#define KSALLOCATOR_FLAG_PARTIAL_READ_SUPPORT 0x00000010 +#define KSALLOCATOR_FLAG_DEVICE_SPECIFIC 0x00000020 +#define KSALLOCATOR_FLAG_CAN_ALLOCATE 0x00000040 +#define KSALLOCATOR_FLAG_INSIST_ON_FRAMESIZE_RATIO 0x00000080 +#define KSALLOCATOR_FLAG_NO_FRAME_INTEGRITY 0x00000100 +#define KSALLOCATOR_FLAG_MULTIPLE_OUTPUT 0x00000200 +#define KSALLOCATOR_FLAG_CYCLE 0x00000400 +#define KSALLOCATOR_FLAG_ALLOCATOR_EXISTS 0x00000800 +#define KSALLOCATOR_FLAG_INDEPENDENT_RANGES 0x00001000 +#define KSALLOCATOR_FLAG_ATTENTION_STEPPING 0x00002000 + +typedef struct +{ + __MINGW_EXTENSION union + { + ULONG OptionsFlags; + ULONG RequirementsFlags; + }; +#if defined(_NTDDK_) + POOL_TYPE PoolType; +#else + ULONG PoolType; +#endif /* _NTDDK_ */ + ULONG Frames; + ULONG FrameSize; + ULONG FileAlignment; + ULONG Reserved; +}KSALLOCATOR_FRAMING, * PKSALLOCATOR_FRAMING; + +#if defined(_NTDDK_) +typedef PVOID (*PFNKSDEFAULTALLOCATE)(PVOID Context); +typedef VOID (*PFNKSDEFAULTFREE)(PVOID Context, PVOID Buffer); +typedef NTSTATUS (*PFNKSINITIALIZEALLOCATOR)(PVOID InitialContext, + PKSALLOCATOR_FRAMING AllocatorFraming, + PVOID* Context); +typedef VOID (*PFNKSDELETEALLOCATOR)(PVOID Context); +#endif /* _NTDDK_ */ + +typedef struct +{ + ULONG MinFrameSize; + ULONG MaxFrameSize; + ULONG Stepping; +}KS_FRAMING_RANGE, * PKS_FRAMING_RANGE; + +typedef struct +{ + KS_FRAMING_RANGE Range; + ULONG InPlaceWeight; + ULONG NotInPlaceWeight; +}KS_FRAMING_RANGE_WEIGHTED, * PKS_FRAMING_RANGE_WEIGHTED; + +typedef struct +{ + ULONG RatioNumerator; + ULONG RatioDenominator; + ULONG RatioConstantMargin; +}KS_COMPRESSION, * PKS_COMPRESSION; + +typedef struct +{ + GUID MemoryType; + GUID BusType; + ULONG MemoryFlags; + ULONG BusFlags; + ULONG Flags; + ULONG Frames; + ULONG FileAlignment; + ULONG MemoryTypeWeight; + KS_FRAMING_RANGE PhysicalRange; + KS_FRAMING_RANGE_WEIGHTED FramingRange; +}KS_FRAMING_ITEM, * PKS_FRAMING_ITEM; + +typedef struct +{ + ULONG CountItems; + ULONG PinFlags; + KS_COMPRESSION OutputCompression; + ULONG PinWeight; + KS_FRAMING_ITEM FramingItem[1]; +}KSALLOCATOR_FRAMING_EX, * PKSALLOCATOR_FRAMING_EX; + +#define KSMEMORY_TYPE_WILDCARD GUID_NULL +#define STATIC_KSMEMORY_TYPE_WILDCARD STATIC_GUID_NULL + +#define KSMEMORY_TYPE_DONT_CARE GUID_NULL +#define STATIC_KSMEMORY_TYPE_DONT_CARE STATIC_GUID_NULL + +#define KS_TYPE_DONT_CARE GUID_NULL +#define STATIC_KS_TYPE_DONT_CARE STATIC_GUID_NULL + +#define STATIC_KSMEMORY_TYPE_SYSTEM \ + 0x091bb638L, 0x603f, 0x11d1, 0xb0, 0x67, 0x00, 0xa0, 0xc9, 0x06, 0x28, 0x02 +DEFINE_GUIDSTRUCT("091bb638-603f-11d1-b067-00a0c9062802", KSMEMORY_TYPE_SYSTEM); +#define KSMEMORY_TYPE_SYSTEM DEFINE_GUIDNAMED(KSMEMORY_TYPE_SYSTEM) + +#define STATIC_KSMEMORY_TYPE_USER \ + 0x8cb0fc28L, 0x7893, 0x11d1, 0xb0, 0x69, 0x00, 0xa0, 0xc9, 0x06, 0x28, 0x02 +DEFINE_GUIDSTRUCT("8cb0fc28-7893-11d1-b069-00a0c9062802", KSMEMORY_TYPE_USER); +#define KSMEMORY_TYPE_USER DEFINE_GUIDNAMED(KSMEMORY_TYPE_USER) + +#define STATIC_KSMEMORY_TYPE_KERNEL_PAGED \ + 0xd833f8f8L, 0x7894, 0x11d1, 0xb0, 0x69, 0x00, 0xa0, 0xc9, 0x06, 0x28, 0x02 +DEFINE_GUIDSTRUCT("d833f8f8-7894-11d1-b069-00a0c9062802", KSMEMORY_TYPE_KERNEL_PAGED); +#define KSMEMORY_TYPE_KERNEL_PAGED DEFINE_GUIDNAMED(KSMEMORY_TYPE_KERNEL_PAGED) + +#define STATIC_KSMEMORY_TYPE_KERNEL_NONPAGED \ + 0x4a6d5fc4L, 0x7895, 0x11d1, 0xb0, 0x69, 0x00, 0xa0, 0xc9, 0x06, 0x28, 0x02 +DEFINE_GUIDSTRUCT("4a6d5fc4-7895-11d1-b069-00a0c9062802", KSMEMORY_TYPE_KERNEL_NONPAGED); +#define KSMEMORY_TYPE_KERNEL_NONPAGED DEFINE_GUIDNAMED(KSMEMORY_TYPE_KERNEL_NONPAGED) + +#define STATIC_KSMEMORY_TYPE_DEVICE_UNKNOWN \ + 0x091bb639L, 0x603f, 0x11d1, 0xb0, 0x67, 0x00, 0xa0, 0xc9, 0x06, 0x28, 0x02 +DEFINE_GUIDSTRUCT("091bb639-603f-11d1-b067-00a0c9062802", KSMEMORY_TYPE_DEVICE_UNKNOWN); +#define KSMEMORY_TYPE_DEVICE_UNKNOWN DEFINE_GUIDNAMED(KSMEMORY_TYPE_DEVICE_UNKNOWN) + +#define DECLARE_SIMPLE_FRAMING_EX(FramingExName, MemoryType, Flags, Frames, Alignment, MinFrameSize, MaxFrameSize) \ + const KSALLOCATOR_FRAMING_EX FramingExName = \ + { \ + 1, \ + 0, \ + { \ + 1, \ + 1, \ + 0 \ + }, \ + 0, \ + { \ + { \ + MemoryType, \ + STATIC_KS_TYPE_DONT_CARE, \ + 0, \ + 0, \ + Flags, \ + Frames, \ + Alignment, \ + 0, \ + { \ + 0, \ + (ULONG)-1, \ + 1 \ + }, \ + { \ + { \ + MinFrameSize, \ + MaxFrameSize, \ + 1 \ + }, \ + 0, \ + 0 \ + } \ + } \ + } \ + } + +#define SetDefaultKsCompression(KsCompressionPointer) \ + { \ + KsCompressionPointer->RatioNumerator = 1; \ + KsCompressionPointer->RatioDenominator = 1; \ + KsCompressionPointer->RatioConstantMargin = 0; \ + } + +#define SetDontCareKsFramingRange(KsFramingRangePointer) \ + { \ + KsFramingRangePointer->MinFrameSize = 0; \ + KsFramingRangePointer->MaxFrameSize = (ULONG)-1; \ + KsFramingRangePointer->Stepping = 1; \ + } + +#define SetKsFramingRange(KsFramingRangePointer, P_MinFrameSize, P_MaxFrameSize) \ + { \ + KsFramingRangePointer->MinFrameSize = P_MinFrameSize; \ + KsFramingRangePointer->MaxFrameSize = P_MaxFrameSize; \ + KsFramingRangePointer->Stepping = 1; \ + } + +#define SetKsFramingRangeWeighted(KsFramingRangeWeightedPointer, P_MinFrameSize, P_MaxFrameSize) \ + { \ + KS_FRAMING_RANGE* KsFramingRange = \ + &KsFramingRangeWeightedPointer->Range; \ + SetKsFramingRange(KsFramingRange, P_MinFrameSize, P_MaxFrameSize); \ + KsFramingRangeWeightedPointer->InPlaceWeight = 0; \ + KsFramingRangeWeightedPointer->NotInPlaceWeight = 0; \ + } + +#define INITIALIZE_SIMPLE_FRAMING_EX(FramingExPointer, P_MemoryType, P_Flags, P_Frames, P_Alignment, P_MinFrameSize, P_MaxFrameSize) \ + { \ + KS_COMPRESSION* KsCompression = \ + &FramingExPointer->OutputCompression; \ + KS_FRAMING_RANGE* KsFramingRange = \ + &FramingExPointer->FramingItem[0].PhysicalRange; \ + KS_FRAMING_RANGE_WEIGHTED* KsFramingRangeWeighted = \ + &FramingExPointer->FramingItem[0].FramingRange; \ + FramingExPointer->CountItems = 1; \ + FramingExPointer->PinFlags = 0; \ + SetDefaultKsCompression(KsCompression); \ + FramingExPointer->PinWeight = 0; \ + FramingExPointer->FramingItem[0].MemoryType = P_MemoryType; \ + FramingExPointer->FramingItem[0].BusType = KS_TYPE_DONT_CARE; \ + FramingExPointer->FramingItem[0].MemoryFlags = 0; \ + FramingExPointer->FramingItem[0].BusFlags = 0; \ + FramingExPointer->FramingItem[0].Flags = P_Flags; \ + FramingExPointer->FramingItem[0].Frames = P_Frames; \ + FramingExPointer->FramingItem[0].FileAlignment = P_Alignment; \ + FramingExPointer->FramingItem[0].MemoryTypeWeight = 0; \ + SetDontCareKsFramingRange(KsFramingRange); \ + SetKsFramingRangeWeighted(KsFramingRangeWeighted, \ + P_MinFrameSize, P_MaxFrameSize); \ + } + +#define STATIC_KSEVENTSETID_StreamAllocator \ + 0x75d95571L, 0x073c, 0x11d0, 0xa1, 0x61, 0x00, 0x20, 0xaf, 0xd1, 0x56, 0xe4 +DEFINE_GUIDSTRUCT("75d95571-073c-11d0-a161-0020afd156e4", KSEVENTSETID_StreamAllocator); +#define KSEVENTSETID_StreamAllocator DEFINE_GUIDNAMED(KSEVENTSETID_StreamAllocator) + +typedef enum +{ + KSEVENT_STREAMALLOCATOR_INTERNAL_FREEFRAME, + KSEVENT_STREAMALLOCATOR_FREEFRAME +}KSEVENT_STREAMALLOCATOR; + +#define STATIC_KSMETHODSETID_StreamAllocator \ + 0xcf6e4341L, 0xec87, 0x11cf, 0xa1, 0x30, 0x00, 0x20, 0xaf, 0xd1, 0x56, 0xe4 +DEFINE_GUIDSTRUCT("cf6e4341-ec87-11cf-a130-0020afd156e4", KSMETHODSETID_StreamAllocator); +#define KSMETHODSETID_StreamAllocator DEFINE_GUIDNAMED(KSMETHODSETID_StreamAllocator) + +typedef enum +{ + KSMETHOD_STREAMALLOCATOR_ALLOC, + KSMETHOD_STREAMALLOCATOR_FREE +}KSMETHOD_STREAMALLOCATOR; + +#define DEFINE_KSMETHOD_ITEM_STREAMALLOCATOR_ALLOC(Handler) \ + DEFINE_KSMETHOD_ITEM( \ + KSMETHOD_STREAMALLOCATOR_ALLOC, \ + KSMETHOD_TYPE_WRITE, \ + (Handler), \ + sizeof(KSMETHOD), \ + sizeof(PVOID), \ + NULL) + +#define DEFINE_KSMETHOD_ITEM_STREAMALLOCATOR_FREE(Handler) \ + DEFINE_KSMETHOD_ITEM( \ + KSMETHOD_STREAMALLOCATOR_FREE, \ + KSMETHOD_TYPE_READ, \ + (Handler), \ + sizeof(KSMETHOD), \ + sizeof(PVOID), \ + NULL) + +#define DEFINE_KSMETHOD_ALLOCATORSET(AllocatorSet, MethodAlloc, MethodFree) \ + DEFINE_KSMETHOD_TABLE(AllocatorSet) { \ + DEFINE_KSMETHOD_ITEM_STREAMALLOCATOR_ALLOC(MethodAlloc), \ + DEFINE_KSMETHOD_ITEM_STREAMALLOCATOR_FREE(MethodFree) \ + } + +#define STATIC_KSPROPSETID_StreamAllocator \ + 0xcf6e4342L, 0xec87, 0x11cf, 0xa1, 0x30, 0x00, 0x20, 0xaf, 0xd1, 0x56, 0xe4 +DEFINE_GUIDSTRUCT("cf6e4342-ec87-11cf-a130-0020afd156e4", KSPROPSETID_StreamAllocator); +#define KSPROPSETID_StreamAllocator DEFINE_GUIDNAMED(KSPROPSETID_StreamAllocator) + +#if defined(_NTDDK_) +typedef enum +{ + KSPROPERTY_STREAMALLOCATOR_FUNCTIONTABLE, + KSPROPERTY_STREAMALLOCATOR_STATUS +}KSPROPERTY_STREAMALLOCATOR; + + # define DEFINE_KSPROPERTY_ITEM_STREAMALLOCATOR_FUNCTIONTABLE(Handler) \ + DEFINE_KSPROPERTY_ITEM( \ + KSPROPERTY_STREAMALLOCATOR_FUNCTIONTABLE, \ + (Handler), \ + sizeof(KSPROPERTY), \ + sizeof(KSSTREAMALLOCATOR_FUNCTIONTABLE), \ + NULL, NULL, 0, NULL, NULL, 0) + + # define DEFINE_KSPROPERTY_ITEM_STREAMALLOCATOR_STATUS(Handler) \ + DEFINE_KSPROPERTY_ITEM( \ + KSPROPERTY_STREAMALLOCATOR_STATUS, \ + (Handler), \ + sizeof(KSPROPERTY), \ + sizeof(KSSTREAMALLOCATOR_STATUS), \ + NULL, NULL, 0, NULL, NULL, 0) + + # define DEFINE_KSPROPERTY_ALLOCATORSET(AllocatorSet, PropFunctionTable, PropStatus) \ + DEFINE_KSPROPERTY_TABLE(AllocatorSet) { \ + DEFINE_KSPROPERTY_ITEM_STREAMALLOCATOR_STATUS(PropStatus), \ + DEFINE_KSPROPERTY_ITEM_STREAMALLOCATOR_FUNCTIONTABLE(PropFunctionTable) \ + } + +typedef NTSTATUS (*PFNALLOCATOR_ALLOCATEFRAME)(PFILE_OBJECT FileObject, + PVOID* Frame); +typedef VOID (*PFNALLOCATOR_FREEFRAME)(PFILE_OBJECT FileObject, PVOID Frame); + +typedef struct +{ + PFNALLOCATOR_ALLOCATEFRAME AllocateFrame; + PFNALLOCATOR_FREEFRAME FreeFrame; +}KSSTREAMALLOCATOR_FUNCTIONTABLE, * PKSSTREAMALLOCATOR_FUNCTIONTABLE; +#endif /* _NTDDK_ */ + +typedef struct +{ + KSALLOCATOR_FRAMING Framing; + ULONG AllocatedFrames; + ULONG Reserved; +}KSSTREAMALLOCATOR_STATUS, * PKSSTREAMALLOCATOR_STATUS; + +typedef struct +{ + KSALLOCATOR_FRAMING_EX Framing; + ULONG AllocatedFrames; + ULONG Reserved; +}KSSTREAMALLOCATOR_STATUS_EX, * PKSSTREAMALLOCATOR_STATUS_EX; + +#define KSSTREAM_HEADER_OPTIONSF_SPLICEPOINT 0x00000001 +#define KSSTREAM_HEADER_OPTIONSF_PREROLL 0x00000002 +#define KSSTREAM_HEADER_OPTIONSF_DATADISCONTINUITY 0x00000004 +#define KSSTREAM_HEADER_OPTIONSF_TYPECHANGED 0x00000008 +#define KSSTREAM_HEADER_OPTIONSF_TIMEVALID 0x00000010 +#define KSSTREAM_HEADER_OPTIONSF_TIMEDISCONTINUITY 0x00000040 +#define KSSTREAM_HEADER_OPTIONSF_FLUSHONPAUSE 0x00000080 +#define KSSTREAM_HEADER_OPTIONSF_DURATIONVALID 0x00000100 +#define KSSTREAM_HEADER_OPTIONSF_ENDOFSTREAM 0x00000200 +#define KSSTREAM_HEADER_OPTIONSF_LOOPEDDATA 0x80000000 + +typedef struct +{ + LONGLONG Time; + ULONG Numerator; + ULONG Denominator; +}KSTIME, * PKSTIME; + +typedef struct +{ + ULONG Size; + ULONG TypeSpecificFlags; + KSTIME PresentationTime; + LONGLONG Duration; + ULONG FrameExtent; + ULONG DataUsed; + PVOID Data; + ULONG OptionsFlags; +#ifdef _WIN64 + ULONG Reserved; +#endif +}KSSTREAM_HEADER, * PKSSTREAM_HEADER; + +#define STATIC_KSPROPSETID_StreamInterface \ + 0x1fdd8ee1L, 0x9cd3, 0x11d0, 0x82, 0xaa, 0x00, 0x00, 0xf8, 0x22, 0xfe, 0x8a +DEFINE_GUIDSTRUCT("1fdd8ee1-9cd3-11d0-82aa-0000f822fe8a", KSPROPSETID_StreamInterface); +#define KSPROPSETID_StreamInterface DEFINE_GUIDNAMED(KSPROPSETID_StreamInterface) + +typedef enum +{ + KSPROPERTY_STREAMINTERFACE_HEADERSIZE +}KSPROPERTY_STREAMINTERFACE; + +#define DEFINE_KSPROPERTY_ITEM_STREAMINTERFACE_HEADERSIZE(GetHandler) \ + DEFINE_KSPROPERTY_ITEM( \ + KSPROPERTY_STREAMINTERFACE_HEADERSIZE, \ + (GetHandler), \ + sizeof(KSPROPERTY), \ + sizeof(ULONG), \ + NULL, NULL, 0, NULL, NULL, 0) + +#define DEFINE_KSPROPERTY_STREAMINTERFACESET(StreamInterfaceSet, HeaderSizeHandler) \ + DEFINE_KSPROPERTY_TABLE(StreamInterfaceSet) { \ + DEFINE_KSPROPERTY_ITEM_STREAMINTERFACE_HEADERSIZE(HeaderSizeHandler) \ + } + +#define STATIC_KSPROPSETID_Stream \ + 0x65aaba60L, 0x98ae, 0x11cf, 0xa1, 0x0d, 0x00, 0x20, 0xaf, 0xd1, 0x56, 0xe4 +DEFINE_GUIDSTRUCT("65aaba60-98ae-11cf-a10d-0020afd156e4", KSPROPSETID_Stream); +#define KSPROPSETID_Stream DEFINE_GUIDNAMED(KSPROPSETID_Stream) + +typedef enum +{ + KSPROPERTY_STREAM_ALLOCATOR, + KSPROPERTY_STREAM_QUALITY, + KSPROPERTY_STREAM_DEGRADATION, + KSPROPERTY_STREAM_MASTERCLOCK, + KSPROPERTY_STREAM_TIMEFORMAT, + KSPROPERTY_STREAM_PRESENTATIONTIME, + KSPROPERTY_STREAM_PRESENTATIONEXTENT, + KSPROPERTY_STREAM_FRAMETIME, + KSPROPERTY_STREAM_RATECAPABILITY, + KSPROPERTY_STREAM_RATE, + KSPROPERTY_STREAM_PIPE_ID +}KSPROPERTY_STREAM; + +#define DEFINE_KSPROPERTY_ITEM_STREAM_ALLOCATOR(GetHandler, SetHandler) \ + DEFINE_KSPROPERTY_ITEM( \ + KSPROPERTY_STREAM_ALLOCATOR, \ + (GetHandler), \ + sizeof(KSPROPERTY), \ + sizeof(HANDLE), \ + (SetHandler), \ + NULL, 0, NULL, NULL, 0) + +#define DEFINE_KSPROPERTY_ITEM_STREAM_QUALITY(Handler) \ + DEFINE_KSPROPERTY_ITEM( \ + KSPROPERTY_STREAM_QUALITY, \ + (Handler), \ + sizeof(KSPROPERTY), \ + sizeof(KSQUALITY_MANAGER), \ + NULL, NULL, 0, NULL, NULL, 0) + +#define DEFINE_KSPROPERTY_ITEM_STREAM_DEGRADATION(GetHandler, SetHandler) \ + DEFINE_KSPROPERTY_ITEM( \ + KSPROPERTY_STREAM_DEGRADATION, \ + (GetHandler), \ + sizeof(KSPROPERTY), \ + 0, \ + (SetHandler), \ + NULL, 0, NULL, NULL, 0) + +#define DEFINE_KSPROPERTY_ITEM_STREAM_MASTERCLOCK(GetHandler, SetHandler) \ + DEFINE_KSPROPERTY_ITEM( \ + KSPROPERTY_STREAM_MASTERCLOCK, \ + (GetHandler), \ + sizeof(KSPROPERTY), \ + sizeof(HANDLE), \ + (SetHandler), \ + NULL, 0, NULL, NULL, 0) + +#define DEFINE_KSPROPERTY_ITEM_STREAM_TIMEFORMAT(Handler) \ + DEFINE_KSPROPERTY_ITEM( \ + KSPROPERTY_STREAM_TIMEFORMAT, \ + (Handler), \ + sizeof(KSPROPERTY), \ + sizeof(GUID), \ + NULL, NULL, 0, NULL, NULL, 0) + +#define DEFINE_KSPROPERTY_ITEM_STREAM_PRESENTATIONTIME(GetHandler, SetHandler) \ + DEFINE_KSPROPERTY_ITEM( \ + KSPROPERTY_STREAM_PRESENTATIONTIME, \ + (GetHandler), \ + sizeof(KSPROPERTY), \ + sizeof(KSTIME), \ + (SetHandler), \ + NULL, 0, NULL, NULL, 0) + +#define DEFINE_KSPROPERTY_ITEM_STREAM_PRESENTATIONEXTENT(Handler) \ + DEFINE_KSPROPERTY_ITEM( \ + KSPROPERTY_STREAM_PRESENTATIONEXTENT, \ + (Handler), \ + sizeof(KSPROPERTY), \ + sizeof(LONGLONG), \ + NULL, NULL, 0, NULL, NULL, 0) + +#define DEFINE_KSPROPERTY_ITEM_STREAM_FRAMETIME(Handler) \ + DEFINE_KSPROPERTY_ITEM( \ + KSPROPERTY_STREAM_FRAMETIME, \ + (Handler), \ + sizeof(KSPROPERTY), \ + sizeof(KSFRAMETIME), \ + NULL, NULL, 0, NULL, NULL, 0) + +#define DEFINE_KSPROPERTY_ITEM_STREAM_RATECAPABILITY(Handler) \ + DEFINE_KSPROPERTY_ITEM( \ + KSPROPERTY_STREAM_RATECAPABILITY, \ + (Handler), \ + sizeof(KSRATE_CAPABILITY), \ + sizeof(KSRATE), \ + NULL, NULL, 0, NULL, NULL, 0) + +#define DEFINE_KSPROPERTY_ITEM_STREAM_RATE(GetHandler, SetHandler) \ + DEFINE_KSPROPERTY_ITEM( \ + KSPROPERTY_STREAM_RATE, \ + (GetHandler), \ + sizeof(KSPROPERTY), \ + sizeof(KSRATE), \ + (SetHandler), \ + NULL, 0, NULL, NULL, 0) + +#define DEFINE_KSPROPERTY_ITEM_STREAM_PIPE_ID(GetHandler, SetHandler) \ + DEFINE_KSPROPERTY_ITEM( \ + KSPROPERTY_STREAM_PIPE_ID, \ + (GetHandler), \ + sizeof(KSPROPERTY), \ + sizeof(HANDLE), \ + (SetHandler), \ + NULL, 0, NULL, NULL, 0) + +typedef struct +{ + HANDLE QualityManager; + PVOID Context; +}KSQUALITY_MANAGER, * PKSQUALITY_MANAGER; + +typedef struct +{ + LONGLONG Duration; + ULONG FrameFlags; + ULONG Reserved; +}KSFRAMETIME, * PKSFRAMETIME; + +#define KSFRAMETIME_VARIABLESIZE 0x00000001 + +typedef struct +{ + LONGLONG PresentationStart; + LONGLONG Duration; + KSPIN_INTERFACE Interface; + LONG Rate; + ULONG Flags; +}KSRATE, * PKSRATE; + +#define KSRATE_NOPRESENTATIONSTART 0x00000001 +#define KSRATE_NOPRESENTATIONDURATION 0x00000002 + +typedef struct +{ + KSPROPERTY Property; + KSRATE Rate; +}KSRATE_CAPABILITY, * PKSRATE_CAPABILITY; + +#define STATIC_KSPROPSETID_Clock \ + 0xDF12A4C0L, 0xAC17, 0x11CF, 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00 +DEFINE_GUIDSTRUCT("DF12A4C0-AC17-11CF-A5D6-28DB04C10000", KSPROPSETID_Clock); +#define KSPROPSETID_Clock DEFINE_GUIDNAMED(KSPROPSETID_Clock) + +#define NANOSECONDS 10000000 +#define KSCONVERT_PERFORMANCE_TIME(Frequency, PerformanceTime) \ + ((((ULONGLONG)(ULONG)(PerformanceTime).HighPart * NANOSECONDS / (Frequency)) << 32) + \ + ((((((ULONGLONG)(ULONG)(PerformanceTime).HighPart * NANOSECONDS) % (Frequency)) << 32) + \ + ((ULONGLONG)(PerformanceTime).LowPart * NANOSECONDS)) / (Frequency))) + +typedef struct +{ + ULONG CreateFlags; +}KSCLOCK_CREATE, * PKSCLOCK_CREATE; + +typedef struct +{ + LONGLONG Time; + LONGLONG SystemTime; +}KSCORRELATED_TIME, * PKSCORRELATED_TIME; + +typedef struct +{ + LONGLONG Granularity; + LONGLONG Error; +}KSRESOLUTION, * PKSRESOLUTION; + +typedef enum +{ + KSPROPERTY_CLOCK_TIME, + KSPROPERTY_CLOCK_PHYSICALTIME, + KSPROPERTY_CLOCK_CORRELATEDTIME, + KSPROPERTY_CLOCK_CORRELATEDPHYSICALTIME, + KSPROPERTY_CLOCK_RESOLUTION, + KSPROPERTY_CLOCK_STATE, +#if defined(_NTDDK_) + KSPROPERTY_CLOCK_FUNCTIONTABLE +#endif /* _NTDDK_ */ +}KSPROPERTY_CLOCK; + +#if defined(_NTDDK_) +typedef LONGLONG (FASTCALL * PFNKSCLOCK_GETTIME)(PFILE_OBJECT FileObject); +typedef LONGLONG (FASTCALL * PFNKSCLOCK_CORRELATEDTIME)(PFILE_OBJECT FileObject, + PLONGLONG SystemTime); + +typedef struct +{ + PFNKSCLOCK_GETTIME GetTime; + PFNKSCLOCK_GETTIME GetPhysicalTime; + PFNKSCLOCK_CORRELATEDTIME GetCorrelatedTime; + PFNKSCLOCK_CORRELATEDTIME GetCorrelatedPhysicalTime; +}KSCLOCK_FUNCTIONTABLE, * PKSCLOCK_FUNCTIONTABLE; + +typedef BOOLEAN (*PFNKSSETTIMER)(PVOID Context, PKTIMER Timer, + LARGE_INTEGER DueTime, PKDPC Dpc); +typedef BOOLEAN (*PFNKSCANCELTIMER)(PVOID Context, PKTIMER Timer); +typedef LONGLONG (FASTCALL * PFNKSCORRELATEDTIME)(PVOID Context, + PLONGLONG SystemTime); + +typedef PVOID PKSDEFAULTCLOCK; + + # define DEFINE_KSPROPERTY_ITEM_CLOCK_TIME(Handler) \ + DEFINE_KSPROPERTY_ITEM( \ + KSPROPERTY_CLOCK_TIME, \ + (Handler), \ + sizeof(KSPROPERTY), sizeof(LONGLONG), \ + NULL, NULL, 0, NULL, NULL, 0) + + # define DEFINE_KSPROPERTY_ITEM_CLOCK_PHYSICALTIME(Handler) \ + DEFINE_KSPROPERTY_ITEM( \ + KSPROPERTY_CLOCK_PHYSICALTIME, \ + (Handler), \ + sizeof(KSPROPERTY), sizeof(LONGLONG), \ + NULL, NULL, 0, NULL, NULL, 0) + + # define DEFINE_KSPROPERTY_ITEM_CLOCK_CORRELATEDTIME(Handler) \ + DEFINE_KSPROPERTY_ITEM( \ + KSPROPERTY_CLOCK_CORRELATEDTIME, \ + (Handler), \ + sizeof(KSPROPERTY), \ + sizeof(KSCORRELATED_TIME), \ + NULL, NULL, 0, NULL, NULL, 0) + + # define DEFINE_KSPROPERTY_ITEM_CLOCK_CORRELATEDPHYSICALTIME(Handler) \ + DEFINE_KSPROPERTY_ITEM( \ + KSPROPERTY_CLOCK_CORRELATEDPHYSICALTIME, \ + (Handler), \ + sizeof(KSPROPERTY), \ + sizeof(KSCORRELATED_TIME), \ + NULL, NULL, 0, NULL, NULL, 0) + + # define DEFINE_KSPROPERTY_ITEM_CLOCK_RESOLUTION(Handler) \ + DEFINE_KSPROPERTY_ITEM( \ + KSPROPERTY_CLOCK_RESOLUTION, \ + (Handler), \ + sizeof(KSPROPERTY), sizeof(KSRESOLUTION), \ + NULL, NULL, 0, NULL, NULL, 0) + + # define DEFINE_KSPROPERTY_ITEM_CLOCK_STATE(Handler) \ + DEFINE_KSPROPERTY_ITEM( \ + KSPROPERTY_CLOCK_STATE, \ + (Handler), \ + sizeof(KSPROPERTY), sizeof(KSSTATE), \ + NULL, NULL, 0, NULL, NULL, 0) + + # define DEFINE_KSPROPERTY_ITEM_CLOCK_FUNCTIONTABLE(Handler) \ + DEFINE_KSPROPERTY_ITEM( \ + KSPROPERTY_CLOCK_FUNCTIONTABLE, \ + (Handler), \ + sizeof(KSPROPERTY), \ + sizeof(KSCLOCK_FUNCTIONTABLE), \ + NULL, NULL, 0, NULL, NULL, 0) + + # define DEFINE_KSPROPERTY_CLOCKSET(ClockSet, PropTime, PropPhysicalTime, PropCorrelatedTime, PropCorrelatedPhysicalTime, PropResolution, PropState, PropFunctionTable) \ + DEFINE_KSPROPERTY_TABLE(ClockSet) { \ + DEFINE_KSPROPERTY_ITEM_CLOCK_TIME(PropTime), \ + DEFINE_KSPROPERTY_ITEM_CLOCK_PHYSICALTIME(PropPhysicalTime), \ + DEFINE_KSPROPERTY_ITEM_CLOCK_CORRELATEDTIME(PropCorrelatedTime), \ + DEFINE_KSPROPERTY_ITEM_CLOCK_CORRELATEDPHYSICALTIME(PropCorrelatedPhysicalTime), \ + DEFINE_KSPROPERTY_ITEM_CLOCK_RESOLUTION(PropResolution), \ + DEFINE_KSPROPERTY_ITEM_CLOCK_STATE(PropState), \ + DEFINE_KSPROPERTY_ITEM_CLOCK_FUNCTIONTABLE(PropFunctionTable), \ + } +#endif /* _NTDDK_ */ + +#define STATIC_KSEVENTSETID_Clock \ + 0x364D8E20L, 0x62C7, 0x11CF, 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00 +DEFINE_GUIDSTRUCT("364D8E20-62C7-11CF-A5D6-28DB04C10000", KSEVENTSETID_Clock); +#define KSEVENTSETID_Clock DEFINE_GUIDNAMED(KSEVENTSETID_Clock) + +typedef enum +{ + KSEVENT_CLOCK_INTERVAL_MARK, + KSEVENT_CLOCK_POSITION_MARK +}KSEVENT_CLOCK_POSITION; + +#define STATIC_KSEVENTSETID_Connection \ + 0x7f4bcbe0L, 0x9ea5, 0x11cf, 0xa5, 0xd6, 0x28, 0xdb, 0x04, 0xc1, 0x00, 0x00 +DEFINE_GUIDSTRUCT("7f4bcbe0-9ea5-11cf-a5d6-28db04c10000", KSEVENTSETID_Connection); +#define KSEVENTSETID_Connection DEFINE_GUIDNAMED(KSEVENTSETID_Connection) + +typedef enum +{ + KSEVENT_CONNECTION_POSITIONUPDATE, + KSEVENT_CONNECTION_DATADISCONTINUITY, + KSEVENT_CONNECTION_TIMEDISCONTINUITY, + KSEVENT_CONNECTION_PRIORITY, + KSEVENT_CONNECTION_ENDOFSTREAM +}KSEVENT_CONNECTION; + +typedef struct +{ + PVOID Context; + ULONG Proportion; + LONGLONG DeltaTime; +}KSQUALITY, * PKSQUALITY; + +typedef struct +{ + PVOID Context; + ULONG Status; +}KSERROR, * PKSERROR; + +typedef KSIDENTIFIER KSDEGRADE, * PKSDEGRADE; + +#define STATIC_KSDEGRADESETID_Standard \ + 0x9F564180L, 0x704C, 0x11D0, 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00 +DEFINE_GUIDSTRUCT("9F564180-704C-11D0-A5D6-28DB04C10000", KSDEGRADESETID_Standard); +#define KSDEGRADESETID_Standard DEFINE_GUIDNAMED(KSDEGRADESETID_Standard) + +typedef enum +{ + KSDEGRADE_STANDARD_SAMPLE, + KSDEGRADE_STANDARD_QUALITY, + KSDEGRADE_STANDARD_COMPUTATION, + KSDEGRADE_STANDARD_SKIP +}KSDEGRADE_STANDARD; + +#if defined(_NTDDK_) + + # define KSPROBE_STREAMREAD 0x00000000 + # define KSPROBE_STREAMWRITE 0x00000001 + # define KSPROBE_ALLOCATEMDL 0x00000010 + # define KSPROBE_PROBEANDLOCK 0x00000020 + # define KSPROBE_SYSTEMADDRESS 0x00000040 + # define KSPROBE_MODIFY 0x00000200 + # define KSPROBE_STREAMWRITEMODIFY (KSPROBE_MODIFY | KSPROBE_STREAMWRITE) + # define KSPROBE_ALLOWFORMATCHANGE 0x00000080 + # define KSSTREAM_READ KSPROBE_STREAMREAD + # define KSSTREAM_WRITE KSPROBE_STREAMWRITE + # define KSSTREAM_PAGED_DATA 0x00000000 + # define KSSTREAM_NONPAGED_DATA 0x00000100 + # define KSSTREAM_SYNCHRONOUS 0x00001000 + # define KSSTREAM_FAILUREEXCEPTION 0x00002000 + +typedef NTSTATUS (*PFNKSCONTEXT_DISPATCH)(PVOID Context, PIRP Irp); +typedef NTSTATUS (*PFNKSHANDLER)(PIRP Irp, PKSIDENTIFIER Request, PVOID Data); +typedef BOOLEAN (*PFNKSFASTHANDLER)(PFILE_OBJECT FileObject, + PKSIDENTIFIER Request, + ULONG RequestLength, PVOID Data, + ULONG DataLength, + PIO_STATUS_BLOCK IoStatus); +typedef NTSTATUS (*PFNKSALLOCATOR)(PIRP Irp, ULONG BufferSize, + BOOLEAN InputOperation); + +typedef struct +{ + KSPROPERTY_MEMBERSHEADER MembersHeader; + const VOID* Members; +}KSPROPERTY_MEMBERSLIST, * PKSPROPERTY_MEMBERSLIST; + +typedef struct +{ + KSIDENTIFIER PropTypeSet; + ULONG MembersListCount; + const KSPROPERTY_MEMBERSLIST* MembersList; +}KSPROPERTY_VALUES, * PKSPROPERTY_VALUES; + + # define DEFINE_KSPROPERTY_TABLE(tablename) \ + const KSPROPERTY_ITEM tablename[] = + + # define DEFINE_KSPROPERTY_ITEM(PropertyId, GetHandler, MinProperty, MinData, SetHandler, Values, RelationsCount, Relations, SupportHandler, SerializedSize) \ + { \ + PropertyId, (PFNKSHANDLER)GetHandler, \ + MinProperty, MinData, \ + (PFNKSHANDLER)SetHandler, \ + (PKSPROPERTY_VALUES)Values, RelationsCount, \ + (PKSPROPERTY)Relations, \ + (PFNKSHANDLER)SupportHandler, \ + (ULONG)SerializedSize \ + } + +typedef struct +{ + ULONG PropertyId; + __MINGW_EXTENSION union + { + PFNKSHANDLER GetPropertyHandler; + BOOLEAN GetSupported; + }; + ULONG MinProperty; + ULONG MinData; + __MINGW_EXTENSION union + { + PFNKSHANDLER SetPropertyHandler; + BOOLEAN SetSupported; + }; + const KSPROPERTY_VALUES* Values; + ULONG RelationsCount; + const KSPROPERTY* Relations; + PFNKSHANDLER SupportHandler; + ULONG SerializedSize; +}KSPROPERTY_ITEM, * PKSPROPERTY_ITEM; + + # define DEFINE_KSFASTPROPERTY_ITEM(PropertyId, GetHandler, SetHandler) \ + { \ + PropertyId, (PFNKSFASTHANDLER)GetHandler, \ + (PFNKSFASTHANDLER)SetHandler, 0 \ + } + +typedef struct +{ + ULONG PropertyId; + __MINGW_EXTENSION union + { + PFNKSFASTHANDLER GetPropertyHandler; + BOOLEAN GetSupported; + }; + __MINGW_EXTENSION union + { + PFNKSFASTHANDLER SetPropertyHandler; + BOOLEAN SetSupported; + }; + ULONG Reserved; +}KSFASTPROPERTY_ITEM, * PKSFASTPROPERTY_ITEM; + + # define DEFINE_KSPROPERTY_SET(Set, PropertiesCount, PropertyItem, FastIoCount, FastIoTable) \ + { \ + Set, \ + PropertiesCount, PropertyItem, \ + FastIoCount, FastIoTable \ + } + + # define DEFINE_KSPROPERTY_SET_TABLE(tablename) \ + const KSPROPERTY_SET tablename[] = + +typedef struct +{ + const GUID* Set; + ULONG PropertiesCount; + const KSPROPERTY_ITEM* PropertyItem; + ULONG FastIoCount; + const KSFASTPROPERTY_ITEM* FastIoTable; +}KSPROPERTY_SET, * PKSPROPERTY_SET; + + # define DEFINE_KSMETHOD_TABLE(tablename) \ + const KSMETHOD_ITEM tablename[] = + + # define DEFINE_KSMETHOD_ITEM(MethodId, Flags, MethodHandler, MinMethod, MinData, SupportHandler) \ + { \ + MethodId, (PFNKSHANDLER)MethodHandler, \ + MinMethod, MinData, \ + SupportHandler, Flags \ + } + +typedef struct +{ + ULONG MethodId; + __MINGW_EXTENSION union + { + PFNKSHANDLER MethodHandler; + BOOLEAN MethodSupported; + }; + ULONG MinMethod; + ULONG MinData; + PFNKSHANDLER SupportHandler; + ULONG Flags; +}KSMETHOD_ITEM, * PKSMETHOD_ITEM; + + # define DEFINE_KSFASTMETHOD_ITEM(MethodId, MethodHandler) \ + { \ + MethodId, (PFNKSFASTHANDLER)MethodHandler \ + } + +typedef struct +{ + ULONG MethodId; + __MINGW_EXTENSION union + { + PFNKSFASTHANDLER MethodHandler; + BOOLEAN MethodSupported; + }; +}KSFASTMETHOD_ITEM, * PKSFASTMETHOD_ITEM; + + # define DEFINE_KSMETHOD_SET(Set, MethodsCount, MethodItem, FastIoCount, FastIoTable) \ + { \ + Set, \ + MethodsCount, MethodItem, \ + FastIoCount, FastIoTable \ + } + + # define DEFINE_KSMETHOD_SET_TABLE(tablename) \ + const KSMETHOD_SET tablename[] = + +typedef struct +{ + const GUID* Set; + ULONG MethodsCount; + const KSMETHOD_ITEM* MethodItem; + ULONG FastIoCount; + const KSFASTMETHOD_ITEM* FastIoTable; +}KSMETHOD_SET, * PKSMETHOD_SET; + +typedef struct _KSEVENT_ENTRY KSEVENT_ENTRY, * PKSEVENT_ENTRY; +typedef NTSTATUS (*PFNKSADDEVENT)(PIRP Irp, PKSEVENTDATA EventData, + struct _KSEVENT_ENTRY* EventEntry); +typedef VOID (*PFNKSREMOVEEVENT)(PFILE_OBJECT FileObject, + struct _KSEVENT_ENTRY* EventEntry); + + # define DEFINE_KSEVENT_TABLE(tablename) \ + const KSEVENT_ITEM tablename[] = + + # define DEFINE_KSEVENT_ITEM(EventId, DataInput, ExtraEntryData, AddHandler, RemoveHandler, SupportHandler) \ + { \ + EventId, DataInput, ExtraEntryData, \ + AddHandler, RemoveHandler, SupportHandler \ + } + +typedef struct +{ + ULONG EventId; + ULONG DataInput; + ULONG ExtraEntryData; + PFNKSADDEVENT AddHandler; + PFNKSREMOVEEVENT RemoveHandler; + PFNKSHANDLER SupportHandler; +}KSEVENT_ITEM, * PKSEVENT_ITEM; + + # define DEFINE_KSEVENT_SET(Set, EventsCount, EventItem) \ + { \ + Set, EventsCount, EventItem \ + } + + # define DEFINE_KSEVENT_SET_TABLE(tablename) \ + const KSEVENT_SET tablename[] = + +typedef struct +{ + const GUID* Set; + ULONG EventsCount; + const KSEVENT_ITEM* EventItem; +}KSEVENT_SET, * PKSEVENT_SET; + +typedef struct +{ + KDPC Dpc; + ULONG ReferenceCount; + KSPIN_LOCK AccessLock; +}KSDPC_ITEM, * PKSDPC_ITEM; + +typedef struct +{ + KSDPC_ITEM DpcItem; + LIST_ENTRY BufferList; +}KSBUFFER_ITEM, * PKSBUFFER_ITEM; + + # define KSEVENT_ENTRY_DELETED 1 + # define KSEVENT_ENTRY_ONESHOT 2 + # define KSEVENT_ENTRY_BUFFERED 4 + +struct _KSEVENT_ENTRY +{ + LIST_ENTRY ListEntry; + PVOID Object; + __MINGW_EXTENSION union + { + PKSDPC_ITEM DpcItem; + PKSBUFFER_ITEM BufferItem; + }; + PKSEVENTDATA EventData; + ULONG NotificationType; + const KSEVENT_SET* EventSet; + const KSEVENT_ITEM* EventItem; + PFILE_OBJECT FileObject; + ULONG SemaphoreAdjustment; + ULONG Reserved; + ULONG Flags; +}; + +typedef enum +{ + KSEVENTS_NONE, + KSEVENTS_SPINLOCK, + KSEVENTS_MUTEX, + KSEVENTS_FMUTEX, + KSEVENTS_FMUTEXUNSAFE, + KSEVENTS_INTERRUPT, + KSEVENTS_ERESOURCE +}KSEVENTS_LOCKTYPE; + + # define KSDISPATCH_FASTIO 0x80000000 + +typedef struct +{ + PDRIVER_DISPATCH Create; + PVOID Context; + UNICODE_STRING ObjectClass; + PSECURITY_DESCRIPTOR SecurityDescriptor; + ULONG Flags; +}KSOBJECT_CREATE_ITEM, * PKSOBJECT_CREATE_ITEM; + +typedef VOID (*PFNKSITEMFREECALLBACK)(PKSOBJECT_CREATE_ITEM CreateItem); + + # define KSCREATE_ITEM_SECURITYCHANGED 0x00000001 + # define KSCREATE_ITEM_WILDCARD 0x00000002 + # define KSCREATE_ITEM_NOPARAMETERS 0x00000004 + # define KSCREATE_ITEM_FREEONSTOP 0x00000008 + + # define DEFINE_KSCREATE_DISPATCH_TABLE(tablename) \ + KSOBJECT_CREATE_ITEM tablename[] = + + # define DEFINE_KSCREATE_ITEM(DispatchCreate, TypeName, Context) \ + { \ + (DispatchCreate), (PVOID)(Context), \ + { \ + sizeof(TypeName) - sizeof(UNICODE_NULL), \ + sizeof(TypeName), \ + (PWCHAR)(TypeName) \ + }, \ + NULL, 0 \ + } + + # define DEFINE_KSCREATE_ITEMEX(DispatchCreate, TypeName, Context, Flags) \ + { \ + (DispatchCreate), \ + (PVOID)(Context), \ + { \ + sizeof(TypeName) - sizeof(UNICODE_NULL), \ + sizeof(TypeName), \ + (PWCHAR)(TypeName) \ + }, \ + NULL, (Flags) \ + } + + # define DEFINE_KSCREATE_ITEMNULL(DispatchCreate, Context) \ + { \ + DispatchCreate, Context, \ + { \ + 0, 0, NULL, \ + }, \ + NULL, 0 \ + } + +typedef struct +{ + ULONG CreateItemsCount; + PKSOBJECT_CREATE_ITEM CreateItemsList; +}KSOBJECT_CREATE, * PKSOBJECT_CREATE; + +typedef struct +{ + PDRIVER_DISPATCH DeviceIoControl; + PDRIVER_DISPATCH Read; + PDRIVER_DISPATCH Write; + PDRIVER_DISPATCH Flush; + PDRIVER_DISPATCH Close; + PDRIVER_DISPATCH QuerySecurity; + PDRIVER_DISPATCH SetSecurity; + PFAST_IO_DEVICE_CONTROL FastDeviceIoControl; + PFAST_IO_READ FastRead; + PFAST_IO_WRITE FastWrite; +}KSDISPATCH_TABLE, * PKSDISPATCH_TABLE; + + # define DEFINE_KSDISPATCH_TABLE(tablename, DeviceIoControl, Read, Write, Flush, Close, QuerySecurity, SetSecurity, FastDeviceIoControl, FastRead, FastWrite) \ + const KSDISPATCH_TABLE tablename = \ + { \ + DeviceIoControl, \ + Read, \ + Write, \ + Flush, \ + Close, \ + QuerySecurity, \ + SetSecurity, \ + FastDeviceIoControl, \ + FastRead, \ + FastWrite, \ + } + + # define KSCREATE_ITEM_IRP_STORAGE(Irp) \ + (*(PKSOBJECT_CREATE_ITEM*)&(Irp)->Tail.Overlay.DriverContext[0]) + # define KSEVENT_SET_IRP_STORAGE(Irp) \ + (*(const KSEVENT_SET**)&(Irp)->Tail.Overlay.DriverContext[0]) + # define KSEVENT_ITEM_IRP_STORAGE(Irp) \ + (*(const KSEVENT_ITEM**)&(Irp)->Tail.Overlay.DriverContext[3]) + # define KSEVENT_ENTRY_IRP_STORAGE(Irp) \ + (*(PKSEVENT_ENTRY*)&(Irp)->Tail.Overlay.DriverContext[0]) + # define KSMETHOD_SET_IRP_STORAGE(Irp) \ + (*(const KSMETHOD_SET**)&(Irp)->Tail.Overlay.DriverContext[0]) + # define KSMETHOD_ITEM_IRP_STORAGE(Irp) \ + (*(const KSMETHOD_ITEM**)&(Irp)->Tail.Overlay.DriverContext[3]) + # define KSMETHOD_TYPE_IRP_STORAGE(Irp) \ + (*(ULONG_PTR*)(&(Irp)->Tail.Overlay.DriverContext[2])) + # define KSQUEUE_SPINLOCK_IRP_STORAGE(Irp) \ + (*(PKSPIN_LOCK*)&(Irp)->Tail.Overlay.DriverContext[1]) + # define KSPROPERTY_SET_IRP_STORAGE(Irp) \ + (*(const KSPROPERTY_SET**)&(Irp)->Tail.Overlay.DriverContext[0]) + # define KSPROPERTY_ITEM_IRP_STORAGE(Irp) \ + (*(const KSPROPERTY_ITEM**)&(Irp)->Tail.Overlay.DriverContext[3]) + # define KSPROPERTY_ATTRIBUTES_IRP_STORAGE(Irp) \ + (*(PKSATTRIBUTE_LIST*)&(Irp)->Tail.Overlay.DriverContext[2]) + +typedef PVOID KSDEVICE_HEADER, KSOBJECT_HEADER; + +typedef enum +{ + KsInvokeOnSuccess = 1, + KsInvokeOnError = 2, + KsInvokeOnCancel = 4 +}KSCOMPLETION_INVOCATION; + +typedef enum +{ + KsListEntryTail, + KsListEntryHead +}KSLIST_ENTRY_LOCATION; + +typedef enum +{ + KsAcquireOnly, + KsAcquireAndRemove, + KsAcquireOnlySingleItem, + KsAcquireAndRemoveOnlySingleItem +}KSIRP_REMOVAL_OPERATION; + +typedef enum +{ + KsStackCopyToNewLocation, + KsStackReuseCurrentLocation, + KsStackUseNewLocation +}KSSTACK_USE; + +typedef enum +{ + KSTARGET_STATE_DISABLED, + KSTARGET_STATE_ENABLED +}KSTARGET_STATE; + +typedef NTSTATUS (*PFNKSIRPLISTCALLBACK)(PIRP Irp, PVOID Context); +typedef VOID (*PFNREFERENCEDEVICEOBJECT)(PVOID Context); +typedef VOID (*PFNDEREFERENCEDEVICEOBJECT)(PVOID Context); +typedef NTSTATUS (*PFNQUERYREFERENCESTRING)(PVOID Context, PWCHAR* String); + + # define BUS_INTERFACE_REFERENCE_VERSION 0x100 + +typedef struct +{ + INTERFACE Interface; + + PFNREFERENCEDEVICEOBJECT ReferenceDeviceObject; + PFNDEREFERENCEDEVICEOBJECT DereferenceDeviceObject; + PFNQUERYREFERENCESTRING QueryReferenceString; +}BUS_INTERFACE_REFERENCE, * PBUS_INTERFACE_REFERENCE; + + # define STATIC_REFERENCE_BUS_INTERFACE STATIC_KSMEDIUMSETID_Standard + # define REFERENCE_BUS_INTERFACE KSMEDIUMSETID_Standard + +#endif /* _NTDDK_ */ + +#ifndef PACK_PRAGMAS_NOT_SUPPORTED + # include +#endif + +typedef struct +{ + GUID PropertySet; + ULONG Count; +}KSPROPERTY_SERIALHDR, * PKSPROPERTY_SERIALHDR; + +#ifndef PACK_PRAGMAS_NOT_SUPPORTED + # include +#endif + +typedef struct +{ + KSIDENTIFIER PropTypeSet; + ULONG Id; + ULONG PropertyLength; +}KSPROPERTY_SERIAL, * PKSPROPERTY_SERIAL; + +#if defined(_NTDDK_) + + # define IOCTL_KS_HANDSHAKE \ + CTL_CODE(FILE_DEVICE_KS, 0x007, METHOD_NEITHER, FILE_ANY_ACCESS) + +typedef struct +{ + GUID ProtocolId; + PVOID Argument1; + PVOID Argument2; +}KSHANDSHAKE, * PKSHANDSHAKE; + +typedef struct _KSGATE KSGATE, * PKSGATE; + +struct _KSGATE +{ + LONG Count; + PKSGATE NextGate; +}; + +typedef PVOID KSOBJECT_BAG; + +typedef BOOLEAN (*PFNKSGENERATEEVENTCALLBACK)(PVOID Context, + PKSEVENT_ENTRY EventEntry); + +typedef NTSTATUS (*PFNKSDEVICECREATE)(PKSDEVICE Device); + +typedef NTSTATUS (*PFNKSDEVICEPNPSTART)(PKSDEVICE Device, PIRP Irp, + PCM_RESOURCE_LIST TranslatedResourceList, + PCM_RESOURCE_LIST UntranslatedResourceList); + +typedef NTSTATUS (*PFNKSDEVICE)(PKSDEVICE Device); + +typedef NTSTATUS (*PFNKSDEVICEIRP)(PKSDEVICE Device, PIRP Irp); + +typedef void (*PFNKSDEVICEIRPVOID)(PKSDEVICE Device, PIRP Irp); + +typedef NTSTATUS (*PFNKSDEVICEQUERYCAPABILITIES)(PKSDEVICE Device, PIRP Irp, + PDEVICE_CAPABILITIES Capabilities); + +typedef NTSTATUS (*PFNKSDEVICEQUERYPOWER)(PKSDEVICE Device, PIRP Irp, + DEVICE_POWER_STATE DeviceTo, + DEVICE_POWER_STATE DeviceFrom, + SYSTEM_POWER_STATE SystemTo, + SYSTEM_POWER_STATE SystemFrom, + POWER_ACTION Action); + +typedef void (*PFNKSDEVICESETPOWER)(PKSDEVICE Device, PIRP Irp, + DEVICE_POWER_STATE To, + DEVICE_POWER_STATE From); + +typedef NTSTATUS (*PFNKSFILTERFACTORYVOID)(PKSFILTERFACTORY FilterFactory); + +typedef void (*PFNKSFILTERFACTORYPOWER)(PKSFILTERFACTORY FilterFactory, + DEVICE_POWER_STATE State); + +typedef NTSTATUS (*PFNKSFILTERIRP)(PKSFILTER Filter, PIRP Irp); + +typedef NTSTATUS (*PFNKSFILTERPROCESS)(PKSFILTER Filter, + PKSPROCESSPIN_INDEXENTRY Index); + +typedef NTSTATUS (*PFNKSFILTERVOID)(PKSFILTER Filter); + +typedef void (*PFNKSFILTERPOWER)(PKSFILTER Filter, DEVICE_POWER_STATE State); + +typedef NTSTATUS (*PFNKSPINIRP)(PKSPIN Pin, PIRP Irp); + +typedef NTSTATUS (*PFNKSPINSETDEVICESTATE)(PKSPIN Pin, KSSTATE ToState, + KSSTATE FromState); + +typedef NTSTATUS (*PFNKSPINSETDATAFORMAT)(PKSPIN Pin, PKSDATAFORMAT OldFormat, + PKSMULTIPLE_ITEM OldAttributeList, + const KSDATARANGE* DataRange, + const KSATTRIBUTE_LIST* AttributeRange); + +typedef NTSTATUS (*PFNKSPINHANDSHAKE)(PKSPIN Pin, PKSHANDSHAKE In, + PKSHANDSHAKE Out); + +typedef NTSTATUS (*PFNKSPIN)(PKSPIN Pin); + +typedef void (*PFNKSPINVOID)(PKSPIN Pin); + +typedef void (*PFNKSPINPOWER)(PKSPIN Pin, DEVICE_POWER_STATE State); + +typedef BOOLEAN (*PFNKSPINSETTIMER)(PKSPIN Pin, PKTIMER Timer, + LARGE_INTEGER DueTime, PKDPC Dpc); + +typedef BOOLEAN (*PFNKSPINCANCELTIMER)(PKSPIN Pin, PKTIMER Timer); + +typedef LONGLONG (FASTCALL * PFNKSPINCORRELATEDTIME)(PKSPIN Pin, + PLONGLONG SystemTime); + +typedef void (*PFNKSPINRESOLUTION)(PKSPIN Pin, PKSRESOLUTION Resolution); + +typedef NTSTATUS (*PFNKSPININITIALIZEALLOCATOR)(PKSPIN Pin, + PKSALLOCATOR_FRAMING AllocatorFraming, + PVOID* Context); + +typedef void (*PFNKSSTREAMPOINTER)(PKSSTREAM_POINTER StreamPointer); + +typedef struct KSAUTOMATION_TABLE_ KSAUTOMATION_TABLE, * PKSAUTOMATION_TABLE; + +struct KSAUTOMATION_TABLE_ +{ + ULONG PropertySetsCount; + ULONG PropertyItemSize; + const KSPROPERTY_SET* PropertySets; + ULONG MethodSetsCount; + ULONG MethodItemSize; + const KSMETHOD_SET* MethodSets; + ULONG EventSetsCount; + ULONG EventItemSize; + const KSEVENT_SET* EventSets; + # ifndef _WIN64 + PVOID Alignment; + # endif +}; + + # define DEFINE_KSAUTOMATION_TABLE(table) \ + const KSAUTOMATION_TABLE table = + + # define DEFINE_KSAUTOMATION_PROPERTIES(table) \ + SIZEOF_ARRAY(table), \ + sizeof(KSPROPERTY_ITEM), \ + table + + # define DEFINE_KSAUTOMATION_METHODS(table) \ + SIZEOF_ARRAY(table), \ + sizeof(KSMETHOD_ITEM), \ + table + + # define DEFINE_KSAUTOMATION_EVENTS(table) \ + SIZEOF_ARRAY(table), \ + sizeof(KSEVENT_ITEM), \ + table + + # define DEFINE_KSAUTOMATION_PROPERTIES_NULL \ + 0, \ + sizeof(KSPROPERTY_ITEM), \ + NULL + + # define DEFINE_KSAUTOMATION_METHODS_NULL \ + 0, \ + sizeof(KSMETHOD_ITEM), \ + NULL + + # define DEFINE_KSAUTOMATION_EVENTS_NULL \ + 0, \ + sizeof(KSEVENT_ITEM), \ + NULL + + # define MIN_DEV_VER_FOR_QI (0x100) + +struct _KSDEVICE_DISPATCH +{ + PFNKSDEVICECREATE Add; + PFNKSDEVICEPNPSTART Start; + PFNKSDEVICE PostStart; + PFNKSDEVICEIRP QueryStop; + PFNKSDEVICEIRPVOID CancelStop; + PFNKSDEVICEIRPVOID Stop; + PFNKSDEVICEIRP QueryRemove; + PFNKSDEVICEIRPVOID CancelRemove; + PFNKSDEVICEIRPVOID Remove; + PFNKSDEVICEQUERYCAPABILITIES QueryCapabilities; + PFNKSDEVICEIRPVOID SurpriseRemoval; + PFNKSDEVICEQUERYPOWER QueryPower; + PFNKSDEVICESETPOWER SetPower; + PFNKSDEVICEIRP QueryInterface; +}; + +struct _KSFILTER_DISPATCH +{ + PFNKSFILTERIRP Create; + PFNKSFILTERIRP Close; + PFNKSFILTERPROCESS Process; + PFNKSFILTERVOID Reset; +}; + +struct _KSPIN_DISPATCH +{ + PFNKSPINIRP Create; + PFNKSPINIRP Close; + PFNKSPIN Process; + PFNKSPINVOID Reset; + PFNKSPINSETDATAFORMAT SetDataFormat; + PFNKSPINSETDEVICESTATE SetDeviceState; + PFNKSPIN Connect; + PFNKSPINVOID Disconnect; + const KSCLOCK_DISPATCH* Clock; + const KSALLOCATOR_DISPATCH* Allocator; +}; + +struct _KSCLOCK_DISPATCH +{ + PFNKSPINSETTIMER SetTimer; + PFNKSPINCANCELTIMER CancelTimer; + PFNKSPINCORRELATEDTIME CorrelatedTime; + PFNKSPINRESOLUTION Resolution; +}; + +struct _KSALLOCATOR_DISPATCH +{ + PFNKSPININITIALIZEALLOCATOR InitializeAllocator; + PFNKSDELETEALLOCATOR DeleteAllocator; + PFNKSDEFAULTALLOCATE Allocate; + PFNKSDEFAULTFREE Free; +}; + + # define KSDEVICE_DESCRIPTOR_VERSION (0x100) + +struct _KSDEVICE_DESCRIPTOR +{ + const KSDEVICE_DISPATCH* Dispatch; + ULONG FilterDescriptorsCount; + const KSFILTER_DESCRIPTOR* const* FilterDescriptors; + ULONG Version; +}; + +struct _KSFILTER_DESCRIPTOR +{ + const KSFILTER_DISPATCH* Dispatch; + const KSAUTOMATION_TABLE* AutomationTable; + ULONG Version; + # define KSFILTER_DESCRIPTOR_VERSION ((ULONG)-1) + ULONG Flags; + # define KSFILTER_FLAG_DISPATCH_LEVEL_PROCESSING 0x00000001 + # define KSFILTER_FLAG_CRITICAL_PROCESSING 0x00000002 + # define KSFILTER_FLAG_HYPERCRITICAL_PROCESSING 0x00000004 + # define KSFILTER_FLAG_RECEIVE_ZERO_LENGTH_SAMPLES 0x00000008 + # define KSFILTER_FLAG_DENY_USERMODE_ACCESS 0x80000000 + const GUID* ReferenceGuid; + ULONG PinDescriptorsCount; + ULONG PinDescriptorSize; + const KSPIN_DESCRIPTOR_EX* PinDescriptors; + ULONG CategoriesCount; + const GUID* Categories; + ULONG NodeDescriptorsCount; + ULONG NodeDescriptorSize; + const KSNODE_DESCRIPTOR* NodeDescriptors; + ULONG ConnectionsCount; + const KSTOPOLOGY_CONNECTION* Connections; + const KSCOMPONENTID* ComponentId; +}; + + # define DEFINE_KSFILTER_DESCRIPTOR(descriptor) \ + const KSFILTER_DESCRIPTOR descriptor = + + # define DEFINE_KSFILTER_PIN_DESCRIPTORS(table) \ + SIZEOF_ARRAY(table), \ + sizeof(table[0]), \ + table + + # define DEFINE_KSFILTER_CATEGORIES(table) \ + SIZEOF_ARRAY(table), \ + table + + # define DEFINE_KSFILTER_CATEGORY(category) \ + 1, \ + &(category) + + # define DEFINE_KSFILTER_CATEGORIES_NULL \ + 0, \ + NULL + + # define DEFINE_KSFILTER_NODE_DESCRIPTORS(table) \ + SIZEOF_ARRAY(table), \ + sizeof(table[0]), \ + table + + # define DEFINE_KSFILTER_NODE_DESCRIPTORS_NULL \ + 0, \ + sizeof(KSNODE_DESCRIPTOR), \ + NULL + + # define DEFINE_KSFILTER_CONNECTIONS(table) \ + SIZEOF_ARRAY(table), \ + table + + # define DEFINE_KSFILTER_DEFAULT_CONNECTIONS \ + 0, \ + NULL + + # define DEFINE_KSFILTER_DESCRIPTOR_TABLE(table) \ + const KSFILTER_DESCRIPTOR * const table[] = + +struct _KSPIN_DESCRIPTOR_EX +{ + const KSPIN_DISPATCH* Dispatch; + const KSAUTOMATION_TABLE* AutomationTable; + KSPIN_DESCRIPTOR PinDescriptor; + ULONG Flags; + # define KSPIN_FLAG_DISPATCH_LEVEL_PROCESSING KSFILTER_FLAG_DISPATCH_LEVEL_PROCESSING + # define KSPIN_FLAG_CRITICAL_PROCESSING KSFILTER_FLAG_CRITICAL_PROCESSING + # define KSPIN_FLAG_HYPERCRITICAL_PROCESSING KSFILTER_FLAG_HYPERCRITICAL_PROCESSING + # define KSPIN_FLAG_ASYNCHRONOUS_PROCESSING 0x00000008 + # define KSPIN_FLAG_DO_NOT_INITIATE_PROCESSING 0x00000010 + # define KSPIN_FLAG_INITIATE_PROCESSING_ON_EVERY_ARRIVAL 0x00000020 + # define KSPIN_FLAG_FRAMES_NOT_REQUIRED_FOR_PROCESSING 0x00000040 + # define KSPIN_FLAG_ENFORCE_FIFO 0x00000080 + # define KSPIN_FLAG_GENERATE_MAPPINGS 0x00000100 + # define KSPIN_FLAG_DISTINCT_TRAILING_EDGE 0x00000200 + # define KSPIN_FLAG_PROCESS_IN_RUN_STATE_ONLY 0x00010000 + # define KSPIN_FLAG_SPLITTER 0x00020000 + # define KSPIN_FLAG_USE_STANDARD_TRANSPORT 0x00040000 + # define KSPIN_FLAG_DO_NOT_USE_STANDARD_TRANSPORT 0x00080000 + # define KSPIN_FLAG_FIXED_FORMAT 0x00100000 + # define KSPIN_FLAG_GENERATE_EOS_EVENTS 0x00200000 + # define KSPIN_FLAG_RENDERER (KSPIN_FLAG_PROCESS_IN_RUN_STATE_ONLY | KSPIN_FLAG_GENERATE_EOS_EVENTS) + # define KSPIN_FLAG_IMPLEMENT_CLOCK 0x00400000 + # define KSPIN_FLAG_SOME_FRAMES_REQUIRED_FOR_PROCESSING 0x00800000 + # define KSPIN_FLAG_PROCESS_IF_ANY_IN_RUN_STATE 0x01000000 + # define KSPIN_FLAG_DENY_USERMODE_ACCESS 0x80000000 + ULONG InstancesPossible; + ULONG InstancesNecessary; + const KSALLOCATOR_FRAMING_EX* AllocatorFraming; + PFNKSINTERSECTHANDLEREX IntersectHandler; +}; + + # define DEFINE_KSPIN_DEFAULT_INTERFACES \ + 0, \ + NULL + + # define DEFINE_KSPIN_DEFAULT_MEDIUMS \ + 0, \ + NULL + +struct _KSNODE_DESCRIPTOR +{ + const KSAUTOMATION_TABLE* AutomationTable; + const GUID* Type; + const GUID* Name; + # ifndef _WIN64 + PVOID Alignment; + # endif +}; + + # ifndef _WIN64 + # define DEFINE_NODE_DESCRIPTOR(automation, type, name) \ + { (automation), (type), (name), NULL } + # else + # define DEFINE_NODE_DESCRIPTOR(automation, type, name) \ + { (automation), (type), (name) } + # endif + +struct _KSDEVICE +{ + const KSDEVICE_DESCRIPTOR* Descriptor; + KSOBJECT_BAG Bag; + PVOID Context; + PDEVICE_OBJECT FunctionalDeviceObject; + PDEVICE_OBJECT PhysicalDeviceObject; + PDEVICE_OBJECT NextDeviceObject; + BOOLEAN Started; + SYSTEM_POWER_STATE SystemPowerState; + DEVICE_POWER_STATE DevicePowerState; +}; + +struct _KSFILTERFACTORY +{ + const KSFILTER_DESCRIPTOR* FilterDescriptor; + KSOBJECT_BAG Bag; + PVOID Context; +}; + +struct _KSFILTER +{ + const KSFILTER_DESCRIPTOR* Descriptor; + KSOBJECT_BAG Bag; + PVOID Context; +}; + +struct _KSPIN +{ + const KSPIN_DESCRIPTOR_EX* Descriptor; + KSOBJECT_BAG Bag; + PVOID Context; + ULONG Id; + KSPIN_COMMUNICATION Communication; + BOOLEAN ConnectionIsExternal; + KSPIN_INTERFACE ConnectionInterface; + KSPIN_MEDIUM ConnectionMedium; + KSPRIORITY ConnectionPriority; + PKSDATAFORMAT ConnectionFormat; + PKSMULTIPLE_ITEM AttributeList; + ULONG StreamHeaderSize; + KSPIN_DATAFLOW DataFlow; + KSSTATE DeviceState; + KSRESET ResetState; + KSSTATE ClientState; +}; + +struct _KSMAPPING +{ + PHYSICAL_ADDRESS PhysicalAddress; + ULONG ByteCount; + ULONG Alignment; +}; + +struct _KSSTREAM_POINTER_OFFSET +{ + # if defined(_NTDDK_) + __MINGW_EXTENSION union + { + PUCHAR Data; + PKSMAPPING Mappings; + }; + # else + PUCHAR Data; + # endif /* _NTDDK_ */ + # ifndef _WIN64 + PVOID Alignment; + # endif + ULONG Count; + ULONG Remaining; +}; + +struct _KSSTREAM_POINTER +{ + PVOID Context; + PKSPIN Pin; + PKSSTREAM_HEADER StreamHeader; + PKSSTREAM_POINTER_OFFSET Offset; + KSSTREAM_POINTER_OFFSET OffsetIn; + KSSTREAM_POINTER_OFFSET OffsetOut; +}; + +struct _KSPROCESSPIN +{ + PKSPIN Pin; + PKSSTREAM_POINTER StreamPointer; + PKSPROCESSPIN InPlaceCounterpart; + PKSPROCESSPIN DelegateBranch; + PKSPROCESSPIN CopySource; + PVOID Data; + ULONG BytesAvailable; + ULONG BytesUsed; + ULONG Flags; + BOOLEAN Terminate; +}; + +struct _KSPROCESSPIN_INDEXENTRY +{ + PKSPROCESSPIN* Pins; + ULONG Count; +}; + +typedef enum +{ + KsObjectTypeDevice, + KsObjectTypeFilterFactory, + KsObjectTypeFilter, + KsObjectTypePin +}KSOBJECTTYPE; + +typedef void (*PFNKSFREE)(PVOID Data); + +typedef void (*PFNKSPINFRAMERETURN)(PKSPIN Pin, PVOID Data, ULONG Size, PMDL Mdl, + PVOID Context, NTSTATUS Status); + +typedef void (*PFNKSPINIRPCOMPLETION)(PKSPIN Pin, PIRP Irp); + + # if defined(_UNKNOWN_H_) || defined(__IUnknown_INTERFACE_DEFINED__) + # ifndef _IKsControl_ + # define _IKsControl_ + +typedef struct IKsControl* PIKSCONTROL; + + # ifndef DEFINE_ABSTRACT_UNKNOWN + # define DEFINE_ABSTRACT_UNKNOWN() \ + STDMETHOD_(NTSTATUS, QueryInterface) (THIS_ \ + REFIID InterfaceId, \ + PVOID * Interface \ + )PURE; \ + STDMETHOD_(ULONG, AddRef) (THIS)PURE; \ + STDMETHOD_(ULONG, Release) (THIS)PURE; + # endif + + # undef INTERFACE + # define INTERFACE IKsControl +DECLARE_INTERFACE_(IKsControl, IUnknown) +{ + DEFINE_ABSTRACT_UNKNOWN() + STDMETHOD_(NTSTATUS, KsProperty) (THIS_ + PKSPROPERTY Property, + ULONG PropertyLength, + PVOID PropertyData, + ULONG DataLength, + ULONG * BytesReturned + ) PURE; + STDMETHOD_(NTSTATUS, KsMethod) (THIS_ + PKSMETHOD Method, + ULONG MethodLength, + PVOID MethodData, + ULONG DataLength, + ULONG * BytesReturned + ) PURE; + STDMETHOD_(NTSTATUS, KsEvent) (THIS_ + PKSEVENT Event, + ULONG EventLength, + PVOID EventData, + ULONG DataLength, + ULONG * BytesReturned + ) PURE; +}; +typedef struct IKsReferenceClock* PIKSREFERENCECLOCK; + + # undef INTERFACE + # define INTERFACE IKsReferenceClock +DECLARE_INTERFACE_(IKsReferenceClock, IUnknown) +{ + DEFINE_ABSTRACT_UNKNOWN() + STDMETHOD_(LONGLONG, GetTime) (THIS) PURE; + STDMETHOD_(LONGLONG, GetPhysicalTime) (THIS) PURE; + STDMETHOD_(LONGLONG, GetCorrelatedTime) (THIS_ + PLONGLONG SystemTime + ) PURE; + STDMETHOD_(LONGLONG, GetCorrelatedPhysicalTime) (THIS_ + PLONGLONG SystemTime + ) PURE; + STDMETHOD_(NTSTATUS, GetResolution) (THIS_ + PKSRESOLUTION Resolution + ) PURE; + STDMETHOD_(NTSTATUS, GetState) (THIS_ + PKSSTATE State + ) PURE; +}; + # undef INTERFACE + + # define INTERFACE IKsDeviceFunctions +DECLARE_INTERFACE_(IKsDeviceFunctions, IUnknown) +{ + DEFINE_ABSTRACT_UNKNOWN() + STDMETHOD_(NTSTATUS, RegisterAdapterObjectEx) (THIS_ + PADAPTER_OBJECT AdapterObject, + PDEVICE_DESCRIPTION DeviceDescription, + ULONG NumberOfMapRegisters, + ULONG MaxMappingsByteCount, + ULONG MappingTableStride + ) PURE; +}; + + # undef INTERFACE + # define STATIC_IID_IKsControl \ + 0x28F54685L, 0x06FD, 0x11D2, 0xB2, 0x7A, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96 +DEFINE_GUID(IID_IKsControl, + 0x28F54685L, 0x06FD, 0x11D2, 0xB2, 0x7A, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96); + # define STATIC_IID_IKsFastClock \ + 0xc9902485, 0xc180, 0x11d2, 0x84, 0x73, 0xd4, 0x23, 0x94, 0x45, 0x9e, 0x5e +DEFINE_GUID(IID_IKsFastClock, + 0xc9902485, 0xc180, 0x11d2, 0x84, 0x73, 0xd4, 0x23, 0x94, 0x45, 0x9e, 0x5e); + # define STATIC_IID_IKsDeviceFunctions \ + 0xe234f2e2, 0xbd69, 0x4f8c, 0xb3, 0xf2, 0x7c, 0xd7, 0x9e, 0xd4, 0x66, 0xbd +DEFINE_GUID(IID_IKsDeviceFunctions, + 0xe234f2e2, 0xbd69, 0x4f8c, 0xb3, 0xf2, 0x7c, 0xd7, 0x9e, 0xd4, 0x66, 0xbd); + # endif /* _IKsControl_ */ + # endif /* defined(_UNKNOWN_H_) || defined(__IUnknown_INTERFACE_DEFINED__) */ + +#endif /* _NTDDK_ */ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef _KSDDK_ + # define KSDDKAPI +#else + # define KSDDKAPI DECLSPEC_IMPORT +#endif + +#if defined(_NTDDK_) + +KSDDKAPI NTSTATUS NTAPI KsEnableEvent(PIRP Irp, ULONG EventSetsCount, const KSEVENT_SET* EventSet, PLIST_ENTRY EventsList, KSEVENTS_LOCKTYPE EventsFlags, PVOID EventsLock); + +KSDDKAPI NTSTATUS NTAPI KsEnableEventWithAllocator(PIRP Irp, ULONG EventSetsCount, const KSEVENT_SET* EventSet, PLIST_ENTRY EventsList, KSEVENTS_LOCKTYPE EventsFlags, PVOID EventsLock, PFNKSALLOCATOR Allocator, ULONG EventItemSize); + +KSDDKAPI NTSTATUS NTAPI KsDisableEvent(PIRP Irp, PLIST_ENTRY EventsList, KSEVENTS_LOCKTYPE EventsFlags, PVOID EventsLock); + +KSDDKAPI VOID NTAPI KsDiscardEvent(PKSEVENT_ENTRY EventEntry); + +KSDDKAPI VOID NTAPI KsFreeEventList(PFILE_OBJECT FileObject, PLIST_ENTRY EventsList, KSEVENTS_LOCKTYPE EventsFlags, PVOID EventsLock); + +KSDDKAPI NTSTATUS NTAPI KsGenerateEvent(PKSEVENT_ENTRY EventEntry); + +KSDDKAPI NTSTATUS NTAPI KsGenerateDataEvent(PKSEVENT_ENTRY EventEntry, ULONG DataSize, PVOID Data); + +KSDDKAPI VOID NTAPI KsGenerateEventList(GUID* Set, ULONG EventId, PLIST_ENTRY EventsList, KSEVENTS_LOCKTYPE EventsFlags, PVOID EventsLock); + +KSDDKAPI NTSTATUS NTAPI KsPropertyHandler(PIRP Irp, ULONG PropertySetsCount, const KSPROPERTY_SET* PropertySet); + +KSDDKAPI NTSTATUS NTAPI KsPropertyHandlerWithAllocator(PIRP Irp, ULONG PropertySetsCount, const KSPROPERTY_SET* PropertySet, PFNKSALLOCATOR Allocator, ULONG PropertyItemSize); + +KSDDKAPI BOOLEAN NTAPI KsFastPropertyHandler(PFILE_OBJECT FileObject, PKSPROPERTY Property, ULONG PropertyLength, PVOID Data, ULONG DataLength, PIO_STATUS_BLOCK IoStatus, ULONG PropertySetsCount, const KSPROPERTY_SET* PropertySet); + +KSDDKAPI NTSTATUS NTAPI KsMethodHandler(PIRP Irp, ULONG MethodSetsCount, const KSMETHOD_SET* MethodSet); + +KSDDKAPI NTSTATUS NTAPI KsMethodHandlerWithAllocator(PIRP Irp, ULONG MethodSetsCount, const KSMETHOD_SET* MethodSet, PFNKSALLOCATOR Allocator, ULONG MethodItemSize); + +KSDDKAPI BOOLEAN NTAPI KsFastMethodHandler(PFILE_OBJECT FileObject, PKSMETHOD Method, ULONG MethodLength, PVOID Data, ULONG DataLength, PIO_STATUS_BLOCK IoStatus, ULONG MethodSetsCount, const KSMETHOD_SET* MethodSet); + +KSDDKAPI NTSTATUS NTAPI KsCreateDefaultAllocator(PIRP Irp); + +KSDDKAPI NTSTATUS NTAPI KsCreateDefaultAllocatorEx(PIRP Irp, PVOID InitializeContext, PFNKSDEFAULTALLOCATE DefaultAllocate, PFNKSDEFAULTFREE DefaultFree, PFNKSINITIALIZEALLOCATOR InitializeAllocator, PFNKSDELETEALLOCATOR DeleteAllocator); + +KSDDKAPI NTSTATUS NTAPI KsCreateAllocator(HANDLE ConnectionHandle, PKSALLOCATOR_FRAMING AllocatorFraming, PHANDLE AllocatorHandle); + +KSDDKAPI NTSTATUS NTAPI KsValidateAllocatorCreateRequest(PIRP Irp, PKSALLOCATOR_FRAMING* AllocatorFraming); + +KSDDKAPI NTSTATUS NTAPI KsValidateAllocatorFramingEx(PKSALLOCATOR_FRAMING_EX Framing, ULONG BufferSize, const KSALLOCATOR_FRAMING_EX* PinFraming); + +KSDDKAPI NTSTATUS NTAPI KsAllocateDefaultClock(PKSDEFAULTCLOCK* DefaultClock); + +KSDDKAPI NTSTATUS NTAPI KsAllocateDefaultClockEx(PKSDEFAULTCLOCK* DefaultClock, PVOID Context, PFNKSSETTIMER SetTimer, PFNKSCANCELTIMER CancelTimer, PFNKSCORRELATEDTIME CorrelatedTime, const KSRESOLUTION* Resolution, ULONG Flags); + +KSDDKAPI VOID NTAPI KsFreeDefaultClock(PKSDEFAULTCLOCK DefaultClock); +KSDDKAPI NTSTATUS NTAPI KsCreateDefaultClock(PIRP Irp, PKSDEFAULTCLOCK DefaultClock); + +KSDDKAPI NTSTATUS NTAPI KsCreateClock(HANDLE ConnectionHandle, PKSCLOCK_CREATE ClockCreate, PHANDLE ClockHandle); + +KSDDKAPI NTSTATUS NTAPI KsValidateClockCreateRequest(PIRP Irp, PKSCLOCK_CREATE* ClockCreate); + +KSDDKAPI KSSTATE NTAPI KsGetDefaultClockState(PKSDEFAULTCLOCK DefaultClock); +KSDDKAPI VOID NTAPI KsSetDefaultClockState(PKSDEFAULTCLOCK DefaultClock, KSSTATE State); +KSDDKAPI LONGLONG NTAPI KsGetDefaultClockTime(PKSDEFAULTCLOCK DefaultClock); +KSDDKAPI VOID NTAPI KsSetDefaultClockTime(PKSDEFAULTCLOCK DefaultClock, LONGLONG Time); + +KSDDKAPI NTSTATUS NTAPI KsCreatePin(HANDLE FilterHandle, PKSPIN_CONNECT Connect, ACCESS_MASK DesiredAccess, PHANDLE ConnectionHandle); + +KSDDKAPI NTSTATUS NTAPI KsValidateConnectRequest(PIRP Irp, ULONG DescriptorsCount, const KSPIN_DESCRIPTOR* Descriptor, PKSPIN_CONNECT* Connect); + +KSDDKAPI NTSTATUS NTAPI KsPinPropertyHandler(PIRP Irp, PKSPROPERTY Property, PVOID Data, ULONG DescriptorsCount, const KSPIN_DESCRIPTOR* Descriptor); + +KSDDKAPI NTSTATUS NTAPI KsPinDataIntersection(PIRP Irp, PKSP_PIN Pin, PVOID Data, ULONG DescriptorsCount, const KSPIN_DESCRIPTOR* Descriptor, PFNKSINTERSECTHANDLER IntersectHandler); + +KSDDKAPI NTSTATUS NTAPI KsPinDataIntersectionEx(PIRP Irp, PKSP_PIN Pin, PVOID Data, ULONG DescriptorsCount, const KSPIN_DESCRIPTOR* Descriptor, ULONG DescriptorSize, PFNKSINTERSECTHANDLEREX IntersectHandler, PVOID HandlerContext); + +KSDDKAPI NTSTATUS NTAPI KsHandleSizedListQuery(PIRP Irp, ULONG DataItemsCount, ULONG DataItemSize, const VOID* DataItems); + + # ifndef MAKEINTRESOURCE + # define MAKEINTRESOURCE(r) ((ULONG_PTR)(USHORT)r) + # endif + # ifndef RT_STRING + # define RT_STRING MAKEINTRESOURCE(6) + # define RT_RCDATA MAKEINTRESOURCE(10) + # endif + +KSDDKAPI NTSTATUS NTAPI KsLoadResource(PVOID ImageBase, POOL_TYPE PoolType, ULONG_PTR ResourceName, ULONG ResourceType, PVOID* Resource, PULONG ResourceSize); + +KSDDKAPI NTSTATUS NTAPI KsGetImageNameAndResourceId(HANDLE RegKey, PUNICODE_STRING ImageName, PULONG_PTR ResourceId, PULONG ValueType); + +KSDDKAPI NTSTATUS NTAPI KsMapModuleName(PDEVICE_OBJECT PhysicalDeviceObject, PUNICODE_STRING ModuleName, PUNICODE_STRING ImageName, PULONG_PTR ResourceId, PULONG ValueType); + +KSDDKAPI NTSTATUS NTAPI KsReferenceBusObject(KSDEVICE_HEADER Header); +KSDDKAPI VOID NTAPI KsDereferenceBusObject(KSDEVICE_HEADER Header); +KSDDKAPI NTSTATUS NTAPI KsDispatchQuerySecurity(PDEVICE_OBJECT DeviceObject, PIRP Irp); +KSDDKAPI NTSTATUS NTAPI KsDispatchSetSecurity(PDEVICE_OBJECT DeviceObject, PIRP Irp); +KSDDKAPI NTSTATUS NTAPI KsDispatchSpecificProperty(PIRP Irp, PFNKSHANDLER Handler); +KSDDKAPI NTSTATUS NTAPI KsDispatchSpecificMethod(PIRP Irp, PFNKSHANDLER Handler); + +KSDDKAPI NTSTATUS NTAPI KsReadFile(PFILE_OBJECT FileObject, PKEVENT Event, PVOID PortContext, PIO_STATUS_BLOCK IoStatusBlock, PVOID Buffer, ULONG Length, ULONG Key, KPROCESSOR_MODE RequestorMode); + +KSDDKAPI NTSTATUS NTAPI KsWriteFile(PFILE_OBJECT FileObject, PKEVENT Event, PVOID PortContext, PIO_STATUS_BLOCK IoStatusBlock, PVOID Buffer, ULONG Length, ULONG Key, KPROCESSOR_MODE RequestorMode); + +KSDDKAPI NTSTATUS NTAPI KsQueryInformationFile(PFILE_OBJECT FileObject, PVOID FileInformation, ULONG Length, FILE_INFORMATION_CLASS FileInformationClass); + +KSDDKAPI NTSTATUS NTAPI KsSetInformationFile(PFILE_OBJECT FileObject, PVOID FileInformation, ULONG Length, FILE_INFORMATION_CLASS FileInformationClass); + +KSDDKAPI NTSTATUS NTAPI KsStreamIo(PFILE_OBJECT FileObject, PKEVENT Event, PVOID PortContext, PIO_COMPLETION_ROUTINE CompletionRoutine, PVOID CompletionContext, KSCOMPLETION_INVOCATION CompletionInvocationFlags, PIO_STATUS_BLOCK IoStatusBlock, PVOID StreamHeaders, ULONG Length, ULONG Flags, KPROCESSOR_MODE RequestorMode); + +KSDDKAPI NTSTATUS NTAPI KsProbeStreamIrp(PIRP Irp, ULONG ProbeFlags, ULONG HeaderSize); +KSDDKAPI NTSTATUS NTAPI KsAllocateExtraData(PIRP Irp, ULONG ExtraSize, PVOID* ExtraBuffer); +KSDDKAPI VOID NTAPI KsNullDriverUnload(PDRIVER_OBJECT DriverObject); + +KSDDKAPI NTSTATUS NTAPI KsSetMajorFunctionHandler(PDRIVER_OBJECT DriverObject, ULONG MajorFunction); + +KSDDKAPI NTSTATUS NTAPI KsDispatchInvalidDeviceRequest(PDEVICE_OBJECT DeviceObject, PIRP Irp); + +KSDDKAPI NTSTATUS NTAPI KsDefaultDeviceIoCompletion(PDEVICE_OBJECT DeviceObject, PIRP Irp); + +KSDDKAPI NTSTATUS NTAPI KsDispatchIrp(PDEVICE_OBJECT DeviceObject, PIRP Irp); + +KSDDKAPI BOOLEAN NTAPI KsDispatchFastIoDeviceControlFailure(PFILE_OBJECT FileObject, BOOLEAN Wait, PVOID InputBuffer, ULONG InputBufferLength, PVOID OutputBuffer, ULONG OutputBufferLength, ULONG IoControlCode, PIO_STATUS_BLOCK IoStatus, PDEVICE_OBJECT DeviceObject); + +KSDDKAPI BOOLEAN NTAPI KsDispatchFastReadFailure(PFILE_OBJECT FileObject, PLARGE_INTEGER FileOffset, ULONG Length, BOOLEAN Wait, ULONG LockKey, PVOID Buffer, PIO_STATUS_BLOCK IoStatus, PDEVICE_OBJECT DeviceObject); + + # define KsDispatchFastWriteFailure KsDispatchFastReadFailure + +KSDDKAPI VOID NTAPI KsCancelRoutine(PDEVICE_OBJECT DeviceObject, PIRP Irp); +KSDDKAPI VOID NTAPI KsCancelIo(PLIST_ENTRY QueueHead, PKSPIN_LOCK SpinLock); +KSDDKAPI VOID NTAPI KsReleaseIrpOnCancelableQueue(PIRP Irp, PDRIVER_CANCEL DriverCancel); + +KSDDKAPI PIRP NTAPI KsRemoveIrpFromCancelableQueue(PLIST_ENTRY QueueHead, PKSPIN_LOCK SpinLock, KSLIST_ENTRY_LOCATION ListLocation, KSIRP_REMOVAL_OPERATION RemovalOperation); + +KSDDKAPI NTSTATUS NTAPI KsMoveIrpsOnCancelableQueue(PLIST_ENTRY SourceList, PKSPIN_LOCK SourceLock, PLIST_ENTRY DestinationList, PKSPIN_LOCK DestinationLock, KSLIST_ENTRY_LOCATION ListLocation, PFNKSIRPLISTCALLBACK ListCallback, PVOID Context); + +KSDDKAPI VOID NTAPI KsRemoveSpecificIrpFromCancelableQueue(PIRP Irp); + +KSDDKAPI VOID NTAPI KsAddIrpToCancelableQueue(PLIST_ENTRY QueueHead, PKSPIN_LOCK SpinLock, PIRP Irp, KSLIST_ENTRY_LOCATION ListLocation, PDRIVER_CANCEL DriverCancel); + +KSDDKAPI NTSTATUS NTAPI KsAcquireResetValue(PIRP Irp, KSRESET* ResetValue); + +KSDDKAPI NTSTATUS NTAPI KsTopologyPropertyHandler(PIRP Irp, PKSPROPERTY Property, PVOID Data, const KSTOPOLOGY* Topology); + +KSDDKAPI VOID NTAPI KsAcquireDeviceSecurityLock(KSDEVICE_HEADER Header, BOOLEAN Exclusive); +KSDDKAPI VOID NTAPI KsReleaseDeviceSecurityLock(KSDEVICE_HEADER Header); +KSDDKAPI NTSTATUS NTAPI KsDefaultDispatchPnp(PDEVICE_OBJECT DeviceObject, PIRP Irp); +KSDDKAPI NTSTATUS NTAPI KsDefaultDispatchPower(PDEVICE_OBJECT DeviceObject, PIRP Irp); +KSDDKAPI NTSTATUS NTAPI KsDefaultForwardIrp(PDEVICE_OBJECT DeviceObject, PIRP Irp); + +KSDDKAPI VOID NTAPI KsSetDevicePnpAndBaseObject(KSDEVICE_HEADER Header, PDEVICE_OBJECT PnpDeviceObject, PDEVICE_OBJECT BaseObject); + +KSDDKAPI PDEVICE_OBJECT NTAPI KsQueryDevicePnpObject(KSDEVICE_HEADER Header); +KSDDKAPI ACCESS_MASK NTAPI KsQueryObjectAccessMask(KSOBJECT_HEADER Header); + +KSDDKAPI VOID NTAPI KsRecalculateStackDepth(KSDEVICE_HEADER Header, BOOLEAN ReuseStackLocation); + +KSDDKAPI VOID NTAPI KsSetTargetState(KSOBJECT_HEADER Header, KSTARGET_STATE TargetState); + +KSDDKAPI VOID NTAPI KsSetTargetDeviceObject(KSOBJECT_HEADER Header, PDEVICE_OBJECT TargetDevice); + +KSDDKAPI VOID NTAPI KsSetPowerDispatch(KSOBJECT_HEADER Header, PFNKSCONTEXT_DISPATCH PowerDispatch, PVOID PowerContext); + +KSDDKAPI PKSOBJECT_CREATE_ITEM NTAPI KsQueryObjectCreateItem(KSOBJECT_HEADER Header); + +KSDDKAPI NTSTATUS NTAPI KsAllocateDeviceHeader(KSDEVICE_HEADER* Header, ULONG ItemsCount, PKSOBJECT_CREATE_ITEM ItemsList); + +KSDDKAPI VOID NTAPI KsFreeDeviceHeader(KSDEVICE_HEADER Header); + +KSDDKAPI NTSTATUS NTAPI KsAllocateObjectHeader(KSOBJECT_HEADER* Header, ULONG ItemsCount, PKSOBJECT_CREATE_ITEM ItemsList, PIRP Irp, const KSDISPATCH_TABLE* Table); + +KSDDKAPI VOID NTAPI KsFreeObjectHeader(KSOBJECT_HEADER Header); + +KSDDKAPI NTSTATUS NTAPI KsAddObjectCreateItemToDeviceHeader(KSDEVICE_HEADER Header, PDRIVER_DISPATCH Create, PVOID Context, PWSTR ObjectClass, PSECURITY_DESCRIPTOR SecurityDescriptor); + +KSDDKAPI NTSTATUS NTAPI KsAddObjectCreateItemToObjectHeader(KSOBJECT_HEADER Header, PDRIVER_DISPATCH Create, PVOID Context, PWSTR ObjectClass, PSECURITY_DESCRIPTOR SecurityDescriptor); + +KSDDKAPI NTSTATUS NTAPI KsAllocateObjectCreateItem(KSDEVICE_HEADER Header, PKSOBJECT_CREATE_ITEM CreateItem, BOOLEAN AllocateEntry, PFNKSITEMFREECALLBACK ItemFreeCallback); + +KSDDKAPI NTSTATUS NTAPI KsFreeObjectCreateItem(KSDEVICE_HEADER Header, PUNICODE_STRING CreateItem); + +KSDDKAPI NTSTATUS NTAPI KsFreeObjectCreateItemsByContext(KSDEVICE_HEADER Header, PVOID Context); + +KSDDKAPI NTSTATUS NTAPI KsCreateDefaultSecurity(PSECURITY_DESCRIPTOR ParentSecurity, PSECURITY_DESCRIPTOR* DefaultSecurity); + +KSDDKAPI NTSTATUS NTAPI KsForwardIrp(PIRP Irp, PFILE_OBJECT FileObject, BOOLEAN ReuseStackLocation); + +KSDDKAPI NTSTATUS NTAPI KsForwardAndCatchIrp(PDEVICE_OBJECT DeviceObject, PIRP Irp, PFILE_OBJECT FileObject, KSSTACK_USE StackUse); + +KSDDKAPI NTSTATUS NTAPI KsSynchronousIoControlDevice(PFILE_OBJECT FileObject, KPROCESSOR_MODE RequestorMode, ULONG IoControl, PVOID InBuffer, ULONG InSize, PVOID OutBuffer, ULONG OutSize, PULONG BytesReturned); + +KSDDKAPI NTSTATUS NTAPI KsUnserializeObjectPropertiesFromRegistry(PFILE_OBJECT FileObject, HANDLE ParentKey, PUNICODE_STRING RegistryPath); + +KSDDKAPI NTSTATUS NTAPI KsCacheMedium(PUNICODE_STRING SymbolicLink, PKSPIN_MEDIUM Medium, ULONG PinDirection); + +KSDDKAPI NTSTATUS NTAPI KsRegisterWorker(WORK_QUEUE_TYPE WorkQueueType, PKSWORKER* Worker); + +KSDDKAPI NTSTATUS NTAPI KsRegisterCountedWorker(WORK_QUEUE_TYPE WorkQueueType, PWORK_QUEUE_ITEM CountedWorkItem, PKSWORKER* Worker); + +KSDDKAPI VOID NTAPI KsUnregisterWorker(PKSWORKER Worker); +KSDDKAPI NTSTATUS NTAPI KsQueueWorkItem(PKSWORKER Worker, PWORK_QUEUE_ITEM WorkItem); +KSDDKAPI ULONG NTAPI KsIncrementCountedWorker(PKSWORKER Worker); +KSDDKAPI ULONG NTAPI KsDecrementCountedWorker(PKSWORKER Worker); + +KSDDKAPI NTSTATUS NTAPI KsCreateTopologyNode(HANDLE ParentHandle, PKSNODE_CREATE NodeCreate, ACCESS_MASK DesiredAccess, PHANDLE NodeHandle); + +KSDDKAPI NTSTATUS NTAPI KsValidateTopologyNodeCreateRequest(PIRP Irp, PKSTOPOLOGY Topology, PKSNODE_CREATE* NodeCreate); + +KSDDKAPI NTSTATUS NTAPI KsMergeAutomationTables(PKSAUTOMATION_TABLE* AutomationTableAB, PKSAUTOMATION_TABLE AutomationTableA, PKSAUTOMATION_TABLE AutomationTableB, KSOBJECT_BAG Bag); + +KSDDKAPI NTSTATUS NTAPI KsInitializeDriver(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPathName, const KSDEVICE_DESCRIPTOR* Descriptor); + +KSDDKAPI NTSTATUS NTAPI KsAddDevice(PDRIVER_OBJECT DriverObject, PDEVICE_OBJECT PhysicalDeviceObject); + +KSDDKAPI NTSTATUS NTAPI KsCreateDevice(PDRIVER_OBJECT DriverObject, PDEVICE_OBJECT PhysicalDeviceObject, const KSDEVICE_DESCRIPTOR* Descriptor, ULONG ExtensionSize, PKSDEVICE* Device); + +KSDDKAPI NTSTATUS NTAPI KsInitializeDevice(PDEVICE_OBJECT FunctionalDeviceObject, PDEVICE_OBJECT PhysicalDeviceObject, PDEVICE_OBJECT NextDeviceObject, const KSDEVICE_DESCRIPTOR* Descriptor); + +KSDDKAPI void NTAPI KsTerminateDevice(PDEVICE_OBJECT DeviceObject); +KSDDKAPI PKSDEVICE NTAPI KsGetDeviceForDeviceObject(PDEVICE_OBJECT FunctionalDeviceObject); +KSDDKAPI void NTAPI KsAcquireDevice(PKSDEVICE Device); +KSDDKAPI void NTAPI KsReleaseDevice(PKSDEVICE Device); + +KSDDKAPI void NTAPI KsDeviceRegisterAdapterObject(PKSDEVICE Device, PADAPTER_OBJECT AdapterObject, ULONG MaxMappingsByteCount, ULONG MappingTableStride); + +KSDDKAPI ULONG NTAPI KsDeviceGetBusData(PKSDEVICE Device, ULONG DataType, PVOID Buffer, ULONG Offset, ULONG Length); + +KSDDKAPI ULONG NTAPI KsDeviceSetBusData(PKSDEVICE Device, ULONG DataType, PVOID Buffer, ULONG Offset, ULONG Length); + +KSDDKAPI NTSTATUS NTAPI KsCreateFilterFactory(PDEVICE_OBJECT DeviceObject, const KSFILTER_DESCRIPTOR* Descriptor, PWSTR RefString, PSECURITY_DESCRIPTOR SecurityDescriptor, ULONG CreateItemFlags, PFNKSFILTERFACTORYPOWER SleepCallback, PFNKSFILTERFACTORYPOWER WakeCallback, PKSFILTERFACTORY* FilterFactory); + + # define KsDeleteFilterFactory(FilterFactory) \ + KsFreeObjectCreateItemsByContext(*(KSDEVICE_HEADER*)( \ + KsFilterFactoryGetParentDevice(FilterFactory)->FunctionalDeviceObject->DeviceExtension), \ + FilterFactory) + +KSDDKAPI NTSTATUS NTAPI KsFilterFactoryUpdateCacheData(PKSFILTERFACTORY FilterFactory, const KSFILTER_DESCRIPTOR* FilterDescriptor); + +KSDDKAPI NTSTATUS NTAPI KsFilterFactoryAddCreateItem(PKSFILTERFACTORY FilterFactory, PWSTR RefString, PSECURITY_DESCRIPTOR SecurityDescriptor, ULONG CreateItemFlags); + +KSDDKAPI NTSTATUS NTAPI KsFilterFactorySetDeviceClassesState(PKSFILTERFACTORY FilterFactory, BOOLEAN NewState); + +KSDDKAPI PUNICODE_STRING NTAPI KsFilterFactoryGetSymbolicLink(PKSFILTERFACTORY FilterFactory); + +KSDDKAPI void NTAPI KsAddEvent(PVOID Object, PKSEVENT_ENTRY EventEntry); + +void __forceinline KsFilterAddEvent(PKSFILTER Filter, PKSEVENT_ENTRY EventEntry) +{ + KsAddEvent(Filter, EventEntry); +} + +void __forceinline KsPinAddEvent(PKSPIN Pin, PKSEVENT_ENTRY EventEntry) +{ + KsAddEvent(Pin, EventEntry); +} + +KSDDKAPI NTSTATUS NTAPI KsDefaultAddEventHandler(PIRP Irp, PKSEVENTDATA EventData, PKSEVENT_ENTRY EventEntry); + +KSDDKAPI void NTAPI KsGenerateEvents(PVOID Object, const GUID* EventSet, ULONG EventId, ULONG DataSize, PVOID Data, PFNKSGENERATEEVENTCALLBACK CallBack, PVOID CallBackContext); + +void __forceinline KsFilterGenerateEvents(PKSFILTER Filter, const GUID* EventSet, ULONG EventId, ULONG DataSize, PVOID Data, PFNKSGENERATEEVENTCALLBACK CallBack, PVOID CallBackContext) +{ + KsGenerateEvents(Filter, EventSet, EventId, DataSize, Data, CallBack, + CallBackContext); +} + +void __forceinline KsPinGenerateEvents(PKSPIN Pin, const GUID* EventSet, ULONG EventId, ULONG DataSize, PVOID Data, PFNKSGENERATEEVENTCALLBACK CallBack, PVOID CallBackContext) +{ + KsGenerateEvents(Pin, EventSet, EventId, DataSize, Data, CallBack, + CallBackContext); +} + +typedef enum +{ + KSSTREAM_POINTER_STATE_UNLOCKED = 0, + KSSTREAM_POINTER_STATE_LOCKED +}KSSTREAM_POINTER_STATE; + +KSDDKAPI NTSTATUS NTAPI KsPinGetAvailableByteCount(PKSPIN Pin, PLONG InputDataBytes, PLONG OutputBufferBytes); + +KSDDKAPI PKSSTREAM_POINTER NTAPI KsPinGetLeadingEdgeStreamPointer(PKSPIN Pin, KSSTREAM_POINTER_STATE State); + +KSDDKAPI PKSSTREAM_POINTER NTAPI KsPinGetTrailingEdgeStreamPointer(PKSPIN Pin, KSSTREAM_POINTER_STATE State); + +KSDDKAPI NTSTATUS NTAPI KsStreamPointerSetStatusCode(PKSSTREAM_POINTER StreamPointer, NTSTATUS Status); + +KSDDKAPI NTSTATUS NTAPI KsStreamPointerLock(PKSSTREAM_POINTER StreamPointer); +KSDDKAPI void NTAPI KsStreamPointerUnlock(PKSSTREAM_POINTER StreamPointer, BOOLEAN Eject); + +KSDDKAPI void NTAPI KsStreamPointerAdvanceOffsetsAndUnlock(PKSSTREAM_POINTER StreamPointer, ULONG InUsed, ULONG OutUsed, BOOLEAN Eject); + +KSDDKAPI void NTAPI KsStreamPointerDelete(PKSSTREAM_POINTER StreamPointer); + +KSDDKAPI NTSTATUS NTAPI KsStreamPointerClone(PKSSTREAM_POINTER StreamPointer, PFNKSSTREAMPOINTER CancelCallback, ULONG ContextSize, PKSSTREAM_POINTER* CloneStreamPointer); + +KSDDKAPI NTSTATUS NTAPI KsStreamPointerAdvanceOffsets(PKSSTREAM_POINTER StreamPointer, ULONG InUsed, ULONG OutUsed, BOOLEAN Eject); + +KSDDKAPI NTSTATUS NTAPI KsStreamPointerAdvance(PKSSTREAM_POINTER StreamPointer); +KSDDKAPI PMDL NTAPI KsStreamPointerGetMdl(PKSSTREAM_POINTER StreamPointer); + +KSDDKAPI PIRP NTAPI KsStreamPointerGetIrp(PKSSTREAM_POINTER StreamPointer, PBOOLEAN FirstFrameInIrp, PBOOLEAN LastFrameInIrp); + +KSDDKAPI void NTAPI KsStreamPointerScheduleTimeout(PKSSTREAM_POINTER StreamPointer, PFNKSSTREAMPOINTER Callback, ULONGLONG Interval); + +KSDDKAPI void NTAPI KsStreamPointerCancelTimeout(PKSSTREAM_POINTER StreamPointer); +KSDDKAPI PKSSTREAM_POINTER NTAPI KsPinGetFirstCloneStreamPointer(PKSPIN Pin); + +KSDDKAPI PKSSTREAM_POINTER NTAPI KsStreamPointerGetNextClone(PKSSTREAM_POINTER StreamPointer); + +KSDDKAPI NTSTATUS NTAPI KsPinHandshake(PKSPIN Pin, PKSHANDSHAKE In, PKSHANDSHAKE Out); +KSDDKAPI void NTAPI KsCompletePendingRequest(PIRP Irp); +KSDDKAPI KSOBJECTTYPE NTAPI KsGetObjectTypeFromIrp(PIRP Irp); +KSDDKAPI PVOID NTAPI KsGetObjectFromFileObject(PFILE_OBJECT FileObject); +KSDDKAPI KSOBJECTTYPE NTAPI KsGetObjectTypeFromFileObject(PFILE_OBJECT FileObject); + +PKSFILTER __forceinline KsGetFilterFromFileObject(PFILE_OBJECT FileObject) +{ + return (PKSFILTER)KsGetObjectFromFileObject(FileObject); +} + +PKSPIN __forceinline KsGetPinFromFileObject(PFILE_OBJECT FileObject) +{ + return (PKSPIN)KsGetObjectFromFileObject(FileObject); +} + +KSDDKAPI PKSGATE NTAPI KsFilterGetAndGate(PKSFILTER Filter); +KSDDKAPI void NTAPI KsFilterAcquireProcessingMutex(PKSFILTER Filter); +KSDDKAPI void NTAPI KsFilterReleaseProcessingMutex(PKSFILTER Filter); +KSDDKAPI void NTAPI KsFilterAttemptProcessing(PKSFILTER Filter, BOOLEAN Asynchronous); +KSDDKAPI PKSGATE NTAPI KsPinGetAndGate(PKSPIN Pin); +KSDDKAPI void NTAPI KsPinAttachAndGate(PKSPIN Pin, PKSGATE AndGate); +KSDDKAPI void NTAPI KsPinAttachOrGate(PKSPIN Pin, PKSGATE OrGate); +KSDDKAPI void NTAPI KsPinAcquireProcessingMutex(PKSPIN Pin); +KSDDKAPI void NTAPI KsPinReleaseProcessingMutex(PKSPIN Pin); +KSDDKAPI BOOLEAN NTAPI KsProcessPinUpdate(PKSPROCESSPIN ProcessPin); + +KSDDKAPI void NTAPI KsPinGetCopyRelationships(PKSPIN Pin, PKSPIN* CopySource, PKSPIN* DelegateBranch); + +KSDDKAPI void NTAPI KsPinAttemptProcessing(PKSPIN Pin, BOOLEAN Asynchronous); +KSDDKAPI PVOID NTAPI KsGetParent(PVOID Object); + +PKSDEVICE __forceinline KsFilterFactoryGetParentDevice(PKSFILTERFACTORY FilterFactory) +{ + return (PKSDEVICE)KsGetParent((PVOID)FilterFactory); +} + +PKSFILTERFACTORY __forceinline KsFilterGetParentFilterFactory(PKSFILTER Filter) +{ + return (PKSFILTERFACTORY)KsGetParent((PVOID)Filter); +} + +KSDDKAPI PKSFILTER NTAPI KsPinGetParentFilter(PKSPIN Pin); +KSDDKAPI PVOID NTAPI KsGetFirstChild(PVOID Object); + +PKSFILTERFACTORY __forceinline KsDeviceGetFirstChildFilterFactory(PKSDEVICE Device) +{ + return (PKSFILTERFACTORY)KsGetFirstChild((PVOID)Device); +} + +PKSFILTER __forceinline KsFilterFactoryGetFirstChildFilter(PKSFILTERFACTORY FilterFactory) +{ + return (PKSFILTER)KsGetFirstChild((PVOID)FilterFactory); +} + +KSDDKAPI ULONG NTAPI KsFilterGetChildPinCount(PKSFILTER Filter, ULONG PinId); +KSDDKAPI PKSPIN NTAPI KsFilterGetFirstChildPin(PKSFILTER Filter, ULONG PinId); +KSDDKAPI PVOID NTAPI KsGetNextSibling(PVOID Object); +KSDDKAPI PKSPIN NTAPI KsPinGetNextSiblingPin(PKSPIN Pin); + +PKSFILTERFACTORY __forceinline KsFilterFactoryGetNextSiblingFilterFactory(PKSFILTERFACTORY FilterFactory) +{ + return (PKSFILTERFACTORY)KsGetNextSibling((PVOID)FilterFactory); +} + +PKSFILTER __forceinline KsFilterGetNextSiblingFilter(PKSFILTER Filter) +{ + return (PKSFILTER)KsGetNextSibling((PVOID)Filter); +} + +KSDDKAPI PKSDEVICE NTAPI KsGetDevice(PVOID Object); + +PKSDEVICE __forceinline KsFilterFactoryGetDevice(PKSFILTERFACTORY FilterFactory) +{ + return KsGetDevice((PVOID)FilterFactory); +} + +PKSDEVICE __forceinline KsFilterGetDevice(PKSFILTER Filter) +{ + return KsGetDevice((PVOID)Filter); +} + +PKSDEVICE __forceinline KsPinGetDevice(PKSPIN Pin) +{ + return KsGetDevice((PVOID)Pin); +} + +KSDDKAPI PKSFILTER NTAPI KsGetFilterFromIrp(PIRP Irp); +KSDDKAPI PKSPIN NTAPI KsGetPinFromIrp(PIRP Irp); +KSDDKAPI ULONG NTAPI KsGetNodeIdFromIrp(PIRP Irp); +KSDDKAPI void NTAPI KsAcquireControl(PVOID Object); +KSDDKAPI void NTAPI KsReleaseControl(PVOID Object); + +void __forceinline KsFilterAcquireControl(PKSFILTER Filter) +{ + KsAcquireControl((PVOID)Filter); +} + +void __forceinline KsFilterReleaseControl(PKSFILTER Filter) +{ + KsReleaseControl((PVOID)Filter); +} + +void __forceinline KsPinAcquireControl(PKSPIN Pin) +{ + KsAcquireControl((PVOID)Pin); +} + +void __forceinline KsPinReleaseControl(PKSPIN Pin) +{ + KsReleaseControl((PVOID)Pin); +} + +KSDDKAPI NTSTATUS NTAPI KsAddItemToObjectBag(KSOBJECT_BAG ObjectBag, PVOID Item, PFNKSFREE Free); + +KSDDKAPI ULONG NTAPI KsRemoveItemFromObjectBag(KSOBJECT_BAG ObjectBag, PVOID Item, BOOLEAN Free); + + # define KsDiscard(Object, Pointer) \ + KsRemoveItemFromObjectBag((Object)->Bag, (PVOID)(Pointer), TRUE) + +KSDDKAPI NTSTATUS NTAPI KsAllocateObjectBag(PKSDEVICE Device, KSOBJECT_BAG* ObjectBag); +KSDDKAPI void NTAPI KsFreeObjectBag(KSOBJECT_BAG ObjectBag); + +KSDDKAPI NTSTATUS NTAPI KsCopyObjectBagItems(KSOBJECT_BAG ObjectBagDestination, KSOBJECT_BAG ObjectBagSource); + +KSDDKAPI NTSTATUS NTAPI _KsEdit(KSOBJECT_BAG ObjectBag, PVOID* PointerToPointerToItem, ULONG NewSize, ULONG OldSize, ULONG Tag); + + # define KsEdit(Object, PointerToPointer, Tag) \ + _KsEdit((Object)->Bag, (PVOID*)(PointerToPointer), \ + sizeof(**(PointerToPointer)), sizeof(**(PointerToPointer)), (Tag)) + + # define KsEditSized(Object, PointerToPointer, NewSize, OldSize, Tag) \ + _KsEdit((Object)->Bag, (PVOID*)(PointerToPointer), (NewSize), (OldSize), (Tag)) + +KSDDKAPI NTSTATUS NTAPI KsRegisterFilterWithNoKSPins(PDEVICE_OBJECT DeviceObject, const GUID* InterfaceClassGUID, ULONG PinCount, WINBOOL* PinDirection, KSPIN_MEDIUM* MediumList, GUID* CategoryList); + +KSDDKAPI NTSTATUS NTAPI KsFilterCreatePinFactory(PKSFILTER Filter, const KSPIN_DESCRIPTOR_EX* const PinDescriptor, PULONG PinID); + +KSDDKAPI NTSTATUS NTAPI KsFilterCreateNode(PKSFILTER Filter, const KSNODE_DESCRIPTOR* const NodeDescriptor, PULONG NodeID); + +KSDDKAPI NTSTATUS NTAPI KsFilterAddTopologyConnections(PKSFILTER Filter, ULONG NewConnectionsCount, const KSTOPOLOGY_CONNECTION* const NewTopologyConnections); + +KSDDKAPI NTSTATUS NTAPI KsPinGetConnectedPinInterface(PKSPIN Pin, const GUID* InterfaceId, PVOID* Interface); + +KSDDKAPI PFILE_OBJECT NTAPI KsPinGetConnectedPinFileObject(PKSPIN Pin); +KSDDKAPI PDEVICE_OBJECT NTAPI KsPinGetConnectedPinDeviceObject(PKSPIN Pin); + +KSDDKAPI NTSTATUS NTAPI KsPinGetConnectedFilterInterface(PKSPIN Pin, const GUID* InterfaceId, PVOID* Interface); + + # if defined(_UNKNOWN_H_) || defined(__IUnknown_INTERFACE_DEFINED__) +KSDDKAPI NTSTATUS NTAPI KsPinGetReferenceClockInterface(PKSPIN Pin, PIKSREFERENCECLOCK* Interface); + # endif /* defined(_UNKNOWN_H_) || defined(__IUnknown_INTERFACE_DEFINED__) */ + +KSDDKAPI VOID NTAPI KsPinSetPinClockTime(PKSPIN Pin, LONGLONG Time); + +KSDDKAPI NTSTATUS NTAPI KsPinSubmitFrame(PKSPIN Pin, PVOID Data, ULONG Size, PKSSTREAM_HEADER StreamHeader, PVOID Context); + +KSDDKAPI NTSTATUS NTAPI KsPinSubmitFrameMdl(PKSPIN Pin, PMDL Mdl, PKSSTREAM_HEADER StreamHeader, PVOID Context); + +KSDDKAPI void NTAPI KsPinRegisterFrameReturnCallback(PKSPIN Pin, PFNKSPINFRAMERETURN FrameReturn); + +KSDDKAPI void NTAPI KsPinRegisterIrpCompletionCallback(PKSPIN Pin, PFNKSPINIRPCOMPLETION IrpCompletion); + +KSDDKAPI void NTAPI KsPinRegisterHandshakeCallback(PKSPIN Pin, PFNKSPINHANDSHAKE Handshake); + +KSDDKAPI void NTAPI KsFilterRegisterPowerCallbacks(PKSFILTER Filter, PFNKSFILTERPOWER Sleep, PFNKSFILTERPOWER Wake); + +KSDDKAPI void NTAPI KsPinRegisterPowerCallbacks(PKSPIN Pin, PFNKSPINPOWER Sleep, PFNKSPINPOWER Wake); + + # if defined(_UNKNOWN_H_) || defined(__IUnknown_INTERFACE_DEFINED__) +KSDDKAPI PUNKNOWN NTAPI KsRegisterAggregatedClientUnknown(PVOID Object, PUNKNOWN ClientUnknown); + +KSDDKAPI PUNKNOWN NTAPI KsGetOuterUnknown(PVOID Object); + +PUNKNOWN __forceinline KsDeviceRegisterAggregatedClientUnknown(PKSDEVICE Device, PUNKNOWN ClientUnknown) +{ + return KsRegisterAggregatedClientUnknown((PVOID)Device, ClientUnknown); +} + +PUNKNOWN __forceinline KsDeviceGetOuterUnknown(PKSDEVICE Device) +{ + return KsGetOuterUnknown((PVOID)Device); +} + +PUNKNOWN __forceinline KsFilterFactoryRegisterAggregatedClientUnknown(PKSFILTERFACTORY FilterFactory, PUNKNOWN ClientUnknown) +{ + return KsRegisterAggregatedClientUnknown((PVOID)FilterFactory, ClientUnknown); +} + +PUNKNOWN __forceinline KsFilterFactoryGetOuterUnknown(PKSFILTERFACTORY FilterFactory) +{ + return KsGetOuterUnknown((PVOID)FilterFactory); +} + +PUNKNOWN __forceinline KsFilterRegisterAggregatedClientUnknown(PKSFILTER Filter, PUNKNOWN ClientUnknown) +{ + return KsRegisterAggregatedClientUnknown((PVOID)Filter, ClientUnknown); +} + +PUNKNOWN __forceinline KsFilterGetOuterUnknown(PKSFILTER Filter) +{ + return KsGetOuterUnknown((PVOID)Filter); +} + +PUNKNOWN __forceinline KsPinRegisterAggregatedClientUnknown(PKSPIN Pin, PUNKNOWN ClientUnknown) +{ + return KsRegisterAggregatedClientUnknown((PVOID)Pin, ClientUnknown); +} + +PUNKNOWN __forceinline KsPinGetOuterUnknown(PKSPIN Pin) +{ + return KsGetOuterUnknown((PVOID)Pin); +} + + # endif /* defined(_UNKNOWN_H_) || defined(__IUnknown_INTERFACE_DEFINED__) */ + +#else /* _NTDDK_ */ + + # ifndef KS_NO_CREATE_FUNCTIONS +KSDDKAPI DWORD WINAPI KsCreateAllocator(HANDLE ConnectionHandle, PKSALLOCATOR_FRAMING AllocatorFraming, PHANDLE AllocatorHandle); +KSDDKAPI DWORD NTAPI KsCreateClock(HANDLE ConnectionHandle, PKSCLOCK_CREATE ClockCreate, PHANDLE ClockHandle); +KSDDKAPI DWORD WINAPI KsCreatePin(HANDLE FilterHandle, PKSPIN_CONNECT Connect, ACCESS_MASK DesiredAccess, PHANDLE ConnectionHandle); +KSDDKAPI DWORD WINAPI KsCreateTopologyNode(HANDLE ParentHandle, PKSNODE_CREATE NodeCreate, ACCESS_MASK DesiredAccess, PHANDLE NodeHandle); + # endif + +#endif /* _NTDDK_ */ + +#ifdef __cplusplus +} +#endif + +#define DENY_USERMODE_ACCESS(pIrp, CompleteRequest) \ + if(pIrp->RequestorMode != KernelMode){ \ + pIrp->IoStatus.Information = 0; \ + pIrp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST; \ + if(CompleteRequest){ \ + IoCompleteRequest(pIrp, IO_NO_INCREMENT); } \ + return STATUS_INVALID_DEVICE_REQUEST; \ + } + +#endif /* _KS_ */ + diff --git a/include/ksmedia.h b/include/ksmedia.h new file mode 100644 index 00000000..a01823b9 --- /dev/null +++ b/include/ksmedia.h @@ -0,0 +1,4824 @@ +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the w64 mingw-runtime package. + */ +#if !defined(_KS_) + # warning ks.h must be included before ksmedia.h + # include "ks.h" +#endif + +#if __GNUC__ >= 3 + # pragma GCC system_header +#endif + +#if !defined(_KSMEDIA_) + # define _KSMEDIA_ + +typedef struct +{ + KSPROPERTY Property; + KSMULTIPLE_ITEM MultipleItem; +}KSMULTIPLE_DATA_PROP, * PKSMULTIPLE_DATA_PROP; + + # define STATIC_KSMEDIUMSETID_MidiBus \ + 0x05908040L, 0x3246, 0x11D0, 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00 +DEFINE_GUIDSTRUCT("05908040-3246-11D0-A5D6-28DB04C10000", KSMEDIUMSETID_MidiBus); + # define KSMEDIUMSETID_MidiBus DEFINE_GUIDNAMED(KSMEDIUMSETID_MidiBus) + + # define STATIC_KSMEDIUMSETID_VPBus \ + 0xA18C15ECL, 0xCE43, 0x11D0, 0xAB, 0xE7, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96 +DEFINE_GUIDSTRUCT("A18C15EC-CE43-11D0-ABE7-00A0C9223196", KSMEDIUMSETID_VPBus); + # define KSMEDIUMSETID_VPBus DEFINE_GUIDNAMED(KSMEDIUMSETID_VPBus) + + # define STATIC_KSINTERFACESETID_Media \ + 0x3A13EB40L, 0x30A7, 0x11D0, 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00 +DEFINE_GUIDSTRUCT("3A13EB40-30A7-11D0-A5D6-28DB04C10000", KSINTERFACESETID_Media); + # define KSINTERFACESETID_Media DEFINE_GUIDNAMED(KSINTERFACESETID_Media) + +typedef enum +{ + KSINTERFACE_MEDIA_MUSIC, + KSINTERFACE_MEDIA_WAVE_BUFFERED, + KSINTERFACE_MEDIA_WAVE_QUEUED +}KSINTERFACE_MEDIA; + + # ifndef INIT_USBAUDIO_MID + # define INIT_USBAUDIO_MID(guid, id) \ + { \ + (guid)->Data1 = 0x4e1cecd2 + (USHORT)(id); \ + (guid)->Data2 = 0x1679; \ + (guid)->Data3 = 0x463b; \ + (guid)->Data4[0] = 0xa7; \ + (guid)->Data4[1] = 0x2f; \ + (guid)->Data4[2] = 0xa5; \ + (guid)->Data4[3] = 0xbf; \ + (guid)->Data4[4] = 0x64; \ + (guid)->Data4[5] = 0xc8; \ + (guid)->Data4[6] = 0x6e; \ + (guid)->Data4[7] = 0xba; \ + } + # define EXTRACT_USBAUDIO_MID(guid) \ + (USHORT)((guid)->Data1 - 0x4e1cecd2) + # define DEFINE_USBAUDIO_MID_GUID(id) \ + 0x4e1cecd2 + (USHORT)(id), 0x1679, 0x463b, 0xa7, 0x2f, 0xa5, 0xbf, 0x64, 0xc8, 0x6e, 0xba + # define IS_COMPATIBLE_USBAUDIO_MID(guid) \ + (((guid)->Data1 >= 0x4e1cecd2) && \ + ((guid)->Data1 < 0x4e1cecd2 + 0xffff) && \ + ((guid)->Data2 == 0x1679) && \ + ((guid)->Data3 == 0x463b) && \ + ((guid)->Data4[0] == 0xa7) && \ + ((guid)->Data4[1] == 0x2f) && \ + ((guid)->Data4[2] == 0xa5) && \ + ((guid)->Data4[3] == 0xbf) && \ + ((guid)->Data4[4] == 0x64) && \ + ((guid)->Data4[5] == 0xc8) && \ + ((guid)->Data4[6] == 0x6e) && \ + ((guid)->Data4[7] == 0xba)) + # endif /* INIT_USBAUDIO_MID */ + + # ifndef INIT_USBAUDIO_PID + # define INIT_USBAUDIO_PID(guid, id) \ + { \ + (guid)->Data1 = 0xabcc5a5e + (USHORT)(id); \ + (guid)->Data2 = 0xc263; \ + (guid)->Data3 = 0x463b; \ + (guid)->Data4[0] = 0xa7; \ + (guid)->Data4[1] = 0x2f; \ + (guid)->Data4[2] = 0xa5; \ + (guid)->Data4[3] = 0xbf; \ + (guid)->Data4[4] = 0x64; \ + (guid)->Data4[5] = 0xc8; \ + (guid)->Data4[6] = 0x6e; \ + (guid)->Data4[7] = 0xba; \ + } + # define EXTRACT_USBAUDIO_PID(guid) \ + (USHORT)((guid)->Data1 - 0xabcc5a5e) + # define DEFINE_USBAUDIO_PID_GUID(id) \ + 0xabcc5a5e + (USHORT)(id), 0xc263, 0x463b, 0xa7, 0x2f, 0xa5, 0xbf, 0x64, 0xc8, 0x6e, 0xba + # define IS_COMPATIBLE_USBAUDIO_PID(guid) \ + (((guid)->Data1 >= 0xabcc5a5e) && \ + ((guid)->Data1 < 0xabcc5a5e + 0xffff) && \ + ((guid)->Data2 == 0xc263) && \ + ((guid)->Data3 == 0x463b) && \ + ((guid)->Data4[0] == 0xa7) && \ + ((guid)->Data4[1] == 0x2f) && \ + ((guid)->Data4[2] == 0xa5) && \ + ((guid)->Data4[3] == 0xbf) && \ + ((guid)->Data4[4] == 0x64) && \ + ((guid)->Data4[5] == 0xc8) && \ + ((guid)->Data4[6] == 0x6e) && \ + ((guid)->Data4[7] == 0xba)) + # endif /* INIT_USBAUDIO_PID */ + + # ifndef INIT_USBAUDIO_PRODUCT_NAME + # define INIT_USBAUDIO_PRODUCT_NAME(guid, vid, pid, strIndex) \ + { \ + (guid)->Data1 = 0XFC575048 + (USHORT)(vid); \ + (guid)->Data2 = 0x2E08 + (USHORT)(pid); \ + (guid)->Data3 = 0x463B + (USHORT)(strIndex); \ + (guid)->Data4[0] = 0xA7; \ + (guid)->Data4[1] = 0x2F; \ + (guid)->Data4[2] = 0xA5; \ + (guid)->Data4[3] = 0xBF; \ + (guid)->Data4[4] = 0x64; \ + (guid)->Data4[5] = 0xC8; \ + (guid)->Data4[6] = 0x6E; \ + (guid)->Data4[7] = 0xBA; \ + } + # define DEFINE_USBAUDIO_PRODUCT_NAME(vid, pid, strIndex) \ + 0xFC575048 + (USHORT)(vid), 0x2E08 + (USHORT)(pid), 0x463B + (USHORT)(strIndex), 0xA7, 0x2F, 0xA5, 0xBF, 0x64, 0xC8, 0x6E, 0xBA + # endif /* INIT_USBAUDIO_PRODUCT_NAME */ + + # define STATIC_KSCOMPONENTID_USBAUDIO \ + 0x8F1275F0, 0x26E9, 0x4264, 0xBA, 0x4D, 0x39, 0xFF, 0xF0, 0x1D, 0x94, 0xAA +DEFINE_GUIDSTRUCT("8F1275F0-26E9-4264-BA4D-39FFF01D94AA", KSCOMPONENTID_USBAUDIO); + # define KSCOMPONENTID_USBAUDIO DEFINE_GUIDNAMED(KSCOMPONENTID_USBAUDIO) + + # define INIT_USB_TERMINAL(guid, id) \ + { \ + (guid)->Data1 = 0xDFF219E0 + (USHORT)(id); \ + (guid)->Data2 = 0xF70F; \ + (guid)->Data3 = 0x11D0; \ + (guid)->Data4[0] = 0xb9; \ + (guid)->Data4[1] = 0x17; \ + (guid)->Data4[2] = 0x00; \ + (guid)->Data4[3] = 0xa0; \ + (guid)->Data4[4] = 0xc9; \ + (guid)->Data4[5] = 0x22; \ + (guid)->Data4[6] = 0x31; \ + (guid)->Data4[7] = 0x96; \ + } + # define EXTRACT_USB_TERMINAL(guid) \ + (USHORT)((guid)->Data1 - 0xDFF219E0) + # define DEFINE_USB_TERMINAL_GUID(id) \ + 0xDFF219E0 + (USHORT)(id), 0xF70F, 0x11D0, 0xB9, 0x17, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96 + + # define STATIC_KSNODETYPE_MICROPHONE \ + DEFINE_USB_TERMINAL_GUID(0x0201) +DEFINE_GUIDSTRUCT("DFF21BE1-F70F-11D0-B917-00A0C9223196", KSNODETYPE_MICROPHONE); + # define KSNODETYPE_MICROPHONE DEFINE_GUIDNAMED(KSNODETYPE_MICROPHONE) + + # define STATIC_KSNODETYPE_DESKTOP_MICROPHONE \ + DEFINE_USB_TERMINAL_GUID(0x0202) +DEFINE_GUIDSTRUCT("DFF21BE2-F70F-11D0-B917-00A0C9223196", KSNODETYPE_DESKTOP_MICROPHONE); + # define KSNODETYPE_DESKTOP_MICROPHONE DEFINE_GUIDNAMED(KSNODETYPE_DESKTOP_MICROPHONE) + + # define STATIC_KSNODETYPE_PERSONAL_MICROPHONE \ + DEFINE_USB_TERMINAL_GUID(0x0203) +DEFINE_GUIDSTRUCT("DFF21BE3-F70F-11D0-B917-00A0C9223196", KSNODETYPE_PERSONAL_MICROPHONE); + # define KSNODETYPE_PERSONAL_MICROPHONE DEFINE_GUIDNAMED(KSNODETYPE_PERSONAL_MICROPHONE) + + # define STATIC_KSNODETYPE_OMNI_DIRECTIONAL_MICROPHONE \ + DEFINE_USB_TERMINAL_GUID(0x0204) +DEFINE_GUIDSTRUCT("DFF21BE4-F70F-11D0-B917-00A0C9223196", KSNODETYPE_OMNI_DIRECTIONAL_MICROPHONE); + # define KSNODETYPE_OMNI_DIRECTIONAL_MICROPHONE DEFINE_GUIDNAMED(KSNODETYPE_OMNI_DIRECTIONAL_MICROPHONE) + + # define STATIC_KSNODETYPE_MICROPHONE_ARRAY \ + DEFINE_USB_TERMINAL_GUID(0x0205) +DEFINE_GUIDSTRUCT("DFF21BE5-F70F-11D0-B917-00A0C9223196", KSNODETYPE_MICROPHONE_ARRAY); + # define KSNODETYPE_MICROPHONE_ARRAY DEFINE_GUIDNAMED(KSNODETYPE_MICROPHONE_ARRAY) + + # define STATIC_KSNODETYPE_PROCESSING_MICROPHONE_ARRAY \ + DEFINE_USB_TERMINAL_GUID(0x0206) +DEFINE_GUIDSTRUCT("DFF21BE6-F70F-11D0-B917-00A0C9223196", KSNODETYPE_PROCESSING_MICROPHONE_ARRAY); + # define KSNODETYPE_PROCESSING_MICROPHONE_ARRAY DEFINE_GUIDNAMED(KSNODETYPE_PROCESSING_MICROPHONE_ARRAY) + + # define STATIC_KSCATEGORY_MICROPHONE_ARRAY_PROCESSOR \ + 0x830a44f2, 0xa32d, 0x476b, 0xbe, 0x97, 0x42, 0x84, 0x56, 0x73, 0xb3, 0x5a +DEFINE_GUIDSTRUCT("830a44f2-a32d-476b-be97-42845673b35a", KSCATEGORY_MICROPHONE_ARRAY_PROCESSOR); + # define KSCATEGORY_MICROPHONE_ARRAY_PROCESSOR DEFINE_GUIDNAMED(KSCATEGORY_MICROPHONE_ARRAY_PROCESSOR) + + # define STATIC_KSNODETYPE_SPEAKER \ + DEFINE_USB_TERMINAL_GUID(0x0301) +DEFINE_GUIDSTRUCT("DFF21CE1-F70F-11D0-B917-00A0C9223196", KSNODETYPE_SPEAKER); + # define KSNODETYPE_SPEAKER DEFINE_GUIDNAMED(KSNODETYPE_SPEAKER) + + # define STATIC_KSNODETYPE_HEADPHONES \ + DEFINE_USB_TERMINAL_GUID(0x0302) +DEFINE_GUIDSTRUCT("DFF21CE2-F70F-11D0-B917-00A0C9223196", KSNODETYPE_HEADPHONES); + # define KSNODETYPE_HEADPHONES DEFINE_GUIDNAMED(KSNODETYPE_HEADPHONES) + + # define STATIC_KSNODETYPE_HEAD_MOUNTED_DISPLAY_AUDIO \ + DEFINE_USB_TERMINAL_GUID(0x0303) +DEFINE_GUIDSTRUCT("DFF21CE3-F70F-11D0-B917-00A0C9223196", KSNODETYPE_HEAD_MOUNTED_DISPLAY_AUDIO); + # define KSNODETYPE_HEAD_MOUNTED_DISPLAY_AUDIO DEFINE_GUIDNAMED(KSNODETYPE_HEAD_MOUNTED_DISPLAY_AUDIO) + + # define STATIC_KSNODETYPE_DESKTOP_SPEAKER \ + DEFINE_USB_TERMINAL_GUID(0x0304) +DEFINE_GUIDSTRUCT("DFF21CE4-F70F-11D0-B917-00A0C9223196", KSNODETYPE_DESKTOP_SPEAKER); + # define KSNODETYPE_DESKTOP_SPEAKER DEFINE_GUIDNAMED(KSNODETYPE_DESKTOP_SPEAKER) + + # define STATIC_KSNODETYPE_ROOM_SPEAKER \ + DEFINE_USB_TERMINAL_GUID(0x0305) +DEFINE_GUIDSTRUCT("DFF21CE5-F70F-11D0-B917-00A0C9223196", KSNODETYPE_ROOM_SPEAKER); + # define KSNODETYPE_ROOM_SPEAKER DEFINE_GUIDNAMED(KSNODETYPE_ROOM_SPEAKER) + + # define STATIC_KSNODETYPE_COMMUNICATION_SPEAKER \ + DEFINE_USB_TERMINAL_GUID(0x0306) +DEFINE_GUIDSTRUCT("DFF21CE6-F70F-11D0-B917-00A0C9223196", KSNODETYPE_COMMUNICATION_SPEAKER); + # define KSNODETYPE_COMMUNICATION_SPEAKER DEFINE_GUIDNAMED(KSNODETYPE_COMMUNICATION_SPEAKER) + + # define STATIC_KSNODETYPE_LOW_FREQUENCY_EFFECTS_SPEAKER \ + DEFINE_USB_TERMINAL_GUID(0x0307) +DEFINE_GUIDSTRUCT("DFF21CE7-F70F-11D0-B917-00A0C9223196", KSNODETYPE_LOW_FREQUENCY_EFFECTS_SPEAKER); + # define KSNODETYPE_LOW_FREQUENCY_EFFECTS_SPEAKER DEFINE_GUIDNAMED(KSNODETYPE_LOW_FREQUENCY_EFFECTS_SPEAKER) + + # define STATIC_KSNODETYPE_HANDSET \ + DEFINE_USB_TERMINAL_GUID(0x0401) +DEFINE_GUIDSTRUCT("DFF21DE1-F70F-11D0-B917-00A0C9223196", KSNODETYPE_HANDSET); + # define KSNODETYPE_HANDSET DEFINE_GUIDNAMED(KSNODETYPE_HANDSET) + + # define STATIC_KSNODETYPE_HEADSET \ + DEFINE_USB_TERMINAL_GUID(0x0402) +DEFINE_GUIDSTRUCT("DFF21DE2-F70F-11D0-B917-00A0C9223196", KSNODETYPE_HEADSET); + # define KSNODETYPE_HEADSET DEFINE_GUIDNAMED(KSNODETYPE_HEADSET) + + # define STATIC_KSNODETYPE_SPEAKERPHONE_NO_ECHO_REDUCTION \ + DEFINE_USB_TERMINAL_GUID(0x0403) +DEFINE_GUIDSTRUCT("DFF21DE3-F70F-11D0-B917-00A0C9223196", KSNODETYPE_SPEAKERPHONE_NO_ECHO_REDUCTION); + # define KSNODETYPE_SPEAKERPHONE_NO_ECHO_REDUCTION DEFINE_GUIDNAMED(KSNODETYPE_SPEAKERPHONE_NO_ECHO_REDUCTION) + + # define STATIC_KSNODETYPE_ECHO_SUPPRESSING_SPEAKERPHONE \ + DEFINE_USB_TERMINAL_GUID(0x0404) +DEFINE_GUIDSTRUCT("DFF21DE4-F70F-11D0-B917-00A0C9223196", KSNODETYPE_ECHO_SUPPRESSING_SPEAKERPHONE); + # define KSNODETYPE_ECHO_SUPPRESSING_SPEAKERPHONE DEFINE_GUIDNAMED(KSNODETYPE_ECHO_SUPPRESSING_SPEAKERPHONE) + + # define STATIC_KSNODETYPE_ECHO_CANCELING_SPEAKERPHONE \ + DEFINE_USB_TERMINAL_GUID(0x0405) +DEFINE_GUIDSTRUCT("DFF21DE5-F70F-11D0-B917-00A0C9223196", KSNODETYPE_ECHO_CANCELING_SPEAKERPHONE); + # define KSNODETYPE_ECHO_CANCELING_SPEAKERPHONE DEFINE_GUIDNAMED(KSNODETYPE_ECHO_CANCELING_SPEAKERPHONE) + + # define STATIC_KSNODETYPE_PHONE_LINE \ + DEFINE_USB_TERMINAL_GUID(0x0501) +DEFINE_GUIDSTRUCT("DFF21EE1-F70F-11D0-B917-00A0C9223196", KSNODETYPE_PHONE_LINE); + # define KSNODETYPE_PHONE_LINE DEFINE_GUIDNAMED(KSNODETYPE_PHONE_LINE) + + # define STATIC_KSNODETYPE_TELEPHONE \ + DEFINE_USB_TERMINAL_GUID(0x0502) +DEFINE_GUIDSTRUCT("DFF21EE2-F70F-11D0-B917-00A0C9223196", KSNODETYPE_TELEPHONE); + # define KSNODETYPE_TELEPHONE DEFINE_GUIDNAMED(KSNODETYPE_TELEPHONE) + + # define STATIC_KSNODETYPE_DOWN_LINE_PHONE \ + DEFINE_USB_TERMINAL_GUID(0x0503) +DEFINE_GUIDSTRUCT("DFF21EE3-F70F-11D0-B917-00A0C9223196", KSNODETYPE_DOWN_LINE_PHONE); + # define KSNODETYPE_DOWN_LINE_PHONE DEFINE_GUIDNAMED(KSNODETYPE_DOWN_LINE_PHONE) + + # define STATIC_KSNODETYPE_ANALOG_CONNECTOR \ + DEFINE_USB_TERMINAL_GUID(0x601) +DEFINE_GUIDSTRUCT("DFF21FE1-F70F-11D0-B917-00A0C9223196", KSNODETYPE_ANALOG_CONNECTOR); + # define KSNODETYPE_ANALOG_CONNECTOR DEFINE_GUIDNAMED(KSNODETYPE_ANALOG_CONNECTOR) + + # define STATIC_KSNODETYPE_DIGITAL_AUDIO_INTERFACE \ + DEFINE_USB_TERMINAL_GUID(0x0602) +DEFINE_GUIDSTRUCT("DFF21FE2-F70F-11D0-B917-00A0C9223196", KSNODETYPE_DIGITAL_AUDIO_INTERFACE); + # define KSNODETYPE_DIGITAL_AUDIO_INTERFACE DEFINE_GUIDNAMED(KSNODETYPE_DIGITAL_AUDIO_INTERFACE) + + # define STATIC_KSNODETYPE_LINE_CONNECTOR \ + DEFINE_USB_TERMINAL_GUID(0x0603) +DEFINE_GUIDSTRUCT("DFF21FE3-F70F-11D0-B917-00A0C9223196", KSNODETYPE_LINE_CONNECTOR); + # define KSNODETYPE_LINE_CONNECTOR DEFINE_GUIDNAMED(KSNODETYPE_LINE_CONNECTOR) + + # define STATIC_KSNODETYPE_LEGACY_AUDIO_CONNECTOR \ + DEFINE_USB_TERMINAL_GUID(0x0604) +DEFINE_GUIDSTRUCT("DFF21FE4-F70F-11D0-B917-00A0C9223196", KSNODETYPE_LEGACY_AUDIO_CONNECTOR); + # define KSNODETYPE_LEGACY_AUDIO_CONNECTOR DEFINE_GUIDNAMED(KSNODETYPE_LEGACY_AUDIO_CONNECTOR) + + # define STATIC_KSNODETYPE_SPDIF_INTERFACE \ + DEFINE_USB_TERMINAL_GUID(0x0605) +DEFINE_GUIDSTRUCT("DFF21FE5-F70F-11D0-B917-00A0C9223196", KSNODETYPE_SPDIF_INTERFACE); + # define KSNODETYPE_SPDIF_INTERFACE DEFINE_GUIDNAMED(KSNODETYPE_SPDIF_INTERFACE) + + # define STATIC_KSNODETYPE_1394_DA_STREAM \ + DEFINE_USB_TERMINAL_GUID(0x0606) +DEFINE_GUIDSTRUCT("DFF21FE6-F70F-11D0-B917-00A0C9223196", KSNODETYPE_1394_DA_STREAM); + # define KSNODETYPE_1394_DA_STREAM DEFINE_GUIDNAMED(KSNODETYPE_1394_DA_STREAM) + + # define STATIC_KSNODETYPE_1394_DV_STREAM_SOUNDTRACK \ + DEFINE_USB_TERMINAL_GUID(0x0607) +DEFINE_GUIDSTRUCT("DFF21FE7-F70F-11D0-B917-00A0C9223196", KSNODETYPE_1394_DV_STREAM_SOUNDTRACK); + # define KSNODETYPE_1394_DV_STREAM_SOUNDTRACK DEFINE_GUIDNAMED(KSNODETYPE_1394_DV_STREAM_SOUNDTRACK) + + # define STATIC_KSNODETYPE_LEVEL_CALIBRATION_NOISE_SOURCE \ + DEFINE_USB_TERMINAL_GUID(0x0701) +DEFINE_GUIDSTRUCT("DFF220E1-F70F-11D0-B917-00A0C9223196", KSNODETYPE_LEVEL_CALIBRATION_NOISE_SOURCE); + # define KSNODETYPE_LEVEL_CALIBRATION_NOISE_SOURCE DEFINE_GUIDNAMED(KSNODETYPE_LEVEL_CALIBRATION_NOISE_SOURCE) + + # define STATIC_KSNODETYPE_EQUALIZATION_NOISE \ + DEFINE_USB_TERMINAL_GUID(0x0702) +DEFINE_GUIDSTRUCT("DFF220E2-F70F-11D0-B917-00A0C9223196", KSNODETYPE_EQUALIZATION_NOISE); + # define KSNODETYPE_EQUALIZATION_NOISE DEFINE_GUIDNAMED(KSNODETYPE_EQUALIZATION_NOISE) + + # define STATIC_KSNODETYPE_CD_PLAYER \ + DEFINE_USB_TERMINAL_GUID(0x0703) +DEFINE_GUIDSTRUCT("DFF220E3-F70F-11D0-B917-00A0C9223196", KSNODETYPE_CD_PLAYER); + # define KSNODETYPE_CD_PLAYER DEFINE_GUIDNAMED(KSNODETYPE_CD_PLAYER) + + # define STATIC_KSNODETYPE_DAT_IO_DIGITAL_AUDIO_TAPE \ + DEFINE_USB_TERMINAL_GUID(0x0704) +DEFINE_GUIDSTRUCT("DFF220E4-F70F-11D0-B917-00A0C9223196", KSNODETYPE_DAT_IO_DIGITAL_AUDIO_TAPE); + # define KSNODETYPE_DAT_IO_DIGITAL_AUDIO_TAPE DEFINE_GUIDNAMED(KSNODETYPE_DAT_IO_DIGITAL_AUDIO_TAPE) + + # define STATIC_KSNODETYPE_DCC_IO_DIGITAL_COMPACT_CASSETTE \ + DEFINE_USB_TERMINAL_GUID(0x0705) +DEFINE_GUIDSTRUCT("DFF220E5-F70F-11D0-B917-00A0C9223196", KSNODETYPE_DCC_IO_DIGITAL_COMPACT_CASSETTE); + # define KSNODETYPE_DCC_IO_DIGITAL_COMPACT_CASSETTE DEFINE_GUIDNAMED(KSNODETYPE_DCC_IO_DIGITAL_COMPACT_CASSETTE) + + # define STATIC_KSNODETYPE_MINIDISK \ + DEFINE_USB_TERMINAL_GUID(0x0706) +DEFINE_GUIDSTRUCT("DFF220E6-F70F-11D0-B917-00A0C9223196", KSNODETYPE_MINIDISK); + # define KSNODETYPE_MINIDISK DEFINE_GUIDNAMED(KSNODETYPE_MINIDISK) + + # define STATIC_KSNODETYPE_ANALOG_TAPE \ + DEFINE_USB_TERMINAL_GUID(0x0707) +DEFINE_GUIDSTRUCT("DFF220E7-F70F-11D0-B917-00A0C9223196", KSNODETYPE_ANALOG_TAPE); + # define KSNODETYPE_ANALOG_TAPE DEFINE_GUIDNAMED(KSNODETYPE_ANALOG_TAPE) + + # define STATIC_KSNODETYPE_PHONOGRAPH \ + DEFINE_USB_TERMINAL_GUID(0x0708) +DEFINE_GUIDSTRUCT("DFF220E8-F70F-11D0-B917-00A0C9223196", KSNODETYPE_PHONOGRAPH); + # define KSNODETYPE_PHONOGRAPH DEFINE_GUIDNAMED(KSNODETYPE_PHONOGRAPH) + + # define STATIC_KSNODETYPE_VCR_AUDIO \ + DEFINE_USB_TERMINAL_GUID(0x0708) +DEFINE_GUIDSTRUCT("DFF220E9-F70F-11D0-B917-00A0C9223196", KSNODETYPE_VCR_AUDIO); + # define KSNODETYPE_VCR_AUDIO DEFINE_GUIDNAMED(KSNODETYPE_VCR_AUDIO) + + # define STATIC_KSNODETYPE_VIDEO_DISC_AUDIO \ + DEFINE_USB_TERMINAL_GUID(0x070A) +DEFINE_GUIDSTRUCT("DFF220EA-F70F-11D0-B917-00A0C9223196", KSNODETYPE_VIDEO_DISC_AUDIO); + # define KSNODETYPE_VIDEO_DISC_AUDIO DEFINE_GUIDNAMED(KSNODETYPE_VIDEO_DISC_AUDIO) + + # define STATIC_KSNODETYPE_DVD_AUDIO \ + DEFINE_USB_TERMINAL_GUID(0x070B) +DEFINE_GUIDSTRUCT("DFF220EB-F70F-11D0-B917-00A0C9223196", KSNODETYPE_DVD_AUDIO); + # define KSNODETYPE_DVD_AUDIO DEFINE_GUIDNAMED(KSNODETYPE_DVD_AUDIO) + + # define STATIC_KSNODETYPE_TV_TUNER_AUDIO \ + DEFINE_USB_TERMINAL_GUID(0x070C) +DEFINE_GUIDSTRUCT("DFF220EC-F70F-11D0-B917-00A0C9223196", KSNODETYPE_TV_TUNER_AUDIO); + # define KSNODETYPE_TV_TUNER_AUDIO DEFINE_GUIDNAMED(KSNODETYPE_TV_TUNER_AUDIO) + + # define STATIC_KSNODETYPE_SATELLITE_RECEIVER_AUDIO \ + DEFINE_USB_TERMINAL_GUID(0x070D) +DEFINE_GUIDSTRUCT("DFF220ED-F70F-11D0-B917-00A0C9223196", KSNODETYPE_SATELLITE_RECEIVER_AUDIO); + # define KSNODETYPE_SATELLITE_RECEIVER_AUDIO DEFINE_GUIDNAMED(KSNODETYPE_SATELLITE_RECEIVER_AUDIO) + + # define STATIC_KSNODETYPE_CABLE_TUNER_AUDIO \ + DEFINE_USB_TERMINAL_GUID(0x070E) +DEFINE_GUIDSTRUCT("DFF220EE-F70F-11D0-B917-00A0C9223196", KSNODETYPE_CABLE_TUNER_AUDIO); + # define KSNODETYPE_CABLE_TUNER_AUDIO DEFINE_GUIDNAMED(KSNODETYPE_CABLE_TUNER_AUDIO) + + # define STATIC_KSNODETYPE_DSS_AUDIO \ + DEFINE_USB_TERMINAL_GUID(0x070F) +DEFINE_GUIDSTRUCT("DFF220EF-F70F-11D0-B917-00A0C9223196", KSNODETYPE_DSS_AUDIO); + # define KSNODETYPE_DSS_AUDIO DEFINE_GUIDNAMED(KSNODETYPE_DSS_AUDIO) + + # define STATIC_KSNODETYPE_RADIO_RECEIVER \ + DEFINE_USB_TERMINAL_GUID(0x0710) +DEFINE_GUIDSTRUCT("DFF220F0-F70F-11D0-B917-00A0C9223196", KSNODETYPE_RADIO_RECEIVER); + # define KSNODETYPE_RADIO_RECEIVER DEFINE_GUIDNAMED(KSNODETYPE_RADIO_RECEIVER) + + # define STATIC_KSNODETYPE_RADIO_TRANSMITTER \ + DEFINE_USB_TERMINAL_GUID(0x0711) +DEFINE_GUIDSTRUCT("DFF220F1-F70F-11D0-B917-00A0C9223196", KSNODETYPE_RADIO_TRANSMITTER); + # define KSNODETYPE_RADIO_TRANSMITTER DEFINE_GUIDNAMED(KSNODETYPE_RADIO_TRANSMITTER) + + # define STATIC_KSNODETYPE_MULTITRACK_RECORDER \ + DEFINE_USB_TERMINAL_GUID(0x0712) +DEFINE_GUIDSTRUCT("DFF220F2-F70F-11D0-B917-00A0C9223196", KSNODETYPE_MULTITRACK_RECORDER); + # define KSNODETYPE_MULTITRACK_RECORDER DEFINE_GUIDNAMED(KSNODETYPE_MULTITRACK_RECORDER) + + # define STATIC_KSNODETYPE_SYNTHESIZER \ + DEFINE_USB_TERMINAL_GUID(0x0713) +DEFINE_GUIDSTRUCT("DFF220F3-F70F-11D0-B917-00A0C9223196", KSNODETYPE_SYNTHESIZER); + # define KSNODETYPE_SYNTHESIZER DEFINE_GUIDNAMED(KSNODETYPE_SYNTHESIZER) + + # define STATIC_KSNODETYPE_SWSYNTH \ + 0x423274A0L, 0x8B81, 0x11D1, 0xA0, 0x50, 0x00, 0x00, 0xF8, 0x00, 0x47, 0x88 +DEFINE_GUIDSTRUCT("423274A0-8B81-11D1-A050-0000F8004788", KSNODETYPE_SWSYNTH); + # define KSNODETYPE_SWSYNTH DEFINE_GUIDNAMED(KSNODETYPE_SWSYNTH) + + # define STATIC_KSNODETYPE_SWMIDI \ + 0xCB9BEFA0L, 0xA251, 0x11D1, 0xA0, 0x50, 0x00, 0x00, 0xF8, 0x00, 0x47, 0x88 +DEFINE_GUIDSTRUCT("CB9BEFA0-A251-11D1-A050-0000F8004788", KSNODETYPE_SWMIDI); + # define KSNODETYPE_SWMIDI DEFINE_GUIDNAMED(KSNODETYPE_SWMIDI) + + # define STATIC_KSNODETYPE_DRM_DESCRAMBLE \ + 0xFFBB6E3FL, 0xCCFE, 0x4D84, 0x90, 0xD9, 0x42, 0x14, 0x18, 0xB0, 0x3A, 0x8E +DEFINE_GUIDSTRUCT("FFBB6E3F-CCFE-4D84-90D9-421418B03A8E", KSNODETYPE_DRM_DESCRAMBLE); + # define KSNODETYPE_DRM_DESCRAMBLE DEFINE_GUIDNAMED(KSNODETYPE_DRM_DESCRAMBLE) + + # define STATIC_KSCATEGORY_AUDIO \ + 0x6994AD04L, 0x93EF, 0x11D0, { 0xA3, 0xCC, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96 } +DEFINE_GUIDSTRUCT("6994AD04-93EF-11D0-A3CC-00A0C9223196", KSCATEGORY_AUDIO); + # define KSCATEGORY_AUDIO DEFINE_GUIDNAMED(KSCATEGORY_AUDIO) + + # define STATIC_KSCATEGORY_VIDEO \ + 0x6994AD05L, 0x93EF, 0x11D0, 0xA3, 0xCC, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96 +DEFINE_GUIDSTRUCT("6994AD05-93EF-11D0-A3CC-00A0C9223196", KSCATEGORY_VIDEO); + # define KSCATEGORY_VIDEO DEFINE_GUIDNAMED(KSCATEGORY_VIDEO) + + # define STATIC_KSCATEGORY_TEXT \ + 0x6994AD06L, 0x93EF, 0x11D0, 0xA3, 0xCC, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96 +DEFINE_GUIDSTRUCT("6994AD06-93EF-11D0-A3CC-00A0C9223196", KSCATEGORY_TEXT); + # define KSCATEGORY_TEXT DEFINE_GUIDNAMED(KSCATEGORY_TEXT) + + # define STATIC_KSCATEGORY_NETWORK \ + 0x67C9CC3CL, 0x69C4, 0x11D2, 0x87, 0x59, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96 +DEFINE_GUIDSTRUCT("67C9CC3C-69C4-11D2-8759-00A0C9223196", KSCATEGORY_NETWORK); + # define KSCATEGORY_NETWORK DEFINE_GUIDNAMED(KSCATEGORY_NETWORK) + + # define STATIC_KSCATEGORY_TOPOLOGY \ + 0xDDA54A40L, 0x1E4C, 0x11D1, 0xA0, 0x50, 0x40, 0x57, 0x05, 0xC1, 0x00, 0x00 +DEFINE_GUIDSTRUCT("DDA54A40-1E4C-11D1-A050-405705C10000", KSCATEGORY_TOPOLOGY); + # define KSCATEGORY_TOPOLOGY DEFINE_GUIDNAMED(KSCATEGORY_TOPOLOGY) + + # define STATIC_KSCATEGORY_VIRTUAL \ + 0x3503EAC4L, 0x1F26, 0x11D1, 0x8A, 0xB0, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96 +DEFINE_GUIDSTRUCT("3503EAC4-1F26-11D1-8AB0-00A0C9223196", KSCATEGORY_VIRTUAL); + # define KSCATEGORY_VIRTUAL DEFINE_GUIDNAMED(KSCATEGORY_VIRTUAL) + + # define STATIC_KSCATEGORY_ACOUSTIC_ECHO_CANCEL \ + 0xBF963D80L, 0xC559, 0x11D0, 0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1 +DEFINE_GUIDSTRUCT("BF963D80-C559-11D0-8A2B-00A0C9255AC1", KSCATEGORY_ACOUSTIC_ECHO_CANCEL); + # define KSCATEGORY_ACOUSTIC_ECHO_CANCEL DEFINE_GUIDNAMED(KSCATEGORY_ACOUSTIC_ECHO_CANCEL) + + # define STATIC_KSCATEGORY_SYSAUDIO \ + 0xA7C7A5B1L, 0x5AF3, 0x11D1, 0x9C, 0xED, 0x00, 0xA0, 0x24, 0xBF, 0x04, 0x07 +DEFINE_GUIDSTRUCT("A7C7A5B1-5AF3-11D1-9CED-00A024BF0407", KSCATEGORY_SYSAUDIO); + # define KSCATEGORY_SYSAUDIO DEFINE_GUIDNAMED(KSCATEGORY_SYSAUDIO) + + # define STATIC_KSCATEGORY_WDMAUD \ + 0x3E227E76L, 0x690D, 0x11D2, 0x81, 0x61, 0x00, 0x00, 0xF8, 0x77, 0x5B, 0xF1 +DEFINE_GUIDSTRUCT("3E227E76-690D-11D2-8161-0000F8775BF1", KSCATEGORY_WDMAUD); + # define KSCATEGORY_WDMAUD DEFINE_GUIDNAMED(KSCATEGORY_WDMAUD) + + # define STATIC_KSCATEGORY_AUDIO_GFX \ + 0x9BAF9572L, 0x340C, 0x11D3, 0xAB, 0xDC, 0x00, 0xA0, 0xC9, 0x0A, 0xB1, 0x6F +DEFINE_GUIDSTRUCT("9BAF9572-340C-11D3-ABDC-00A0C90AB16F", KSCATEGORY_AUDIO_GFX); + # define KSCATEGORY_AUDIO_GFX DEFINE_GUIDNAMED(KSCATEGORY_AUDIO_GFX) + + # define STATIC_KSCATEGORY_AUDIO_SPLITTER \ + 0x9EA331FAL, 0xB91B, 0x45F8, 0x92, 0x85, 0xBD, 0x2B, 0xC7, 0x7A, 0xFC, 0xDE +DEFINE_GUIDSTRUCT("9EA331FA-B91B-45F8-9285-BD2BC77AFCDE", KSCATEGORY_AUDIO_SPLITTER); + # define KSCATEGORY_AUDIO_SPLITTER DEFINE_GUIDNAMED(KSCATEGORY_AUDIO_SPLITTER) + + # define STATIC_KSCATEGORY_SYNTHESIZER STATIC_KSNODETYPE_SYNTHESIZER + # define KSCATEGORY_SYNTHESIZER KSNODETYPE_SYNTHESIZER + + # define STATIC_KSCATEGORY_DRM_DESCRAMBLE STATIC_KSNODETYPE_DRM_DESCRAMBLE + # define KSCATEGORY_DRM_DESCRAMBLE KSNODETYPE_DRM_DESCRAMBLE + + # define STATIC_KSCATEGORY_AUDIO_DEVICE \ + 0xFBF6F530L, 0x07B9, 0x11D2, 0xA7, 0x1E, 0x00, 0x00, 0xF8, 0x00, 0x47, 0x88 +DEFINE_GUIDSTRUCT("FBF6F530-07B9-11D2-A71E-0000F8004788", KSCATEGORY_AUDIO_DEVICE); + # define KSCATEGORY_AUDIO_DEVICE DEFINE_GUIDNAMED(KSCATEGORY_AUDIO_DEVICE) + + # define STATIC_KSCATEGORY_PREFERRED_WAVEOUT_DEVICE \ + 0xD6C5066EL, 0x72C1, 0x11D2, 0x97, 0x55, 0x00, 0x00, 0xF8, 0x00, 0x47, 0x88 +DEFINE_GUIDSTRUCT("D6C5066E-72C1-11D2-9755-0000F8004788", KSCATEGORY_PREFERRED_WAVEOUT_DEVICE); + # define KSCATEGORY_PREFERRED_WAVEOUT_DEVICE DEFINE_GUIDNAMED(KSCATEGORY_PREFERRED_WAVEOUT_DEVICE) + + # define STATIC_KSCATEGORY_PREFERRED_WAVEIN_DEVICE \ + 0xD6C50671L, 0x72C1, 0x11D2, 0x97, 0x55, 0x00, 0x00, 0xF8, 0x00, 0x47, 0x88 +DEFINE_GUIDSTRUCT("D6C50671-72C1-11D2-9755-0000F8004788", KSCATEGORY_PREFERRED_WAVEIN_DEVICE); + # define KSCATEGORY_PREFERRED_WAVEIN_DEVICE DEFINE_GUIDNAMED(KSCATEGORY_PREFERRED_WAVEIN_DEVICE) + + # define STATIC_KSCATEGORY_PREFERRED_MIDIOUT_DEVICE \ + 0xD6C50674L, 0x72C1, 0x11D2, 0x97, 0x55, 0x00, 0x00, 0xF8, 0x00, 0x47, 0x88 +DEFINE_GUIDSTRUCT("D6C50674-72C1-11D2-9755-0000F8004788", KSCATEGORY_PREFERRED_MIDIOUT_DEVICE); + # define KSCATEGORY_PREFERRED_MIDIOUT_DEVICE DEFINE_GUIDNAMED(KSCATEGORY_PREFERRED_MIDIOUT_DEVICE) + + # define STATIC_KSCATEGORY_WDMAUD_USE_PIN_NAME \ + 0x47A4FA20L, 0xA251, 0x11D1, 0xA0, 0x50, 0x00, 0x00, 0xF8, 0x00, 0x47, 0x88 +DEFINE_GUIDSTRUCT("47A4FA20-A251-11D1-A050-0000F8004788", KSCATEGORY_WDMAUD_USE_PIN_NAME); + # define KSCATEGORY_WDMAUD_USE_PIN_NAME DEFINE_GUIDNAMED(KSCATEGORY_WDMAUD_USE_PIN_NAME) + + # define STATIC_KSCATEGORY_ESCALANTE_PLATFORM_DRIVER \ + 0x74f3aea8L, 0x9768, 0x11d1, 0x8e, 0x07, 0x00, 0xa0, 0xc9, 0x5e, 0xc2, 0x2e +DEFINE_GUIDSTRUCT("74f3aea8-9768-11d1-8e07-00a0c95ec22e", KSCATEGORY_ESCALANTE_PLATFORM_DRIVER); + # define KSCATEGORY_ESCALANTE_PLATFORM_DRIVER DEFINE_GUIDNAMED(KSCATEGORY_ESCALANTE_PLATFORM_DRIVER) + + # define STATIC_KSDATAFORMAT_TYPE_VIDEO \ + 0x73646976L, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 +DEFINE_GUIDSTRUCT("73646976-0000-0010-8000-00aa00389b71", KSDATAFORMAT_TYPE_VIDEO); + # define KSDATAFORMAT_TYPE_VIDEO DEFINE_GUIDNAMED(KSDATAFORMAT_TYPE_VIDEO) + + # define STATIC_KSDATAFORMAT_TYPE_AUDIO \ + 0x73647561L, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 +DEFINE_GUIDSTRUCT("73647561-0000-0010-8000-00aa00389b71", KSDATAFORMAT_TYPE_AUDIO); + # define KSDATAFORMAT_TYPE_AUDIO DEFINE_GUIDNAMED(KSDATAFORMAT_TYPE_AUDIO) + + # define STATIC_KSDATAFORMAT_TYPE_TEXT \ + 0x73747874L, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 +DEFINE_GUIDSTRUCT("73747874-0000-0010-8000-00aa00389b71", KSDATAFORMAT_TYPE_TEXT); + # define KSDATAFORMAT_TYPE_TEXT DEFINE_GUIDNAMED(KSDATAFORMAT_TYPE_TEXT) + + # if !defined(DEFINE_WAVEFORMATEX_GUID) + # define DEFINE_WAVEFORMATEX_GUID(x) \ + (USHORT)(x), 0x0000, 0x0010, { 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 } + # endif + + # define STATIC_KSDATAFORMAT_SUBTYPE_WAVEFORMATEX \ + 0x00000000L, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 +DEFINE_GUIDSTRUCT("00000000-0000-0010-8000-00aa00389b71", KSDATAFORMAT_SUBTYPE_WAVEFORMATEX); + # define KSDATAFORMAT_SUBTYPE_WAVEFORMATEX DEFINE_GUIDNAMED(KSDATAFORMAT_SUBTYPE_WAVEFORMATEX) + + # define INIT_WAVEFORMATEX_GUID(Guid, x) \ + { \ + *(Guid) = KSDATAFORMAT_SUBTYPE_WAVEFORMATEX; \ + (Guid)->Data1 = (USHORT)(x); \ + } + + # define EXTRACT_WAVEFORMATEX_ID(Guid) \ + (USHORT)((Guid)->Data1) + + # define IS_VALID_WAVEFORMATEX_GUID(Guid) \ + (!memcmp(((PUSHORT)&KSDATAFORMAT_SUBTYPE_WAVEFORMATEX) + 1, ((PUSHORT)(Guid)) + 1, sizeof(GUID) - sizeof(USHORT))) + + # ifndef INIT_MMREG_MID + # define INIT_MMREG_MID(guid, id) \ + { \ + (guid)->Data1 = 0xd5a47fa7 + (USHORT)(id); \ + (guid)->Data2 = 0x6d98; \ + (guid)->Data3 = 0x11d1; \ + (guid)->Data4[0] = 0xa2; \ + (guid)->Data4[1] = 0x1a; \ + (guid)->Data4[2] = 0x00; \ + (guid)->Data4[3] = 0xa0; \ + (guid)->Data4[4] = 0xc9; \ + (guid)->Data4[5] = 0x22; \ + (guid)->Data4[6] = 0x31; \ + (guid)->Data4[7] = 0x96; \ + } + # define EXTRACT_MMREG_MID(guid) \ + (USHORT)((guid)->Data1 - 0xd5a47fa7) + # define DEFINE_MMREG_MID_GUID(id) \ + 0xd5a47fa7 + (USHORT)(id), 0x6d98, 0x11d1, 0xa2, 0x1a, 0x00, 0xa0, 0xc9, 0x22, 0x31, 0x96 + + # define IS_COMPATIBLE_MMREG_MID(guid) \ + (((guid)->Data1 >= 0xd5a47fa7) && \ + ((guid)->Data1 < 0xd5a47fa7 + 0xffff) && \ + ((guid)->Data2 == 0x6d98) && \ + ((guid)->Data3 == 0x11d1) && \ + ((guid)->Data4[0] == 0xa2) && \ + ((guid)->Data4[1] == 0x1a) && \ + ((guid)->Data4[2] == 0x00) && \ + ((guid)->Data4[3] == 0xa0) && \ + ((guid)->Data4[4] == 0xc9) && \ + ((guid)->Data4[5] == 0x22) && \ + ((guid)->Data4[6] == 0x31) && \ + ((guid)->Data4[7] == 0x96)) + # endif /* INIT_MMREG_MID */ + + # ifndef INIT_MMREG_PID + # define INIT_MMREG_PID(guid, id) \ + { \ + (guid)->Data1 = 0xe36dc2ac + (USHORT)(id); \ + (guid)->Data2 = 0x6d9a; \ + (guid)->Data3 = 0x11d1; \ + (guid)->Data4[0] = 0xa2; \ + (guid)->Data4[1] = 0x1a; \ + (guid)->Data4[2] = 0x00; \ + (guid)->Data4[3] = 0xa0; \ + (guid)->Data4[4] = 0xc9; \ + (guid)->Data4[5] = 0x22; \ + (guid)->Data4[6] = 0x31; \ + (guid)->Data4[7] = 0x96; \ + } + # define EXTRACT_MMREG_PID(guid) \ + (USHORT)((guid)->Data1 - 0xe36dc2ac) + # define DEFINE_MMREG_PID_GUID(id) \ + 0xe36dc2ac + (USHORT)(id), 0x6d9a, 0x11d1, 0xa2, 0x1a, 0x00, 0xa0, 0xc9, 0x22, 0x31, 0x96 + + # define IS_COMPATIBLE_MMREG_PID(guid) \ + (((guid)->Data1 >= 0xe36dc2ac) && \ + ((guid)->Data1 < 0xe36dc2ac + 0xffff) && \ + ((guid)->Data2 == 0x6d9a) && \ + ((guid)->Data3 == 0x11d1) && \ + ((guid)->Data4[0] == 0xa2) && \ + ((guid)->Data4[1] == 0x1a) && \ + ((guid)->Data4[2] == 0x00) && \ + ((guid)->Data4[3] == 0xa0) && \ + ((guid)->Data4[4] == 0xc9) && \ + ((guid)->Data4[5] == 0x22) && \ + ((guid)->Data4[6] == 0x31) && \ + ((guid)->Data4[7] == 0x96)) + # endif /* INIT_MMREG_PID */ + + # define STATIC_KSDATAFORMAT_SUBTYPE_ANALOG \ + 0x6dba3190L, 0x67bd, 0x11cf, 0xa0, 0xf7, 0x00, 0x20, 0xaf, 0xd1, 0x56, 0xe4 +DEFINE_GUIDSTRUCT("6dba3190-67bd-11cf-a0f7-0020afd156e4", KSDATAFORMAT_SUBTYPE_ANALOG); + # define KSDATAFORMAT_SUBTYPE_ANALOG DEFINE_GUIDNAMED(KSDATAFORMAT_SUBTYPE_ANALOG) + + # define STATIC_KSDATAFORMAT_SUBTYPE_PCM \ + DEFINE_WAVEFORMATEX_GUID(WAVE_FORMAT_PCM) +DEFINE_GUIDSTRUCT("00000001-0000-0010-8000-00aa00389b71", KSDATAFORMAT_SUBTYPE_PCM); + # define KSDATAFORMAT_SUBTYPE_PCM DEFINE_GUIDNAMED(KSDATAFORMAT_SUBTYPE_PCM) + + # ifdef _INC_MMREG + # define STATIC_KSDATAFORMAT_SUBTYPE_IEEE_FLOAT \ + DEFINE_WAVEFORMATEX_GUID(WAVE_FORMAT_IEEE_FLOAT) +DEFINE_GUIDSTRUCT("00000003-0000-0010-8000-00aa00389b71", KSDATAFORMAT_SUBTYPE_IEEE_FLOAT); + # define KSDATAFORMAT_SUBTYPE_IEEE_FLOAT DEFINE_GUIDNAMED(KSDATAFORMAT_SUBTYPE_IEEE_FLOAT) + + # define STATIC_KSDATAFORMAT_SUBTYPE_DRM \ + DEFINE_WAVEFORMATEX_GUID(WAVE_FORMAT_DRM) +DEFINE_GUIDSTRUCT("00000009-0000-0010-8000-00aa00389b71", KSDATAFORMAT_SUBTYPE_DRM); + # define KSDATAFORMAT_SUBTYPE_DRM DEFINE_GUIDNAMED(KSDATAFORMAT_SUBTYPE_DRM) + + # define STATIC_KSDATAFORMAT_SUBTYPE_ALAW \ + DEFINE_WAVEFORMATEX_GUID(WAVE_FORMAT_ALAW) +DEFINE_GUIDSTRUCT("00000006-0000-0010-8000-00aa00389b71", KSDATAFORMAT_SUBTYPE_ALAW); + # define KSDATAFORMAT_SUBTYPE_ALAW DEFINE_GUIDNAMED(KSDATAFORMAT_SUBTYPE_ALAW) + + # define STATIC_KSDATAFORMAT_SUBTYPE_MULAW \ + DEFINE_WAVEFORMATEX_GUID(WAVE_FORMAT_MULAW) +DEFINE_GUIDSTRUCT("00000007-0000-0010-8000-00aa00389b71", KSDATAFORMAT_SUBTYPE_MULAW); + # define KSDATAFORMAT_SUBTYPE_MULAW DEFINE_GUIDNAMED(KSDATAFORMAT_SUBTYPE_MULAW) + + # define STATIC_KSDATAFORMAT_SUBTYPE_ADPCM \ + DEFINE_WAVEFORMATEX_GUID(WAVE_FORMAT_ADPCM) +DEFINE_GUIDSTRUCT("00000002-0000-0010-8000-00aa00389b71", KSDATAFORMAT_SUBTYPE_ADPCM); + # define KSDATAFORMAT_SUBTYPE_ADPCM DEFINE_GUIDNAMED(KSDATAFORMAT_SUBTYPE_ADPCM) + + # define STATIC_KSDATAFORMAT_SUBTYPE_MPEG \ + DEFINE_WAVEFORMATEX_GUID(WAVE_FORMAT_MPEG) +DEFINE_GUIDSTRUCT("00000050-0000-0010-8000-00aa00389b71", KSDATAFORMAT_SUBTYPE_MPEG); + # define KSDATAFORMAT_SUBTYPE_MPEG DEFINE_GUIDNAMED(KSDATAFORMAT_SUBTYPE_MPEG) + # endif /* _INC_MMREG */ + + # define STATIC_KSDATAFORMAT_SPECIFIER_VC_ID \ + 0xAD98D184L, 0xAAC3, 0x11D0, 0xA4, 0x1C, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96 +DEFINE_GUIDSTRUCT("AD98D184-AAC3-11D0-A41C-00A0C9223196", KSDATAFORMAT_SPECIFIER_VC_ID); + # define KSDATAFORMAT_SPECIFIER_VC_ID DEFINE_GUIDNAMED(KSDATAFORMAT_SPECIFIER_VC_ID) + + # define STATIC_KSDATAFORMAT_SPECIFIER_WAVEFORMATEX \ + 0x05589f81L, 0xc356, 0x11ce, 0xbf, 0x01, 0x00, 0xaa, 0x00, 0x55, 0x59, 0x5a +DEFINE_GUIDSTRUCT("05589f81-c356-11ce-bf01-00aa0055595a", KSDATAFORMAT_SPECIFIER_WAVEFORMATEX); + # define KSDATAFORMAT_SPECIFIER_WAVEFORMATEX DEFINE_GUIDNAMED(KSDATAFORMAT_SPECIFIER_WAVEFORMATEX) + + # define STATIC_KSDATAFORMAT_SPECIFIER_DSOUND \ + 0x518590a2L, 0xa184, 0x11d0, 0x85, 0x22, 0x00, 0xc0, 0x4f, 0xd9, 0xba, 0xf3 +DEFINE_GUIDSTRUCT("518590a2-a184-11d0-8522-00c04fd9baf3", KSDATAFORMAT_SPECIFIER_DSOUND); + # define KSDATAFORMAT_SPECIFIER_DSOUND DEFINE_GUIDNAMED(KSDATAFORMAT_SPECIFIER_DSOUND) + + # if defined(_INC_MMSYSTEM) || defined(_INC_MMREG) || 1 + # if !defined(PACK_PRAGMAS_NOT_SUPPORTED) + # include + # endif +typedef struct +{ + KSDATAFORMAT DataFormat; + WAVEFORMATEX WaveFormatEx; +}KSDATAFORMAT_WAVEFORMATEX, * PKSDATAFORMAT_WAVEFORMATEX; + + # ifndef _WAVEFORMATEXTENSIBLE_ + # define _WAVEFORMATEXTENSIBLE_ +typedef struct +{ + WAVEFORMATEX Format; + union + { + WORD wValidBitsPerSample; + WORD wSamplesPerBlock; + WORD wReserved; + }Samples; + DWORD dwChannelMask; + + GUID SubFormat; +}WAVEFORMATEXTENSIBLE, * PWAVEFORMATEXTENSIBLE; + # endif /* _WAVEFORMATEXTENSIBLE_ */ + + # if !defined(WAVE_FORMAT_EXTENSIBLE) + # define WAVE_FORMAT_EXTENSIBLE 0xFFFE + # endif + +typedef struct +{ + ULONG Flags; + ULONG Control; + WAVEFORMATEX WaveFormatEx; +}KSDSOUND_BUFFERDESC, * PKSDSOUND_BUFFERDESC; + +typedef struct +{ + KSDATAFORMAT DataFormat; + KSDSOUND_BUFFERDESC BufferDesc; +}KSDATAFORMAT_DSOUND, * PKSDATAFORMAT_DSOUND; + + # if !defined(PACK_PRAGMAS_NOT_SUPPORTED) + # include + # endif + # endif /* defined(_INC_MMSYSTEM) || defined(_INC_MMREG) */ + + # define KSDSOUND_BUFFER_PRIMARY 0x00000001 + # define KSDSOUND_BUFFER_STATIC 0x00000002 + # define KSDSOUND_BUFFER_LOCHARDWARE 0x00000004 + # define KSDSOUND_BUFFER_LOCSOFTWARE 0x00000008 + + # define KSDSOUND_BUFFER_CTRL_3D 0x00000001 + # define KSDSOUND_BUFFER_CTRL_FREQUENCY 0x00000002 + # define KSDSOUND_BUFFER_CTRL_PAN 0x00000004 + # define KSDSOUND_BUFFER_CTRL_VOLUME 0x00000008 + # define KSDSOUND_BUFFER_CTRL_POSITIONNOTIFY 0x00000010 + +typedef struct +{ + DWORDLONG PlayOffset; + DWORDLONG WriteOffset; +}KSAUDIO_POSITION, * PKSAUDIO_POSITION; + +typedef struct _DS3DVECTOR +{ + __MINGW_EXTENSION union + { + FLOAT x; + FLOAT dvX; + }; + __MINGW_EXTENSION union + { + FLOAT y; + FLOAT dvY; + }; + __MINGW_EXTENSION union + { + FLOAT z; + FLOAT dvZ; + }; +}DS3DVECTOR, * PDS3DVECTOR; + + # define STATIC_KSPROPSETID_DirectSound3DListener \ + 0x437b3414L, 0xd060, 0x11d0, 0x85, 0x83, 0x00, 0xc0, 0x4f, 0xd9, 0xba, 0xf3 +DEFINE_GUIDSTRUCT("437b3414-d060-11d0-8583-00c04fd9baf3", KSPROPSETID_DirectSound3DListener); + # define KSPROPSETID_DirectSound3DListener DEFINE_GUIDNAMED(KSPROPSETID_DirectSound3DListener) + +typedef enum +{ + KSPROPERTY_DIRECTSOUND3DLISTENER_ALL, + KSPROPERTY_DIRECTSOUND3DLISTENER_POSITION, + KSPROPERTY_DIRECTSOUND3DLISTENER_VELOCITY, + KSPROPERTY_DIRECTSOUND3DLISTENER_ORIENTATION, + KSPROPERTY_DIRECTSOUND3DLISTENER_DISTANCEFACTOR, + KSPROPERTY_DIRECTSOUND3DLISTENER_ROLLOFFFACTOR, + KSPROPERTY_DIRECTSOUND3DLISTENER_DOPPLERFACTOR, + KSPROPERTY_DIRECTSOUND3DLISTENER_BATCH, + KSPROPERTY_DIRECTSOUND3DLISTENER_ALLOCATION +}KSPROPERTY_DIRECTSOUND3DLISTENER; + +typedef struct +{ + DS3DVECTOR Position; + DS3DVECTOR Velocity; + DS3DVECTOR OrientFront; + DS3DVECTOR OrientTop; + FLOAT DistanceFactor; + FLOAT RolloffFactor; + FLOAT DopplerFactor; +}KSDS3D_LISTENER_ALL, * PKSDS3D_LISTENER_ALL; + +typedef struct +{ + DS3DVECTOR Front; + DS3DVECTOR Top; +}KSDS3D_LISTENER_ORIENTATION, * PKSDS3D_LISTENER_ORIENTATION; + + # define STATIC_KSPROPSETID_DirectSound3DBuffer \ + 0x437b3411L, 0xd060, 0x11d0, 0x85, 0x83, 0x00, 0xc0, 0x4f, 0xd9, 0xba, 0xf3 +DEFINE_GUIDSTRUCT("437b3411-d060-11d0-8583-00c04fd9baf3", KSPROPSETID_DirectSound3DBuffer); + # define KSPROPSETID_DirectSound3DBuffer DEFINE_GUIDNAMED(KSPROPSETID_DirectSound3DBuffer) + +typedef enum +{ + KSPROPERTY_DIRECTSOUND3DBUFFER_ALL, + KSPROPERTY_DIRECTSOUND3DBUFFER_POSITION, + KSPROPERTY_DIRECTSOUND3DBUFFER_VELOCITY, + KSPROPERTY_DIRECTSOUND3DBUFFER_CONEANGLES, + KSPROPERTY_DIRECTSOUND3DBUFFER_CONEORIENTATION, + KSPROPERTY_DIRECTSOUND3DBUFFER_CONEOUTSIDEVOLUME, + KSPROPERTY_DIRECTSOUND3DBUFFER_MINDISTANCE, + KSPROPERTY_DIRECTSOUND3DBUFFER_MAXDISTANCE, + KSPROPERTY_DIRECTSOUND3DBUFFER_MODE +}KSPROPERTY_DIRECTSOUND3DBUFFER; + +typedef struct +{ + DS3DVECTOR Position; + DS3DVECTOR Velocity; + ULONG InsideConeAngle; + ULONG OutsideConeAngle; + DS3DVECTOR ConeOrientation; + LONG ConeOutsideVolume; + FLOAT MinDistance; + FLOAT MaxDistance; + ULONG Mode; +}KSDS3D_BUFFER_ALL, * PKSDS3D_BUFFER_ALL; + +typedef struct +{ + ULONG InsideConeAngle; + ULONG OutsideConeAngle; +}KSDS3D_BUFFER_CONE_ANGLES, * PKSDS3D_BUFFER_CONE_ANGLES; + + # define KSAUDIO_STEREO_SPEAKER_GEOMETRY_HEADPHONE (-1) + # define KSAUDIO_STEREO_SPEAKER_GEOMETRY_MIN 5 + # define KSAUDIO_STEREO_SPEAKER_GEOMETRY_NARROW 10 + # define KSAUDIO_STEREO_SPEAKER_GEOMETRY_WIDE 20 + # define KSAUDIO_STEREO_SPEAKER_GEOMETRY_MAX 180 + + # define KSDSOUND_3D_MODE_NORMAL 0x00000000 + # define KSDSOUND_3D_MODE_HEADRELATIVE 0x00000001 + # define KSDSOUND_3D_MODE_DISABLE 0x00000002 + + # define KSDSOUND_BUFFER_CTRL_HRTF_3D 0x40000000 + +typedef struct +{ + ULONG Size; + ULONG Enabled; + WINBOOL SwapChannels; + WINBOOL ZeroAzimuth; + WINBOOL CrossFadeOutput; + ULONG FilterSize; +}KSDS3D_HRTF_PARAMS_MSG, * PKSDS3D_HRTF_PARAMS_MSG; + +typedef enum +{ + FULL_FILTER, + LIGHT_FILTER, + KSDS3D_FILTER_QUALITY_COUNT +}KSDS3D_HRTF_FILTER_QUALITY; + +typedef struct +{ + ULONG Size; + KSDS3D_HRTF_FILTER_QUALITY Quality; + FLOAT SampleRate; + ULONG MaxFilterSize; + ULONG FilterTransientMuteLength; + ULONG FilterOverlapBufferLength; + ULONG OutputOverlapBufferLength; + ULONG Reserved; +}KSDS3D_HRTF_INIT_MSG, * PKSDS3D_HRTF_INIT_MSG; + +typedef enum +{ + FLOAT_COEFF, + SHORT_COEFF, + KSDS3D_COEFF_COUNT +}KSDS3D_HRTF_COEFF_FORMAT; + +typedef enum +{ + DIRECT_FORM, + CASCADE_FORM, + KSDS3D_FILTER_METHOD_COUNT +}KSDS3D_HRTF_FILTER_METHOD; + +typedef enum +{ + DS3D_HRTF_VERSION_1 +}KSDS3D_HRTF_FILTER_VERSION; + +typedef struct +{ + KSDS3D_HRTF_FILTER_METHOD FilterMethod; + KSDS3D_HRTF_COEFF_FORMAT CoeffFormat; + KSDS3D_HRTF_FILTER_VERSION Version; + ULONG Reserved; +}KSDS3D_HRTF_FILTER_FORMAT_MSG, * PKSDS3D_HRTF_FILTER_FORMAT_MSG; + + # define STATIC_KSPROPSETID_Hrtf3d \ + 0xb66decb0L, 0xa083, 0x11d0, 0x85, 0x1e, 0x00, 0xc0, 0x4f, 0xd9, 0xba, 0xf3 +DEFINE_GUIDSTRUCT("b66decb0-a083-11d0-851e-00c04fd9baf3", KSPROPSETID_Hrtf3d); + # define KSPROPSETID_Hrtf3d DEFINE_GUIDNAMED(KSPROPSETID_Hrtf3d) + +typedef enum +{ + KSPROPERTY_HRTF3D_PARAMS = 0, + KSPROPERTY_HRTF3D_INITIALIZE, + KSPROPERTY_HRTF3D_FILTER_FORMAT +}KSPROPERTY_HRTF3D; + +typedef struct +{ + LONG Channel; + FLOAT VolSmoothScale; + FLOAT TotalDryAttenuation; + FLOAT TotalWetAttenuation; + LONG SmoothFrequency; + LONG Delay; +}KSDS3D_ITD_PARAMS, * PKSDS3D_ITD_PARAMS; + +typedef struct +{ + ULONG Enabled; + KSDS3D_ITD_PARAMS LeftParams; + KSDS3D_ITD_PARAMS RightParams; + ULONG Reserved; +}KSDS3D_ITD_PARAMS_MSG, * PKSDS3D_ITD_PARAMS_MSG; + + # define STATIC_KSPROPSETID_Itd3d \ + 0x6429f090L, 0x9fd9, 0x11d0, 0xa7, 0x5b, 0x00, 0xa0, 0xc9, 0x03, 0x65, 0xe3 +DEFINE_GUIDSTRUCT("6429f090-9fd9-11d0-a75b-00a0c90365e3", KSPROPSETID_Itd3d); + # define KSPROPSETID_Itd3d DEFINE_GUIDNAMED(KSPROPSETID_Itd3d) + +typedef enum +{ + KSPROPERTY_ITD3D_PARAMS = 0 +}KSPROPERTY_ITD3D; + +typedef struct +{ + KSDATARANGE DataRange; + ULONG MaximumChannels; + ULONG MinimumBitsPerSample; + ULONG MaximumBitsPerSample; + ULONG MinimumSampleFrequency; + ULONG MaximumSampleFrequency; +}KSDATARANGE_AUDIO, * PKSDATARANGE_AUDIO; + + # define STATIC_KSDATAFORMAT_SUBTYPE_RIFF \ + 0x4995DAEEL, 0x9EE6, 0x11D0, 0xA4, 0x0E, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96 +DEFINE_GUIDSTRUCT("4995DAEE-9EE6-11D0-A40E-00A0C9223196", KSDATAFORMAT_SUBTYPE_RIFF); + # define KSDATAFORMAT_SUBTYPE_RIFF DEFINE_GUIDNAMED(KSDATAFORMAT_SUBTYPE_RIFF) + + # define STATIC_KSDATAFORMAT_SUBTYPE_RIFFWAVE \ + 0xe436eb8bL, 0x524f, 0x11ce, 0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70 +DEFINE_GUIDSTRUCT("e436eb8b-524f-11ce-9f53-0020af0ba770", KSDATAFORMAT_SUBTYPE_RIFFWAVE); + # define KSDATAFORMAT_SUBTYPE_RIFFWAVE DEFINE_GUIDNAMED(KSDATAFORMAT_SUBTYPE_RIFFWAVE) + + # define STATIC_KSPROPSETID_Bibliographic \ + 0x07BA150EL, 0xE2B1, 0x11D0, 0xAC, 0x17, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96 +DEFINE_GUIDSTRUCT("07BA150E-E2B1-11D0-AC17-00A0C9223196", KSPROPSETID_Bibliographic); + # define KSPROPSETID_Bibliographic DEFINE_GUIDNAMED(KSPROPSETID_Bibliographic) + + # define SEB_MK_FOURCC(a, b, c, d) ((a << 24) | (b << 16) | (c << 8) | (d << 0)) + +typedef enum +{ + KSPROPERTY_BIBLIOGRAPHIC_LEADER = SEB_MK_FOURCC('R', 'D', 'L', ' '), + KSPROPERTY_BIBLIOGRAPHIC_LCCN = SEB_MK_FOURCC('0', '1', '0', ' '), + KSPROPERTY_BIBLIOGRAPHIC_ISBN = SEB_MK_FOURCC('0', '2', '0', ' '), + KSPROPERTY_BIBLIOGRAPHIC_ISSN = SEB_MK_FOURCC('2', '2', '0', ' '), + KSPROPERTY_BIBLIOGRAPHIC_CATALOGINGSOURCE = SEB_MK_FOURCC('0', '4', '0', ' '), + KSPROPERTY_BIBLIOGRAPHIC_MAINPERSONALNAME = SEB_MK_FOURCC('0', '0', '1', ' '), + KSPROPERTY_BIBLIOGRAPHIC_MAINCORPORATEBODY = SEB_MK_FOURCC('0', '1', '1', ' '), + KSPROPERTY_BIBLIOGRAPHIC_MAINMEETINGNAME = SEB_MK_FOURCC('1', '1', '1', ' '), + KSPROPERTY_BIBLIOGRAPHIC_MAINUNIFORMTITLE = SEB_MK_FOURCC('0', '3', '1', ' '), + KSPROPERTY_BIBLIOGRAPHIC_UNIFORMTITLE = SEB_MK_FOURCC('0', '4', '2', ' '), + KSPROPERTY_BIBLIOGRAPHIC_TITLESTATEMENT = SEB_MK_FOURCC('5', '4', '2', ' '), + KSPROPERTY_BIBLIOGRAPHIC_VARYINGFORMTITLE = SEB_MK_FOURCC('6', '4', '2', ' '), + KSPROPERTY_BIBLIOGRAPHIC_PUBLICATION = SEB_MK_FOURCC('0', '6', '2', ' '), + KSPROPERTY_BIBLIOGRAPHIC_PHYSICALDESCRIPTION = SEB_MK_FOURCC('0', '0', '3', ' '), + KSPROPERTY_BIBLIOGRAPHIC_ADDEDENTRYTITLE = SEB_MK_FOURCC('0', '4', '4', ' '), + KSPROPERTY_BIBLIOGRAPHIC_SERIESSTATEMENT = SEB_MK_FOURCC('0', '9', '4', ' '), + KSPROPERTY_BIBLIOGRAPHIC_GENERALNOTE = SEB_MK_FOURCC('0', '0', '5', ' '), + KSPROPERTY_BIBLIOGRAPHIC_BIBLIOGRAPHYNOTE = SEB_MK_FOURCC('4', '0', '5', ' '), + KSPROPERTY_BIBLIOGRAPHIC_CONTENTSNOTE = SEB_MK_FOURCC('5', '0', '5', ' '), + KSPROPERTY_BIBLIOGRAPHIC_CREATIONCREDIT = SEB_MK_FOURCC('8', '0', '5', ' '), + KSPROPERTY_BIBLIOGRAPHIC_CITATION = SEB_MK_FOURCC('0', '1', '5', ' '), + KSPROPERTY_BIBLIOGRAPHIC_PARTICIPANT = SEB_MK_FOURCC('1', '1', '5', ' '), + KSPROPERTY_BIBLIOGRAPHIC_SUMMARY = SEB_MK_FOURCC('0', '2', '5', ' '), + KSPROPERTY_BIBLIOGRAPHIC_TARGETAUDIENCE = SEB_MK_FOURCC('1', '2', '5', ' '), + KSPROPERTY_BIBLIOGRAPHIC_ADDEDFORMAVAILABLE = SEB_MK_FOURCC('0', '3', '5', ' '), + KSPROPERTY_BIBLIOGRAPHIC_SYSTEMDETAILS = SEB_MK_FOURCC('8', '3', '5', ' '), + KSPROPERTY_BIBLIOGRAPHIC_AWARDS = SEB_MK_FOURCC('6', '8', '5', ' '), + KSPROPERTY_BIBLIOGRAPHIC_ADDEDENTRYPERSONALNAME = SEB_MK_FOURCC('0', '0', '6', ' '), + KSPROPERTY_BIBLIOGRAPHIC_ADDEDENTRYTOPICALTERM = SEB_MK_FOURCC('0', '5', '6', ' '), + KSPROPERTY_BIBLIOGRAPHIC_ADDEDENTRYGEOGRAPHIC = SEB_MK_FOURCC('1', '5', '6', ' '), + KSPROPERTY_BIBLIOGRAPHIC_INDEXTERMGENRE = SEB_MK_FOURCC('5', '5', '6', ' '), + KSPROPERTY_BIBLIOGRAPHIC_INDEXTERMCURRICULUM = SEB_MK_FOURCC('8', '5', '6', ' '), + KSPROPERTY_BIBLIOGRAPHIC_ADDEDENTRYUNIFORMTITLE = SEB_MK_FOURCC('0', '3', '7', ' '), + KSPROPERTY_BIBLIOGRAPHIC_ADDEDENTRYRELATED = SEB_MK_FOURCC('0', '4', '7', ' '), + KSPROPERTY_BIBLIOGRAPHIC_SERIESSTATEMENTPERSONALNAME = SEB_MK_FOURCC('0', '0', '8', ' '), + KSPROPERTY_BIBLIOGRAPHIC_SERIESSTATEMENTUNIFORMTITLE = SEB_MK_FOURCC('0', '3', '8', ' ') +}KSPROPERTY_BIBLIOGRAPHIC; + + # undef SEB_MK_FOURCC + + # define STATIC_KSPROPSETID_TopologyNode \ + 0x45FFAAA1L, 0x6E1B, 0x11D0, 0xBC, 0xF2, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00 +DEFINE_GUIDSTRUCT("45FFAAA1-6E1B-11D0-BCF2-444553540000", KSPROPSETID_TopologyNode); + # define KSPROPSETID_TopologyNode DEFINE_GUIDNAMED(KSPROPSETID_TopologyNode) + +typedef enum +{ + KSPROPERTY_TOPOLOGYNODE_ENABLE = 1, + KSPROPERTY_TOPOLOGYNODE_RESET +}KSPROPERTY_TOPOLOGYNODE; + + # define STATIC_KSPROPSETID_RtAudio \ + 0xa855a48c, 0x2f78, 0x4729, 0x90, 0x51, 0x19, 0x68, 0x74, 0x6b, 0x9e, 0xef +DEFINE_GUIDSTRUCT("A855A48C-2F78-4729-9051-1968746B9EEF", KSPROPSETID_RtAudio); + # define KSPROPSETID_RtAudio DEFINE_GUIDNAMED(KSPROPSETID_RtAudio) + +typedef enum +{ + KSPROPERTY_RTAUDIO_GETPOSITIONFUNCTION +}KSPROPERTY_RTAUDIO; + + # define STATIC_KSPROPSETID_DrmAudioStream \ + 0x2f2c8ddd, 0x4198, 0x4fac, 0xba, 0x29, 0x61, 0xbb, 0x5, 0xb7, 0xde, 0x6 +DEFINE_GUIDSTRUCT("2F2C8DDD-4198-4fac-BA29-61BB05B7DE06", KSPROPSETID_DrmAudioStream); + # define KSPROPSETID_DrmAudioStream DEFINE_GUIDNAMED(KSPROPSETID_DrmAudioStream) + +typedef enum +{ + KSPROPERTY_DRMAUDIOSTREAM_CONTENTID +}KSPROPERTY_DRMAUDIOSTREAM; + + # define STATIC_KSPROPSETID_Audio \ + 0x45FFAAA0L, 0x6E1B, 0x11D0, 0xBC, 0xF2, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00 +DEFINE_GUIDSTRUCT("45FFAAA0-6E1B-11D0-BCF2-444553540000", KSPROPSETID_Audio); + # define KSPROPSETID_Audio DEFINE_GUIDNAMED(KSPROPSETID_Audio) + +typedef enum +{ + KSPROPERTY_AUDIO_LATENCY = 1, + KSPROPERTY_AUDIO_COPY_PROTECTION, + KSPROPERTY_AUDIO_CHANNEL_CONFIG, + KSPROPERTY_AUDIO_VOLUMELEVEL, + KSPROPERTY_AUDIO_POSITION, + KSPROPERTY_AUDIO_DYNAMIC_RANGE, + KSPROPERTY_AUDIO_QUALITY, + KSPROPERTY_AUDIO_SAMPLING_RATE, + KSPROPERTY_AUDIO_DYNAMIC_SAMPLING_RATE, + KSPROPERTY_AUDIO_MIX_LEVEL_TABLE, + KSPROPERTY_AUDIO_MIX_LEVEL_CAPS, + KSPROPERTY_AUDIO_MUX_SOURCE, + KSPROPERTY_AUDIO_MUTE, + KSPROPERTY_AUDIO_BASS, + KSPROPERTY_AUDIO_MID, + KSPROPERTY_AUDIO_TREBLE, + KSPROPERTY_AUDIO_BASS_BOOST, + KSPROPERTY_AUDIO_EQ_LEVEL, + KSPROPERTY_AUDIO_NUM_EQ_BANDS, + KSPROPERTY_AUDIO_EQ_BANDS, + KSPROPERTY_AUDIO_AGC, + KSPROPERTY_AUDIO_DELAY, + KSPROPERTY_AUDIO_LOUDNESS, + KSPROPERTY_AUDIO_WIDE_MODE, + KSPROPERTY_AUDIO_WIDENESS, + KSPROPERTY_AUDIO_REVERB_LEVEL, + KSPROPERTY_AUDIO_CHORUS_LEVEL, + KSPROPERTY_AUDIO_DEV_SPECIFIC, + KSPROPERTY_AUDIO_DEMUX_DEST, + KSPROPERTY_AUDIO_STEREO_ENHANCE, + KSPROPERTY_AUDIO_MANUFACTURE_GUID, + KSPROPERTY_AUDIO_PRODUCT_GUID, + KSPROPERTY_AUDIO_CPU_RESOURCES, + KSPROPERTY_AUDIO_STEREO_SPEAKER_GEOMETRY, + KSPROPERTY_AUDIO_SURROUND_ENCODE, + KSPROPERTY_AUDIO_3D_INTERFACE, + KSPROPERTY_AUDIO_PEAKMETER, + KSPROPERTY_AUDIO_ALGORITHM_INSTANCE, + KSPROPERTY_AUDIO_FILTER_STATE, + KSPROPERTY_AUDIO_PREFERRED_STATUS +}KSPROPERTY_AUDIO; + + # define KSAUDIO_QUALITY_WORST 0x0 + # define KSAUDIO_QUALITY_PC 0x1 + # define KSAUDIO_QUALITY_BASIC 0x2 + # define KSAUDIO_QUALITY_ADVANCED 0x3 + + # define KSAUDIO_CPU_RESOURCES_NOT_HOST_CPU 0x00000000 + # define KSAUDIO_CPU_RESOURCES_HOST_CPU 0x7FFFFFFF + +typedef struct +{ + WINBOOL fCopyrighted; + WINBOOL fOriginal; +}KSAUDIO_COPY_PROTECTION, * PKSAUDIO_COPY_PROTECTION; + +typedef struct +{ + LONG ActiveSpeakerPositions; +}KSAUDIO_CHANNEL_CONFIG, * PKSAUDIO_CHANNEL_CONFIG; + + # define SPEAKER_FRONT_LEFT 0x1 + # define SPEAKER_FRONT_RIGHT 0x2 + # define SPEAKER_FRONT_CENTER 0x4 + # define SPEAKER_LOW_FREQUENCY 0x8 + # define SPEAKER_BACK_LEFT 0x10 + # define SPEAKER_BACK_RIGHT 0x20 + # define SPEAKER_FRONT_LEFT_OF_CENTER 0x40 + # define SPEAKER_FRONT_RIGHT_OF_CENTER 0x80 + # define SPEAKER_BACK_CENTER 0x100 + # define SPEAKER_SIDE_LEFT 0x200 + # define SPEAKER_SIDE_RIGHT 0x400 + # define SPEAKER_TOP_CENTER 0x800 + # define SPEAKER_TOP_FRONT_LEFT 0x1000 + # define SPEAKER_TOP_FRONT_CENTER 0x2000 + # define SPEAKER_TOP_FRONT_RIGHT 0x4000 + # define SPEAKER_TOP_BACK_LEFT 0x8000 + # define SPEAKER_TOP_BACK_CENTER 0x10000 + # define SPEAKER_TOP_BACK_RIGHT 0x20000 + + # define SPEAKER_RESERVED 0x7FFC0000 + + # define SPEAKER_ALL 0x80000000 + + # define KSAUDIO_SPEAKER_DIRECTOUT 0 + # define KSAUDIO_SPEAKER_MONO (SPEAKER_FRONT_CENTER) + # define KSAUDIO_SPEAKER_STEREO (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT) + # define KSAUDIO_SPEAKER_QUAD (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | \ + SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT) + # define KSAUDIO_SPEAKER_SURROUND (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | \ + SPEAKER_FRONT_CENTER | SPEAKER_BACK_CENTER) + # define KSAUDIO_SPEAKER_5POINT1 (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | \ + SPEAKER_FRONT_CENTER | SPEAKER_LOW_FREQUENCY | \ + SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT) + # define KSAUDIO_SPEAKER_7POINT1 (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | \ + SPEAKER_FRONT_CENTER | SPEAKER_LOW_FREQUENCY | \ + SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT | \ + SPEAKER_FRONT_LEFT_OF_CENTER | SPEAKER_FRONT_RIGHT_OF_CENTER) + # define KSAUDIO_SPEAKER_5POINT1_SURROUND (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | \ + SPEAKER_FRONT_CENTER | SPEAKER_LOW_FREQUENCY | \ + SPEAKER_SIDE_LEFT | SPEAKER_SIDE_RIGHT) + # define KSAUDIO_SPEAKER_7POINT1_SURROUND (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | \ + SPEAKER_FRONT_CENTER | SPEAKER_LOW_FREQUENCY | \ + SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT | \ + SPEAKER_SIDE_LEFT | SPEAKER_SIDE_RIGHT) + + # define KSAUDIO_SPEAKER_5POINT1_BACK KSAUDIO_SPEAKER_5POINT1 + # define KSAUDIO_SPEAKER_7POINT1_WIDE KSAUDIO_SPEAKER_7POINT1 + + # define KSAUDIO_SPEAKER_GROUND_FRONT_LEFT SPEAKER_FRONT_LEFT + # define KSAUDIO_SPEAKER_GROUND_FRONT_CENTER SPEAKER_FRONT_CENTER + # define KSAUDIO_SPEAKER_GROUND_FRONT_RIGHT SPEAKER_FRONT_RIGHT + # define KSAUDIO_SPEAKER_GROUND_REAR_LEFT SPEAKER_BACK_LEFT + # define KSAUDIO_SPEAKER_GROUND_REAR_RIGHT SPEAKER_BACK_RIGHT + # define KSAUDIO_SPEAKER_TOP_MIDDLE SPEAKER_TOP_CENTER + # define KSAUDIO_SPEAKER_SUPER_WOOFER SPEAKER_LOW_FREQUENCY + +typedef struct +{ + ULONG QuietCompression; + ULONG LoudCompression; +}KSAUDIO_DYNAMIC_RANGE, * PKSAUDIO_DYNAMIC_RANGE; + +typedef struct +{ + WINBOOL Mute; + LONG Level; +}KSAUDIO_MIXLEVEL, * PKSAUDIO_MIXLEVEL; + +typedef struct +{ + WINBOOL Mute; + LONG Minimum; + LONG Maximum; + LONG Reset; +}KSAUDIO_MIX_CAPS, * PKSAUDIO_MIX_CAPS; + +typedef struct +{ + ULONG InputChannels; + ULONG OutputChannels; + KSAUDIO_MIX_CAPS Capabilities[1]; +}KSAUDIO_MIXCAP_TABLE, * PKSAUDIO_MIXCAP_TABLE; + +typedef enum +{ + SE_TECH_NONE, + SE_TECH_ANALOG_DEVICES_PHAT, + SE_TECH_CREATIVE, + SE_TECH_NATIONAL_SEMI, + SE_TECH_YAMAHA_YMERSION, + SE_TECH_BBE, + SE_TECH_CRYSTAL_SEMI, + SE_TECH_QSOUND_QXPANDER, + SE_TECH_SPATIALIZER, + SE_TECH_SRS, + SE_TECH_PLATFORM_TECH, + SE_TECH_AKM, + SE_TECH_AUREAL, + SE_TECH_AZTECH, + SE_TECH_BINAURA, + SE_TECH_ESS_TECH, + SE_TECH_HARMAN_VMAX, + SE_TECH_NVIDEA, + SE_TECH_PHILIPS_INCREDIBLE, + SE_TECH_TEXAS_INST, + SE_TECH_VLSI_TECH +}SE_TECHNIQUE; + +typedef struct +{ + SE_TECHNIQUE Technique; + ULONG Center; + ULONG Depth; + ULONG Reserved; +}KSAUDIO_STEREO_ENHANCE, * PKSAUDIO_STEREO_ENHANCE; + +typedef enum +{ + KSPROPERTY_SYSAUDIO_NORMAL_DEFAULT = 0, + KSPROPERTY_SYSAUDIO_PLAYBACK_DEFAULT, + KSPROPERTY_SYSAUDIO_RECORD_DEFAULT, + KSPROPERTY_SYSAUDIO_MIDI_DEFAULT, + KSPROPERTY_SYSAUDIO_MIXER_DEFAULT +}KSPROPERTY_SYSAUDIO_DEFAULT_TYPE; + +typedef struct +{ + WINBOOL Enable; + KSPROPERTY_SYSAUDIO_DEFAULT_TYPE DeviceType; + ULONG Flags; + ULONG Reserved; +}KSAUDIO_PREFERRED_STATUS, * PKSAUDIO_PREFERRED_STATUS; + + # define STATIC_KSNODETYPE_DAC \ + 0x507AE360L, 0xC554, 0x11D0, 0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1 +DEFINE_GUIDSTRUCT("507AE360-C554-11D0-8A2B-00A0C9255AC1", KSNODETYPE_DAC); + # define KSNODETYPE_DAC DEFINE_GUIDNAMED(KSNODETYPE_DAC) + + # define STATIC_KSNODETYPE_ADC \ + 0x4D837FE0L, 0xC555, 0x11D0, 0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1 +DEFINE_GUIDSTRUCT("4D837FE0-C555-11D0-8A2B-00A0C9255AC1", KSNODETYPE_ADC); + # define KSNODETYPE_ADC DEFINE_GUIDNAMED(KSNODETYPE_ADC) + + # define STATIC_KSNODETYPE_SRC \ + 0x9DB7B9E0L, 0xC555, 0x11D0, 0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1 +DEFINE_GUIDSTRUCT("9DB7B9E0-C555-11D0-8A2B-00A0C9255AC1", KSNODETYPE_SRC); + # define KSNODETYPE_SRC DEFINE_GUIDNAMED(KSNODETYPE_SRC) + + # define STATIC_KSNODETYPE_SUPERMIX \ + 0xE573ADC0L, 0xC555, 0x11D0, 0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1 +DEFINE_GUIDSTRUCT("E573ADC0-C555-11D0-8A2B-00A0C9255AC1", KSNODETYPE_SUPERMIX); + # define KSNODETYPE_SUPERMIX DEFINE_GUIDNAMED(KSNODETYPE_SUPERMIX) + + # define STATIC_KSNODETYPE_MUX \ + 0x2CEAF780L, 0xC556, 0x11D0, 0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1 +DEFINE_GUIDSTRUCT("2CEAF780-C556-11D0-8A2B-00A0C9255AC1", KSNODETYPE_MUX); + # define KSNODETYPE_MUX DEFINE_GUIDNAMED(KSNODETYPE_MUX) + + # define STATIC_KSNODETYPE_DEMUX \ + 0xC0EB67D4L, 0xE807, 0x11D0, 0x95, 0x8A, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3 +DEFINE_GUIDSTRUCT("C0EB67D4-E807-11D0-958A-00C04FB925D3", KSNODETYPE_DEMUX); + # define KSNODETYPE_DEMUX DEFINE_GUIDNAMED(KSNODETYPE_DEMUX) + + # define STATIC_KSNODETYPE_SUM \ + 0xDA441A60L, 0xC556, 0x11D0, 0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1 +DEFINE_GUIDSTRUCT("DA441A60-C556-11D0-8A2B-00A0C9255AC1", KSNODETYPE_SUM); + # define KSNODETYPE_SUM DEFINE_GUIDNAMED(KSNODETYPE_SUM) + + # define STATIC_KSNODETYPE_MUTE \ + 0x02B223C0L, 0xC557, 0x11D0, 0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1 +DEFINE_GUIDSTRUCT("02B223C0-C557-11D0-8A2B-00A0C9255AC1", KSNODETYPE_MUTE); + # define KSNODETYPE_MUTE DEFINE_GUIDNAMED(KSNODETYPE_MUTE) + + # define STATIC_KSNODETYPE_VOLUME \ + 0x3A5ACC00L, 0xC557, 0x11D0, 0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1 +DEFINE_GUIDSTRUCT("3A5ACC00-C557-11D0-8A2B-00A0C9255AC1", KSNODETYPE_VOLUME); + # define KSNODETYPE_VOLUME DEFINE_GUIDNAMED(KSNODETYPE_VOLUME) + + # define STATIC_KSNODETYPE_TONE \ + 0x7607E580L, 0xC557, 0x11D0, 0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1 +DEFINE_GUIDSTRUCT("7607E580-C557-11D0-8A2B-00A0C9255AC1", KSNODETYPE_TONE); + # define KSNODETYPE_TONE DEFINE_GUIDNAMED(KSNODETYPE_TONE) + + # define STATIC_KSNODETYPE_EQUALIZER \ + 0x9D41B4A0L, 0xC557, 0x11D0, 0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1 +DEFINE_GUIDSTRUCT("9D41B4A0-C557-11D0-8A2B-00A0C9255AC1", KSNODETYPE_EQUALIZER); + # define KSNODETYPE_EQUALIZER DEFINE_GUIDNAMED(KSNODETYPE_EQUALIZER) + + # define STATIC_KSNODETYPE_AGC \ + 0xE88C9BA0L, 0xC557, 0x11D0, 0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1 +DEFINE_GUIDSTRUCT("E88C9BA0-C557-11D0-8A2B-00A0C9255AC1", KSNODETYPE_AGC); + # define KSNODETYPE_AGC DEFINE_GUIDNAMED(KSNODETYPE_AGC) + + # define STATIC_KSNODETYPE_NOISE_SUPPRESS \ + 0xe07f903f, 0x62fd, 0x4e60, 0x8c, 0xdd, 0xde, 0xa7, 0x23, 0x66, 0x65, 0xb5 +DEFINE_GUIDSTRUCT("E07F903F-62FD-4e60-8CDD-DEA7236665B5", KSNODETYPE_NOISE_SUPPRESS); + # define KSNODETYPE_NOISE_SUPPRESS DEFINE_GUIDNAMED(KSNODETYPE_NOISE_SUPPRESS) + + # define STATIC_KSNODETYPE_DELAY \ + 0x144981E0L, 0xC558, 0x11D0, 0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1 +DEFINE_GUIDSTRUCT("144981E0-C558-11D0-8A2B-00A0C9255AC1", KSNODETYPE_DELAY); + # define KSNODETYPE_DELAY DEFINE_GUIDNAMED(KSNODETYPE_DELAY) + + # define STATIC_KSNODETYPE_LOUDNESS \ + 0x41887440L, 0xC558, 0x11D0, 0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1 +DEFINE_GUIDSTRUCT("41887440-C558-11D0-8A2B-00A0C9255AC1", KSNODETYPE_LOUDNESS); + # define KSNODETYPE_LOUDNESS DEFINE_GUIDNAMED(KSNODETYPE_LOUDNESS) + + # define STATIC_KSNODETYPE_PROLOGIC_DECODER \ + 0x831C2C80L, 0xC558, 0x11D0, 0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1 +DEFINE_GUIDSTRUCT("831C2C80-C558-11D0-8A2B-00A0C9255AC1", KSNODETYPE_PROLOGIC_DECODER); + # define KSNODETYPE_PROLOGIC_DECODER DEFINE_GUIDNAMED(KSNODETYPE_PROLOGIC_DECODER) + + # define STATIC_KSNODETYPE_STEREO_WIDE \ + 0xA9E69800L, 0xC558, 0x11D0, 0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1 +DEFINE_GUIDSTRUCT("A9E69800-C558-11D0-8A2B-00A0C9255AC1", KSNODETYPE_STEREO_WIDE); + # define KSNODETYPE_STEREO_WIDE DEFINE_GUIDNAMED(KSNODETYPE_STEREO_WIDE) + + # define STATIC_KSNODETYPE_STEREO_ENHANCE \ + 0xAF6878ACL, 0xE83F, 0x11D0, 0x95, 0x8A, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3 +DEFINE_GUIDSTRUCT("AF6878AC-E83F-11D0-958A-00C04FB925D3", KSNODETYPE_STEREO_ENHANCE); + # define KSNODETYPE_STEREO_ENHANCE DEFINE_GUIDNAMED(KSNODETYPE_STEREO_ENHANCE) + + # define STATIC_KSNODETYPE_REVERB \ + 0xEF0328E0L, 0xC558, 0x11D0, 0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1 +DEFINE_GUIDSTRUCT("EF0328E0-C558-11D0-8A2B-00A0C9255AC1", KSNODETYPE_REVERB); + # define KSNODETYPE_REVERB DEFINE_GUIDNAMED(KSNODETYPE_REVERB) + + # define STATIC_KSNODETYPE_CHORUS \ + 0x20173F20L, 0xC559, 0x11D0, 0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1 +DEFINE_GUIDSTRUCT("20173F20-C559-11D0-8A2B-00A0C9255AC1", KSNODETYPE_CHORUS); + # define KSNODETYPE_CHORUS DEFINE_GUIDNAMED(KSNODETYPE_CHORUS) + + # define STATIC_KSNODETYPE_3D_EFFECTS \ + 0x55515860L, 0xC559, 0x11D0, 0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1 +DEFINE_GUIDSTRUCT("55515860-C559-11D0-8A2B-00A0C9255AC1", KSNODETYPE_3D_EFFECTS); + # define KSNODETYPE_3D_EFFECTS DEFINE_GUIDNAMED(KSNODETYPE_3D_EFFECTS) + + # define STATIC_KSNODETYPE_ACOUSTIC_ECHO_CANCEL STATIC_KSCATEGORY_ACOUSTIC_ECHO_CANCEL + # define KSNODETYPE_ACOUSTIC_ECHO_CANCEL KSCATEGORY_ACOUSTIC_ECHO_CANCEL + + # define STATIC_KSALGORITHMINSTANCE_SYSTEM_ACOUSTIC_ECHO_CANCEL \ + 0x1c22c56dL, 0x9879, 0x4f5b, 0xa3, 0x89, 0x27, 0x99, 0x6d, 0xdc, 0x28, 0x10 +DEFINE_GUIDSTRUCT("1C22C56D-9879-4f5b-A389-27996DDC2810", KSALGORITHMINSTANCE_SYSTEM_ACOUSTIC_ECHO_CANCEL); + # define KSALGORITHMINSTANCE_SYSTEM_ACOUSTIC_ECHO_CANCEL DEFINE_GUIDNAMED(KSALGORITHMINSTANCE_SYSTEM_ACOUSTIC_ECHO_CANCEL) + + # define STATIC_KSALGORITHMINSTANCE_SYSTEM_NOISE_SUPPRESS \ + 0x5ab0882eL, 0x7274, 0x4516, 0x87, 0x7d, 0x4e, 0xee, 0x99, 0xba, 0x4f, 0xd0 +DEFINE_GUIDSTRUCT("5AB0882E-7274-4516-877D-4EEE99BA4FD0", KSALGORITHMINSTANCE_SYSTEM_NOISE_SUPPRESS); + # define KSALGORITHMINSTANCE_SYSTEM_NOISE_SUPPRESS DEFINE_GUIDNAMED(KSALGORITHMINSTANCE_SYSTEM_NOISE_SUPPRESS) + + # define STATIC_KSALGORITHMINSTANCE_SYSTEM_AGC \ + 0x950e55b9L, 0x877c, 0x4c67, 0xbe, 0x8, 0xe4, 0x7b, 0x56, 0x11, 0x13, 0xa +DEFINE_GUIDSTRUCT("950E55B9-877C-4c67-BE08-E47B5611130A", KSALGORITHMINSTANCE_SYSTEM_AGC); + # define KSALGORITHMINSTANCE_SYSTEM_AGC DEFINE_GUIDNAMED(KSALGORITHMINSTANCE_SYSTEM_AGC) + + # define STATIC_KSALGORITHMINSTANCE_SYSTEM_MICROPHONE_ARRAY_PROCESSOR \ + 0xB6F5A0A0L, 0x9E61, 0x4F8C, 0x91, 0xE3, 0x76, 0xCF, 0xF, 0x3C, 0x47, 0x1F +DEFINE_GUIDSTRUCT("B6F5A0A0-9E61-4f8c-91E3-76CF0F3C471F", KSALGORITHMINSTANCE_SYSTEM_MICROPHONE_ARRAY_PROCESSOR); + # define KSALGORITHMINSTANCE_SYSTEM_MICROPHONE_ARRAY_PROCESSOR DEFINE_GUIDNAMED(KSALGORITHMINSTANCE_SYSTEM_MICROPHONE_ARRAY_PROCESSOR) + + # define STATIC_KSNODETYPE_MICROPHONE_ARRAY_PROCESSOR STATIC_KSCATEGORY_MICROPHONE_ARRAY_PROCESSOR + # define KSNODETYPE_MICROPHONE_ARRAY_PROCESSOR KSCATEGORY_MICROPHONE_ARRAY_PROCESSOR + + # define STATIC_KSNODETYPE_DEV_SPECIFIC \ + 0x941C7AC0L, 0xC559, 0x11D0, 0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1 +DEFINE_GUIDSTRUCT("941C7AC0-C559-11D0-8A2B-00A0C9255AC1", KSNODETYPE_DEV_SPECIFIC); + # define KSNODETYPE_DEV_SPECIFIC DEFINE_GUIDNAMED(KSNODETYPE_DEV_SPECIFIC) + + # define STATIC_KSNODETYPE_PROLOGIC_ENCODER \ + 0x8074C5B2L, 0x3C66, 0x11D2, 0xB4, 0x5A, 0x30, 0x78, 0x30, 0x2C, 0x20, 0x30 +DEFINE_GUIDSTRUCT("8074C5B2-3C66-11D2-B45A-3078302C2030", KSNODETYPE_PROLOGIC_ENCODER); + # define KSNODETYPE_PROLOGIC_ENCODER DEFINE_GUIDNAMED(KSNODETYPE_PROLOGIC_ENCODER) + # define KSNODETYPE_SURROUND_ENCODER KSNODETYPE_PROLOGIC_ENCODER + + # define STATIC_KSNODETYPE_PEAKMETER \ + 0xa085651eL, 0x5f0d, 0x4b36, 0xa8, 0x69, 0xd1, 0x95, 0xd6, 0xab, 0x4b, 0x9e +DEFINE_GUIDSTRUCT("A085651E-5F0D-4b36-A869-D195D6AB4B9E", KSNODETYPE_PEAKMETER); + # define KSNODETYPE_PEAKMETER DEFINE_GUIDNAMED(KSNODETYPE_PEAKMETER) + + # define STATIC_KSAUDFNAME_BASS \ + 0x185FEDE0L, 0x9905, 0x11D1, 0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3 +DEFINE_GUIDSTRUCT("185FEDE0-9905-11D1-95A9-00C04FB925D3", KSAUDFNAME_BASS); + # define KSAUDFNAME_BASS DEFINE_GUIDNAMED(KSAUDFNAME_BASS) + + # define STATIC_KSAUDFNAME_TREBLE \ + 0x185FEDE1L, 0x9905, 0x11D1, 0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3 +DEFINE_GUIDSTRUCT("185FEDE1-9905-11D1-95A9-00C04FB925D3", KSAUDFNAME_TREBLE); + # define KSAUDFNAME_TREBLE DEFINE_GUIDNAMED(KSAUDFNAME_TREBLE) + + # define STATIC_KSAUDFNAME_3D_STEREO \ + 0x185FEDE2L, 0x9905, 0x11D1, 0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3 +DEFINE_GUIDSTRUCT("185FEDE2-9905-11D1-95A9-00C04FB925D3", KSAUDFNAME_3D_STEREO); + # define KSAUDFNAME_3D_STEREO DEFINE_GUIDNAMED(KSAUDFNAME_3D_STEREO) + + # define STATIC_KSAUDFNAME_MASTER_VOLUME \ + 0x185FEDE3L, 0x9905, 0x11D1, 0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3 +DEFINE_GUIDSTRUCT("185FEDE3-9905-11D1-95A9-00C04FB925D3", KSAUDFNAME_MASTER_VOLUME); + # define KSAUDFNAME_MASTER_VOLUME DEFINE_GUIDNAMED(KSAUDFNAME_MASTER_VOLUME) + + # define STATIC_KSAUDFNAME_MASTER_MUTE \ + 0x185FEDE4L, 0x9905, 0x11D1, 0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3 +DEFINE_GUIDSTRUCT("185FEDE4-9905-11D1-95A9-00C04FB925D3", KSAUDFNAME_MASTER_MUTE); + # define KSAUDFNAME_MASTER_MUTE DEFINE_GUIDNAMED(KSAUDFNAME_MASTER_MUTE) + + # define STATIC_KSAUDFNAME_WAVE_VOLUME \ + 0x185FEDE5L, 0x9905, 0x11D1, 0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3 +DEFINE_GUIDSTRUCT("185FEDE5-9905-11D1-95A9-00C04FB925D3", KSAUDFNAME_WAVE_VOLUME); + # define KSAUDFNAME_WAVE_VOLUME DEFINE_GUIDNAMED(KSAUDFNAME_WAVE_VOLUME) + + # define STATIC_KSAUDFNAME_WAVE_MUTE \ + 0x185FEDE6L, 0x9905, 0x11D1, 0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3 +DEFINE_GUIDSTRUCT("185FEDE6-9905-11D1-95A9-00C04FB925D3", KSAUDFNAME_WAVE_MUTE); + # define KSAUDFNAME_WAVE_MUTE DEFINE_GUIDNAMED(KSAUDFNAME_WAVE_MUTE) + + # define STATIC_KSAUDFNAME_MIDI_VOLUME \ + 0x185FEDE7L, 0x9905, 0x11D1, 0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3 +DEFINE_GUIDSTRUCT("185FEDE7-9905-11D1-95A9-00C04FB925D3", KSAUDFNAME_MIDI_VOLUME); + # define KSAUDFNAME_MIDI_VOLUME DEFINE_GUIDNAMED(KSAUDFNAME_MIDI_VOLUME) + + # define STATIC_KSAUDFNAME_MIDI_MUTE \ + 0x185FEDE8L, 0x9905, 0x11D1, 0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3 +DEFINE_GUIDSTRUCT("185FEDE8-9905-11D1-95A9-00C04FB925D3", KSAUDFNAME_MIDI_MUTE); + # define KSAUDFNAME_MIDI_MUTE DEFINE_GUIDNAMED(KSAUDFNAME_MIDI_MUTE) + + # define STATIC_KSAUDFNAME_CD_VOLUME \ + 0x185FEDE9L, 0x9905, 0x11D1, 0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3 +DEFINE_GUIDSTRUCT("185FEDE9-9905-11D1-95A9-00C04FB925D3", KSAUDFNAME_CD_VOLUME); + # define KSAUDFNAME_CD_VOLUME DEFINE_GUIDNAMED(KSAUDFNAME_CD_VOLUME) + + # define STATIC_KSAUDFNAME_CD_MUTE \ + 0x185FEDEAL, 0x9905, 0x11D1, 0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3 +DEFINE_GUIDSTRUCT("185FEDEA-9905-11D1-95A9-00C04FB925D3", KSAUDFNAME_CD_MUTE); + # define KSAUDFNAME_CD_MUTE DEFINE_GUIDNAMED(KSAUDFNAME_CD_MUTE) + + # define STATIC_KSAUDFNAME_LINE_VOLUME \ + 0x185FEDEBL, 0x9905, 0x11D1, 0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3 +DEFINE_GUIDSTRUCT("185FEDEB-9905-11D1-95A9-00C04FB925D3", KSAUDFNAME_LINE_VOLUME); + # define KSAUDFNAME_LINE_VOLUME DEFINE_GUIDNAMED(KSAUDFNAME_LINE_VOLUME) + + # define STATIC_KSAUDFNAME_LINE_MUTE \ + 0x185FEDECL, 0x9905, 0x11D1, 0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3 +DEFINE_GUIDSTRUCT("185FEDEC-9905-11D1-95A9-00C04FB925D3", KSAUDFNAME_LINE_MUTE); + # define KSAUDFNAME_LINE_MUTE DEFINE_GUIDNAMED(KSAUDFNAME_LINE_MUTE) + + # define STATIC_KSAUDFNAME_MIC_VOLUME \ + 0x185FEDEDL, 0x9905, 0x11D1, 0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3 +DEFINE_GUIDSTRUCT("185FEDED-9905-11D1-95A9-00C04FB925D3", KSAUDFNAME_MIC_VOLUME); + # define KSAUDFNAME_MIC_VOLUME DEFINE_GUIDNAMED(KSAUDFNAME_MIC_VOLUME) + + # define STATIC_KSAUDFNAME_MIC_MUTE \ + 0x185FEDEEL, 0x9905, 0x11D1, 0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3 +DEFINE_GUIDSTRUCT("185FEDEE-9905-11D1-95A9-00C04FB925D3", KSAUDFNAME_MIC_MUTE); + # define KSAUDFNAME_MIC_MUTE DEFINE_GUIDNAMED(KSAUDFNAME_MIC_MUTE) + + # define STATIC_KSAUDFNAME_RECORDING_SOURCE \ + 0x185FEDEFL, 0x9905, 0x11D1, 0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3 +DEFINE_GUIDSTRUCT("185FEDEF-9905-11D1-95A9-00C04FB925D3", KSAUDFNAME_RECORDING_SOURCE); + # define KSAUDFNAME_RECORDING_SOURCE DEFINE_GUIDNAMED(KSAUDFNAME_RECORDING_SOURCE) + + # define STATIC_KSAUDFNAME_PC_SPEAKER_VOLUME \ + 0x185FEDF0L, 0x9905, 0x11D1, 0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3 +DEFINE_GUIDSTRUCT("185FEDF0-9905-11D1-95A9-00C04FB925D3", KSAUDFNAME_PC_SPEAKER_VOLUME); + # define KSAUDFNAME_PC_SPEAKER_VOLUME DEFINE_GUIDNAMED(KSAUDFNAME_PC_SPEAKER_VOLUME) + + # define STATIC_KSAUDFNAME_PC_SPEAKER_MUTE \ + 0x185FEDF1L, 0x9905, 0x11D1, 0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3 +DEFINE_GUIDSTRUCT("185FEDF1-9905-11D1-95A9-00C04FB925D3", KSAUDFNAME_PC_SPEAKER_MUTE); + # define KSAUDFNAME_PC_SPEAKER_MUTE DEFINE_GUIDNAMED(KSAUDFNAME_PC_SPEAKER_MUTE) + + # define STATIC_KSAUDFNAME_MIDI_IN_VOLUME \ + 0x185FEDF2L, 0x9905, 0x11D1, 0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3 +DEFINE_GUIDSTRUCT("185FEDF2-9905-11D1-95A9-00C04FB925D3", KSAUDFNAME_MIDI_IN_VOLUME); + # define KSAUDFNAME_MIDI_IN_VOLUME DEFINE_GUIDNAMED(KSAUDFNAME_MIDI_IN_VOLUME) + + # define STATIC_KSAUDFNAME_CD_IN_VOLUME \ + 0x185FEDF3L, 0x9905, 0x11D1, 0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3 +DEFINE_GUIDSTRUCT("185FEDF3-9905-11D1-95A9-00C04FB925D3", KSAUDFNAME_CD_IN_VOLUME); + # define KSAUDFNAME_CD_IN_VOLUME DEFINE_GUIDNAMED(KSAUDFNAME_CD_IN_VOLUME) + + # define STATIC_KSAUDFNAME_LINE_IN_VOLUME \ + 0x185FEDF4L, 0x9905, 0x11D1, 0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3 +DEFINE_GUIDSTRUCT("185FEDF4-9905-11D1-95A9-00C04FB925D3", KSAUDFNAME_LINE_IN_VOLUME); + # define KSAUDFNAME_LINE_IN_VOLUME DEFINE_GUIDNAMED(KSAUDFNAME_LINE_IN_VOLUME) + + # define STATIC_KSAUDFNAME_MIC_IN_VOLUME \ + 0x185FEDF5L, 0x9905, 0x11D1, 0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3 +DEFINE_GUIDSTRUCT("185FEDF5-9905-11D1-95A9-00C04FB925D3", KSAUDFNAME_MIC_IN_VOLUME); + # define KSAUDFNAME_MIC_IN_VOLUME DEFINE_GUIDNAMED(KSAUDFNAME_MIC_IN_VOLUME) + + # define STATIC_KSAUDFNAME_WAVE_IN_VOLUME \ + 0x185FEDF6L, 0x9905, 0x11D1, 0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3 +DEFINE_GUIDSTRUCT("185FEDF6-9905-11D1-95A9-00C04FB925D3", KSAUDFNAME_WAVE_IN_VOLUME); + # define KSAUDFNAME_WAVE_IN_VOLUME DEFINE_GUIDNAMED(KSAUDFNAME_WAVE_IN_VOLUME) + + # define STATIC_KSAUDFNAME_VOLUME_CONTROL \ + 0x185FEDF7L, 0x9905, 0x11D1, 0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3 +DEFINE_GUIDSTRUCT("185FEDF7-9905-11D1-95A9-00C04FB925D3", KSAUDFNAME_VOLUME_CONTROL); + # define KSAUDFNAME_VOLUME_CONTROL DEFINE_GUIDNAMED(KSAUDFNAME_VOLUME_CONTROL) + + # define STATIC_KSAUDFNAME_MIDI \ + 0x185FEDF8L, 0x9905, 0x11D1, 0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3 +DEFINE_GUIDSTRUCT("185FEDF8-9905-11D1-95A9-00C04FB925D3", KSAUDFNAME_MIDI); + # define KSAUDFNAME_MIDI DEFINE_GUIDNAMED(KSAUDFNAME_MIDI) + + # define STATIC_KSAUDFNAME_LINE_IN \ + 0x185FEDF9L, 0x9905, 0x11D1, 0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3 +DEFINE_GUIDSTRUCT("185FEDF9-9905-11D1-95A9-00C04FB925D3", KSAUDFNAME_LINE_IN); + # define KSAUDFNAME_LINE_IN DEFINE_GUIDNAMED(KSAUDFNAME_LINE_IN) + + # define STATIC_KSAUDFNAME_RECORDING_CONTROL \ + 0x185FEDFAL, 0x9905, 0x11D1, 0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3 +DEFINE_GUIDSTRUCT("185FEDFA-9905-11D1-95A9-00C04FB925D3", KSAUDFNAME_RECORDING_CONTROL); + # define KSAUDFNAME_RECORDING_CONTROL DEFINE_GUIDNAMED(KSAUDFNAME_RECORDING_CONTROL) + + # define STATIC_KSAUDFNAME_CD_AUDIO \ + 0x185FEDFBL, 0x9905, 0x11D1, 0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3 +DEFINE_GUIDSTRUCT("185FEDFB-9905-11D1-95A9-00C04FB925D3", KSAUDFNAME_CD_AUDIO); + # define KSAUDFNAME_CD_AUDIO DEFINE_GUIDNAMED(KSAUDFNAME_CD_AUDIO) + + # define STATIC_KSAUDFNAME_AUX_VOLUME \ + 0x185FEDFCL, 0x9905, 0x11D1, 0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3 +DEFINE_GUIDSTRUCT("185FEDFC-9905-11D1-95A9-00C04FB925D3", KSAUDFNAME_AUX_VOLUME); + # define KSAUDFNAME_AUX_VOLUME DEFINE_GUIDNAMED(KSAUDFNAME_AUX_VOLUME) + + # define STATIC_KSAUDFNAME_AUX_MUTE \ + 0x185FEDFDL, 0x9905, 0x11D1, 0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3 +DEFINE_GUIDSTRUCT("185FEDFD-9905-11D1-95A9-00C04FB925D3", KSAUDFNAME_AUX_MUTE); + # define KSAUDFNAME_AUX_MUTE DEFINE_GUIDNAMED(KSAUDFNAME_AUX_MUTE) + + # define STATIC_KSAUDFNAME_AUX \ + 0x185FEDFEL, 0x9905, 0x11D1, 0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3 +DEFINE_GUIDSTRUCT("185FEDFE-9905-11D1-95A9-00C04FB925D3", KSAUDFNAME_AUX); + # define KSAUDFNAME_AUX DEFINE_GUIDNAMED(KSAUDFNAME_AUX) + + # define STATIC_KSAUDFNAME_PC_SPEAKER \ + 0x185FEDFFL, 0x9905, 0x11D1, 0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3 +DEFINE_GUIDSTRUCT("185FEDFF-9905-11D1-95A9-00C04FB925D3", KSAUDFNAME_PC_SPEAKER); + # define KSAUDFNAME_PC_SPEAKER DEFINE_GUIDNAMED(KSAUDFNAME_PC_SPEAKER) + + # define STATIC_KSAUDFNAME_WAVE_OUT_MIX \ + 0x185FEE00L, 0x9905, 0x11D1, 0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3 +DEFINE_GUIDSTRUCT("185FEE00-9905-11D1-95A9-00C04FB925D3", KSAUDFNAME_WAVE_OUT_MIX); + # define KSAUDFNAME_WAVE_OUT_MIX DEFINE_GUIDNAMED(KSAUDFNAME_WAVE_OUT_MIX) + + # define STATIC_KSAUDFNAME_MONO_OUT \ + 0xf9b41dc3L, 0x96e2, 0x11d2, 0xac, 0x4c, 0x0, 0xc0, 0x4f, 0x8e, 0xfb, 0x68 +DEFINE_GUIDSTRUCT("F9B41DC3-96E2-11d2-AC4C-00C04F8EFB68", KSAUDFNAME_MONO_OUT); + # define KSAUDFNAME_MONO_OUT DEFINE_GUIDNAMED(KSAUDFNAME_MONO_OUT) + + # define STATIC_KSAUDFNAME_STEREO_MIX \ + 0xdff077L, 0x96e3, 0x11d2, 0xac, 0x4c, 0x0, 0xc0, 0x4f, 0x8e, 0xfb, 0x68 +DEFINE_GUIDSTRUCT("00DFF077-96E3-11d2-AC4C-00C04F8EFB68", KSAUDFNAME_STEREO_MIX); + # define KSAUDFNAME_STEREO_MIX DEFINE_GUIDNAMED(KSAUDFNAME_STEREO_MIX) + + # define STATIC_KSAUDFNAME_MONO_MIX \ + 0xdff078L, 0x96e3, 0x11d2, 0xac, 0x4c, 0x0, 0xc0, 0x4f, 0x8e, 0xfb, 0x68 +DEFINE_GUIDSTRUCT("00DFF078-96E3-11d2-AC4C-00C04F8EFB68", KSAUDFNAME_MONO_MIX); + # define KSAUDFNAME_MONO_MIX DEFINE_GUIDNAMED(KSAUDFNAME_MONO_MIX) + + # define STATIC_KSAUDFNAME_MONO_OUT_VOLUME \ + 0x1ad247ebL, 0x96e3, 0x11d2, 0xac, 0x4c, 0x0, 0xc0, 0x4f, 0x8e, 0xfb, 0x68 +DEFINE_GUIDSTRUCT("1AD247EB-96E3-11d2-AC4C-00C04F8EFB68", KSAUDFNAME_MONO_OUT_VOLUME); + # define KSAUDFNAME_MONO_OUT_VOLUME DEFINE_GUIDNAMED(KSAUDFNAME_MONO_OUT_VOLUME) + + # define STATIC_KSAUDFNAME_MONO_OUT_MUTE \ + 0x1ad247ecL, 0x96e3, 0x11d2, 0xac, 0x4c, 0x0, 0xc0, 0x4f, 0x8e, 0xfb, 0x68 +DEFINE_GUIDSTRUCT("1AD247EC-96E3-11d2-AC4C-00C04F8EFB68", KSAUDFNAME_MONO_OUT_MUTE); + # define KSAUDFNAME_MONO_OUT_MUTE DEFINE_GUIDNAMED(KSAUDFNAME_MONO_OUT_MUTE) + + # define STATIC_KSAUDFNAME_STEREO_MIX_VOLUME \ + 0x1ad247edL, 0x96e3, 0x11d2, 0xac, 0x4c, 0x0, 0xc0, 0x4f, 0x8e, 0xfb, 0x68 +DEFINE_GUIDSTRUCT("1AD247ED-96E3-11d2-AC4C-00C04F8EFB68", KSAUDFNAME_STEREO_MIX_VOLUME); + # define KSAUDFNAME_STEREO_MIX_VOLUME DEFINE_GUIDNAMED(KSAUDFNAME_STEREO_MIX_VOLUME) + + # define STATIC_KSAUDFNAME_STEREO_MIX_MUTE \ + 0x22b0eafdL, 0x96e3, 0x11d2, 0xac, 0x4c, 0x0, 0xc0, 0x4f, 0x8e, 0xfb, 0x68 +DEFINE_GUIDSTRUCT("22B0EAFD-96E3-11d2-AC4C-00C04F8EFB68", KSAUDFNAME_STEREO_MIX_MUTE); + # define KSAUDFNAME_STEREO_MIX_MUTE DEFINE_GUIDNAMED(KSAUDFNAME_STEREO_MIX_MUTE) + + # define STATIC_KSAUDFNAME_MONO_MIX_VOLUME \ + 0x22b0eafeL, 0x96e3, 0x11d2, 0xac, 0x4c, 0x0, 0xc0, 0x4f, 0x8e, 0xfb, 0x68 +DEFINE_GUIDSTRUCT("22B0EAFE-96E3-11d2-AC4C-00C04F8EFB68", KSAUDFNAME_MONO_MIX_VOLUME); + # define KSAUDFNAME_MONO_MIX_VOLUME DEFINE_GUIDNAMED(KSAUDFNAME_MONO_MIX_VOLUME) + + # define STATIC_KSAUDFNAME_MONO_MIX_MUTE \ + 0x2bc31d69L, 0x96e3, 0x11d2, 0xac, 0x4c, 0x0, 0xc0, 0x4f, 0x8e, 0xfb, 0x68 +DEFINE_GUIDSTRUCT("2BC31D69-96E3-11d2-AC4C-00C04F8EFB68", KSAUDFNAME_MONO_MIX_MUTE); + # define KSAUDFNAME_MONO_MIX_MUTE DEFINE_GUIDNAMED(KSAUDFNAME_MONO_MIX_MUTE) + + # define STATIC_KSAUDFNAME_MICROPHONE_BOOST \ + 0x2bc31d6aL, 0x96e3, 0x11d2, 0xac, 0x4c, 0x0, 0xc0, 0x4f, 0x8e, 0xfb, 0x68 +DEFINE_GUIDSTRUCT("2BC31D6A-96E3-11d2-AC4C-00C04F8EFB68", KSAUDFNAME_MICROPHONE_BOOST); + # define KSAUDFNAME_MICROPHONE_BOOST DEFINE_GUIDNAMED(KSAUDFNAME_MICROPHONE_BOOST) + + # define STATIC_KSAUDFNAME_ALTERNATE_MICROPHONE \ + 0x2bc31d6bL, 0x96e3, 0x11d2, 0xac, 0x4c, 0x0, 0xc0, 0x4f, 0x8e, 0xfb, 0x68 +DEFINE_GUIDSTRUCT("2BC31D6B-96E3-11d2-AC4C-00C04F8EFB68", KSAUDFNAME_ALTERNATE_MICROPHONE); + # define KSAUDFNAME_ALTERNATE_MICROPHONE DEFINE_GUIDNAMED(KSAUDFNAME_ALTERNATE_MICROPHONE) + + # define STATIC_KSAUDFNAME_3D_DEPTH \ + 0x63ff5747L, 0x991f, 0x11d2, 0xac, 0x4d, 0x0, 0xc0, 0x4f, 0x8e, 0xfb, 0x68 +DEFINE_GUIDSTRUCT("63FF5747-991F-11d2-AC4D-00C04F8EFB68", KSAUDFNAME_3D_DEPTH); + # define KSAUDFNAME_3D_DEPTH DEFINE_GUIDNAMED(KSAUDFNAME_3D_DEPTH) + + # define STATIC_KSAUDFNAME_3D_CENTER \ + 0x9f0670b4L, 0x991f, 0x11d2, 0xac, 0x4d, 0x0, 0xc0, 0x4f, 0x8e, 0xfb, 0x68 +DEFINE_GUIDSTRUCT("9F0670B4-991F-11d2-AC4D-00C04F8EFB68", KSAUDFNAME_3D_CENTER); + # define KSAUDFNAME_3D_CENTER DEFINE_GUIDNAMED(KSAUDFNAME_3D_CENTER) + + # define STATIC_KSAUDFNAME_VIDEO_VOLUME \ + 0x9b46e708L, 0x992a, 0x11d2, 0xac, 0x4d, 0x0, 0xc0, 0x4f, 0x8e, 0xfb, 0x68 +DEFINE_GUIDSTRUCT("9B46E708-992A-11d2-AC4D-00C04F8EFB68", KSAUDFNAME_VIDEO_VOLUME); + # define KSAUDFNAME_VIDEO_VOLUME DEFINE_GUIDNAMED(KSAUDFNAME_VIDEO_VOLUME) + + # define STATIC_KSAUDFNAME_VIDEO_MUTE \ + 0x9b46e709L, 0x992a, 0x11d2, 0xac, 0x4d, 0x0, 0xc0, 0x4f, 0x8e, 0xfb, 0x68 +DEFINE_GUIDSTRUCT("9B46E709-992A-11d2-AC4D-00C04F8EFB68", KSAUDFNAME_VIDEO_MUTE); + # define KSAUDFNAME_VIDEO_MUTE DEFINE_GUIDNAMED(KSAUDFNAME_VIDEO_MUTE) + + # define STATIC_KSAUDFNAME_VIDEO \ + 0x915daec4L, 0xa434, 0x11d2, 0xac, 0x52, 0x0, 0xc0, 0x4f, 0x8e, 0xfb, 0x68 +DEFINE_GUIDSTRUCT("915DAEC4-A434-11d2-AC52-00C04F8EFB68", KSAUDFNAME_VIDEO); + # define KSAUDFNAME_VIDEO DEFINE_GUIDNAMED(KSAUDFNAME_VIDEO) + + # define STATIC_KSAUDFNAME_PEAKMETER \ + 0x57e24340L, 0xfc5b, 0x4612, 0xa5, 0x62, 0x72, 0xb1, 0x1a, 0x29, 0xdf, 0xae +DEFINE_GUIDSTRUCT("57E24340-FC5B-4612-A562-72B11A29DFAE", KSAUDFNAME_PEAKMETER); + # define KSAUDFNAME_PEAKMETER DEFINE_GUIDNAMED(KSAUDFNAME_PEAKMETER) + + # define KSNODEPIN_STANDARD_IN 1 + # define KSNODEPIN_STANDARD_OUT 0 + + # define KSNODEPIN_SUM_MUX_IN 1 + # define KSNODEPIN_SUM_MUX_OUT 0 + + # define KSNODEPIN_DEMUX_IN 0 + # define KSNODEPIN_DEMUX_OUT 1 + + # define KSNODEPIN_AEC_RENDER_IN 1 + # define KSNODEPIN_AEC_RENDER_OUT 0 + # define KSNODEPIN_AEC_CAPTURE_IN 2 + # define KSNODEPIN_AEC_CAPTURE_OUT 3 + + # define STATIC_KSMETHODSETID_Wavetable \ + 0xDCEF31EBL, 0xD907, 0x11D0, 0x95, 0x83, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3 +DEFINE_GUIDSTRUCT("DCEF31EB-D907-11D0-9583-00C04FB925D3", KSMETHODSETID_Wavetable); + # define KSMETHODSETID_Wavetable DEFINE_GUIDNAMED(KSMETHODSETID_Wavetable) + +typedef enum +{ + KSMETHOD_WAVETABLE_WAVE_ALLOC, + KSMETHOD_WAVETABLE_WAVE_FREE, + KSMETHOD_WAVETABLE_WAVE_FIND, + KSMETHOD_WAVETABLE_WAVE_WRITE +}KSMETHOD_WAVETABLE; + +typedef struct +{ + KSIDENTIFIER Identifier; + ULONG Size; + WINBOOL Looped; + ULONG LoopPoint; + WINBOOL InROM; + KSDATAFORMAT Format; +}KSWAVETABLE_WAVE_DESC, * PKSWAVETABLE_WAVE_DESC; + + # define STATIC_KSPROPSETID_Acoustic_Echo_Cancel \ + 0xd7a4af8bL, 0x3dc1, 0x4902, 0x91, 0xea, 0x8a, 0x15, 0xc9, 0x0e, 0x05, 0xb2 +DEFINE_GUIDSTRUCT("D7A4AF8B-3DC1-4902-91EA-8A15C90E05B2", KSPROPSETID_Acoustic_Echo_Cancel); + # define KSPROPSETID_Acoustic_Echo_Cancel DEFINE_GUIDNAMED(KSPROPSETID_Acoustic_Echo_Cancel) + +typedef enum +{ + KSPROPERTY_AEC_NOISE_FILL_ENABLE = 0, + KSPROPERTY_AEC_STATUS, + KSPROPERTY_AEC_MODE +}KSPROPERTY_AEC; + + # define AEC_STATUS_FD_HISTORY_UNINITIALIZED 0x0 + # define AEC_STATUS_FD_HISTORY_CONTINUOUSLY_CONVERGED 0x1 + # define AEC_STATUS_FD_HISTORY_PREVIOUSLY_DIVERGED 0x2 + # define AEC_STATUS_FD_CURRENTLY_CONVERGED 0x8 + + # define AEC_MODE_PASS_THROUGH 0x0 + # define AEC_MODE_HALF_DUPLEX 0x1 + # define AEC_MODE_FULL_DUPLEX 0x2 + + # define STATIC_KSPROPSETID_Wave \ + 0x924e54b0L, 0x630f, 0x11cf, 0xad, 0xa7, 0x08, 0x00, 0x3e, 0x30, 0x49, 0x4a +DEFINE_GUIDSTRUCT("924e54b0-630f-11cf-ada7-08003e30494a", KSPROPSETID_Wave); + # define KSPROPSETID_Wave DEFINE_GUIDNAMED(KSPROPSETID_Wave) + +typedef enum +{ + KSPROPERTY_WAVE_COMPATIBLE_CAPABILITIES, + KSPROPERTY_WAVE_INPUT_CAPABILITIES, + KSPROPERTY_WAVE_OUTPUT_CAPABILITIES, + KSPROPERTY_WAVE_BUFFER, + KSPROPERTY_WAVE_FREQUENCY, + KSPROPERTY_WAVE_VOLUME, + KSPROPERTY_WAVE_PAN +}KSPROPERTY_WAVE; + +typedef struct +{ + ULONG ulDeviceType; +}KSWAVE_COMPATCAPS, * PKSWAVE_COMPATCAPS; + + # define KSWAVE_COMPATCAPS_INPUT 0x00000000 + # define KSWAVE_COMPATCAPS_OUTPUT 0x00000001 + +typedef struct +{ + ULONG MaximumChannelsPerConnection; + ULONG MinimumBitsPerSample; + ULONG MaximumBitsPerSample; + ULONG MinimumSampleFrequency; + ULONG MaximumSampleFrequency; + ULONG TotalConnections; + ULONG ActiveConnections; +}KSWAVE_INPUT_CAPABILITIES, * PKSWAVE_INPUT_CAPABILITIES; + +typedef struct +{ + ULONG MaximumChannelsPerConnection; + ULONG MinimumBitsPerSample; + ULONG MaximumBitsPerSample; + ULONG MinimumSampleFrequency; + ULONG MaximumSampleFrequency; + ULONG TotalConnections; + ULONG StaticConnections; + ULONG StreamingConnections; + ULONG ActiveConnections; + ULONG ActiveStaticConnections; + ULONG ActiveStreamingConnections; + ULONG Total3DConnections; + ULONG Static3DConnections; + ULONG Streaming3DConnections; + ULONG Active3DConnections; + ULONG ActiveStatic3DConnections; + ULONG ActiveStreaming3DConnections; + ULONG TotalSampleMemory; + ULONG FreeSampleMemory; + ULONG LargestFreeContiguousSampleMemory; +}KSWAVE_OUTPUT_CAPABILITIES, * PKSWAVE_OUTPUT_CAPABILITIES; + +typedef struct +{ + LONG LeftAttenuation; + LONG RightAttenuation; +}KSWAVE_VOLUME, * PKSWAVE_VOLUME; + + # define KSWAVE_BUFFER_ATTRIBUTEF_LOOPING 0x00000001 + # define KSWAVE_BUFFER_ATTRIBUTEF_STATIC 0x00000002 + +typedef struct +{ + ULONG Attributes; + ULONG BufferSize; + PVOID BufferAddress; +}KSWAVE_BUFFER, * PKSWAVE_BUFFER; + + # define STATIC_KSMUSIC_TECHNOLOGY_PORT \ + 0x86C92E60L, 0x62E8, 0x11CF, 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00 +DEFINE_GUIDSTRUCT("86C92E60-62E8-11CF-A5D6-28DB04C10000", KSMUSIC_TECHNOLOGY_PORT); + # define KSMUSIC_TECHNOLOGY_PORT DEFINE_GUIDNAMED(KSMUSIC_TECHNOLOGY_PORT) + + # define STATIC_KSMUSIC_TECHNOLOGY_SQSYNTH \ + 0x0ECF4380L, 0x62E9, 0x11CF, 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00 +DEFINE_GUIDSTRUCT("0ECF4380-62E9-11CF-A5D6-28DB04C10000", KSMUSIC_TECHNOLOGY_SQSYNTH); + # define KSMUSIC_TECHNOLOGY_SQSYNTH DEFINE_GUIDNAMED(KSMUSIC_TECHNOLOGY_SQSYNTH) + + # define STATIC_KSMUSIC_TECHNOLOGY_FMSYNTH \ + 0x252C5C80L, 0x62E9, 0x11CF, 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00 +DEFINE_GUIDSTRUCT("252C5C80-62E9-11CF-A5D6-28DB04C10000", KSMUSIC_TECHNOLOGY_FMSYNTH); + # define KSMUSIC_TECHNOLOGY_FMSYNTH DEFINE_GUIDNAMED(KSMUSIC_TECHNOLOGY_FMSYNTH) + + # define STATIC_KSMUSIC_TECHNOLOGY_WAVETABLE \ + 0x394EC7C0L, 0x62E9, 0x11CF, 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00 +DEFINE_GUIDSTRUCT("394EC7C0-62E9-11CF-A5D6-28DB04C10000", KSMUSIC_TECHNOLOGY_WAVETABLE); + # define KSMUSIC_TECHNOLOGY_WAVETABLE DEFINE_GUIDNAMED(KSMUSIC_TECHNOLOGY_WAVETABLE) + + # define STATIC_KSMUSIC_TECHNOLOGY_SWSYNTH \ + 0x37407736L, 0x3620, 0x11D1, 0x85, 0xD3, 0x00, 0x00, 0xF8, 0x75, 0x43, 0x80 +DEFINE_GUIDSTRUCT("37407736-3620-11D1-85D3-0000F8754380", KSMUSIC_TECHNOLOGY_SWSYNTH); + # define KSMUSIC_TECHNOLOGY_SWSYNTH DEFINE_GUIDNAMED(KSMUSIC_TECHNOLOGY_SWSYNTH) + + # define STATIC_KSPROPSETID_WaveTable \ + 0x8539E660L, 0x62E9, 0x11CF, 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00 +DEFINE_GUIDSTRUCT("8539E660-62E9-11CF-A5D6-28DB04C10000", KSPROPSETID_WaveTable); + # define KSPROPSETID_WaveTable DEFINE_GUIDNAMED(KSPROPSETID_WaveTable) + +typedef enum +{ + KSPROPERTY_WAVETABLE_LOAD_SAMPLE, + KSPROPERTY_WAVETABLE_UNLOAD_SAMPLE, + KSPROPERTY_WAVETABLE_MEMORY, + KSPROPERTY_WAVETABLE_VERSION +}KSPROPERTY_WAVETABLE; + +typedef struct +{ + KSDATARANGE DataRange; + GUID Technology; + ULONG Channels; + ULONG Notes; + ULONG ChannelMask; +}KSDATARANGE_MUSIC, * PKSDATARANGE_MUSIC; + + # define STATIC_KSEVENTSETID_Cyclic \ + 0x142C1AC0L, 0x072A, 0x11D0, 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00 +DEFINE_GUIDSTRUCT("142C1AC0-072A-11D0-A5D6-28DB04C10000", KSEVENTSETID_Cyclic); + # define KSEVENTSETID_Cyclic DEFINE_GUIDNAMED(KSEVENTSETID_Cyclic) + +typedef enum +{ + KSEVENT_CYCLIC_TIME_INTERVAL +}KSEVENT_CYCLIC_TIME; + + # define STATIC_KSPROPSETID_Cyclic \ + 0x3FFEAEA0L, 0x2BEE, 0x11CF, 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00 +DEFINE_GUIDSTRUCT("3FFEAEA0-2BEE-11CF-A5D6-28DB04C10000", KSPROPSETID_Cyclic); + # define KSPROPSETID_Cyclic DEFINE_GUIDNAMED(KSPROPSETID_Cyclic) + +typedef enum +{ + KSPROPERTY_CYCLIC_POSITION +}KSPROPERTY_CYCLIC; + + # define STATIC_KSEVENTSETID_AudioControlChange \ + 0xE85E9698L, 0xFA2F, 0x11D1, 0x95, 0xBD, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3 +DEFINE_GUIDSTRUCT("E85E9698-FA2F-11D1-95BD-00C04FB925D3", KSEVENTSETID_AudioControlChange); + # define KSEVENTSETID_AudioControlChange DEFINE_GUIDNAMED(KSEVENTSETID_AudioControlChange) + +typedef enum +{ + KSEVENT_CONTROL_CHANGE +}KSEVENT_AUDIO_CONTROL_CHANGE; + + # define STATIC_KSEVENTSETID_LoopedStreaming \ + 0x4682B940L, 0xC6EF, 0x11D0, 0x96, 0xD8, 0x00, 0xAA, 0x00, 0x51, 0xE5, 0x1D +DEFINE_GUIDSTRUCT("4682B940-C6EF-11D0-96D8-00AA0051E51D", KSEVENTSETID_LoopedStreaming); + # define KSEVENTSETID_LoopedStreaming DEFINE_GUIDNAMED(KSEVENTSETID_LoopedStreaming) + +typedef enum +{ + KSEVENT_LOOPEDSTREAMING_POSITION +}KSEVENT_LOOPEDSTREAMING; + +typedef struct +{ + KSEVENTDATA KsEventData; + DWORDLONG Position; +}LOOPEDSTREAMING_POSITION_EVENT_DATA, * PLOOPEDSTREAMING_POSITION_EVENT_DATA; + + # define STATIC_KSPROPSETID_Sysaudio \ + 0xCBE3FAA0L, 0xCC75, 0x11D0, 0xB4, 0x65, 0x00, 0x00, 0x1A, 0x18, 0x18, 0xE6 +DEFINE_GUIDSTRUCT("CBE3FAA0-CC75-11D0-B465-00001A1818E6", KSPROPSETID_Sysaudio); + # define KSPROPSETID_Sysaudio DEFINE_GUIDNAMED(KSPROPSETID_Sysaudio) + +typedef enum +{ + KSPROPERTY_SYSAUDIO_DEVICE_COUNT = 1, + KSPROPERTY_SYSAUDIO_DEVICE_FRIENDLY_NAME = 2, + KSPROPERTY_SYSAUDIO_DEVICE_INSTANCE = 3, + KSPROPERTY_SYSAUDIO_DEVICE_INTERFACE_NAME = 4, + KSPROPERTY_SYSAUDIO_SELECT_GRAPH = 5, + KSPROPERTY_SYSAUDIO_CREATE_VIRTUAL_SOURCE = 6, + KSPROPERTY_SYSAUDIO_DEVICE_DEFAULT = 7, + KSPROPERTY_SYSAUDIO_INSTANCE_INFO = 14, + KSPROPERTY_SYSAUDIO_COMPONENT_ID = 16 +}KSPROPERTY_SYSAUDIO; + +typedef struct +{ + KSPROPERTY Property; + GUID PinCategory; + GUID PinName; +}SYSAUDIO_CREATE_VIRTUAL_SOURCE, * PSYSAUDIO_CREATE_VIRTUAL_SOURCE; + +typedef struct +{ + KSPROPERTY Property; + ULONG PinId; + ULONG NodeId; + ULONG Flags; + ULONG Reserved; +}SYSAUDIO_SELECT_GRAPH, * PSYSAUDIO_SELECT_GRAPH; + +typedef struct +{ + KSPROPERTY Property; + ULONG Flags; + ULONG DeviceNumber; +}SYSAUDIO_INSTANCE_INFO, * PSYSAUDIO_INSTANCE_INFO; + + # define SYSAUDIO_FLAGS_DONT_COMBINE_PINS 0x00000001 + + # define STATIC_KSPROPSETID_Sysaudio_Pin \ + 0xA3A53220L, 0xC6E4, 0x11D0, 0xB4, 0x65, 0x00, 0x00, 0x1A, 0x18, 0x18, 0xE6 +DEFINE_GUIDSTRUCT("A3A53220-C6E4-11D0-B465-00001A1818E6", KSPROPSETID_Sysaudio_Pin); + # define KSPROPSETID_Sysaudio_Pin DEFINE_GUIDNAMED(KSPROPSETID_Sysaudio_Pin) + +typedef enum +{ + KSPROPERTY_SYSAUDIO_ATTACH_VIRTUAL_SOURCE = 1 +}KSPROPERTY_SYSAUDIO_PIN; + +typedef struct +{ + KSPROPERTY Property; + ULONG MixerPinId; + ULONG Reserved; +}SYSAUDIO_ATTACH_VIRTUAL_SOURCE, * PSYSAUDIO_ATTACH_VIRTUAL_SOURCE; + +typedef struct +{ + KSPROPERTY Property; + ULONG NodeId; + ULONG Reserved; +}KSNODEPROPERTY, * PKSNODEPROPERTY; + +typedef struct +{ + KSNODEPROPERTY NodeProperty; + LONG Channel; + ULONG Reserved; +}KSNODEPROPERTY_AUDIO_CHANNEL, * PKSNODEPROPERTY_AUDIO_CHANNEL; + +typedef struct +{ + KSNODEPROPERTY NodeProperty; + ULONG DevSpecificId; + ULONG DeviceInfo; + ULONG Length; +}KSNODEPROPERTY_AUDIO_DEV_SPECIFIC, * PKSNODEPROPERTY_AUDIO_DEV_SPECIFIC; + +typedef struct +{ + KSNODEPROPERTY NodeProperty; + PVOID ListenerId; + # ifndef _WIN64 + ULONG Reserved; + # endif +}KSNODEPROPERTY_AUDIO_3D_LISTENER, * PKSNODEPROPERTY_AUDIO_3D_LISTENER; + +typedef struct +{ + KSNODEPROPERTY NodeProperty; + PVOID AppContext; + ULONG Length; + # ifndef _WIN64 + ULONG Reserved; + # endif +}KSNODEPROPERTY_AUDIO_PROPERTY, * PKSNODEPROPERTY_AUDIO_PROPERTY; + + # define STATIC_KSPROPSETID_AudioGfx \ + 0x79a9312eL, 0x59ae, 0x43b0, 0xa3, 0x50, 0x8b, 0x5, 0x28, 0x4c, 0xab, 0x24 +DEFINE_GUIDSTRUCT("79A9312E-59AE-43b0-A350-8B05284CAB24", KSPROPSETID_AudioGfx); + # define KSPROPSETID_AudioGfx DEFINE_GUIDNAMED(KSPROPSETID_AudioGfx) + +typedef enum +{ + KSPROPERTY_AUDIOGFX_RENDERTARGETDEVICEID, + KSPROPERTY_AUDIOGFX_CAPTURETARGETDEVICEID +}KSPROPERTY_AUDIOGFX; + + # define STATIC_KSPROPSETID_Linear \ + 0x5A2FFE80L, 0x16B9, 0x11D0, 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00 +DEFINE_GUIDSTRUCT("5A2FFE80-16B9-11D0-A5D6-28DB04C10000", KSPROPSETID_Linear); + # define KSPROPSETID_Linear DEFINE_GUIDNAMED(KSPROPSETID_Linear) + +typedef enum +{ + KSPROPERTY_LINEAR_POSITION +}KSPROPERTY_LINEAR; + + # define STATIC_KSDATAFORMAT_TYPE_MUSIC \ + 0xE725D360L, 0x62CC, 0x11CF, { 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00 } +DEFINE_GUIDSTRUCT("E725D360-62CC-11CF-A5D6-28DB04C10000", KSDATAFORMAT_TYPE_MUSIC); + # define KSDATAFORMAT_TYPE_MUSIC DEFINE_GUIDNAMED(KSDATAFORMAT_TYPE_MUSIC) + + # define STATIC_KSDATAFORMAT_TYPE_MIDI \ + 0x7364696DL, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 +DEFINE_GUIDSTRUCT("7364696D-0000-0010-8000-00aa00389b71", KSDATAFORMAT_TYPE_MIDI); + # define KSDATAFORMAT_TYPE_MIDI DEFINE_GUIDNAMED(KSDATAFORMAT_TYPE_MIDI) + + # define STATIC_KSDATAFORMAT_SUBTYPE_MIDI \ + 0x1D262760L, 0xE957, 0x11CF, { 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00 } +DEFINE_GUIDSTRUCT("1D262760-E957-11CF-A5D6-28DB04C10000", KSDATAFORMAT_SUBTYPE_MIDI); + # define KSDATAFORMAT_SUBTYPE_MIDI DEFINE_GUIDNAMED(KSDATAFORMAT_SUBTYPE_MIDI) + + # define STATIC_KSDATAFORMAT_SUBTYPE_MIDI_BUS \ + 0x2CA15FA0L, 0x6CFE, 0x11CF, 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00 +DEFINE_GUIDSTRUCT("2CA15FA0-6CFE-11CF-A5D6-28DB04C10000", KSDATAFORMAT_SUBTYPE_MIDI_BUS); + # define KSDATAFORMAT_SUBTYPE_MIDI_BUS DEFINE_GUIDNAMED(KSDATAFORMAT_SUBTYPE_MIDI_BUS) + + # define STATIC_KSDATAFORMAT_SUBTYPE_RIFFMIDI \ + 0x4995DAF0L, 0x9EE6, 0x11D0, 0xA4, 0x0E, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96 +DEFINE_GUIDSTRUCT("4995DAF0-9EE6-11D0-A40E-00A0C9223196", KSDATAFORMAT_SUBTYPE_RIFFMIDI); + # define KSDATAFORMAT_SUBTYPE_RIFFMIDI DEFINE_GUIDNAMED(KSDATAFORMAT_SUBTYPE_RIFFMIDI) + +typedef struct +{ + ULONG TimeDeltaMs; + + ULONG ByteCount; +}KSMUSICFORMAT, * PKSMUSICFORMAT; + + # define STATIC_KSDATAFORMAT_TYPE_STANDARD_ELEMENTARY_STREAM \ + 0x36523b11L, 0x8ee5, 0x11d1, 0x8c, 0xa3, 0x00, 0x60, 0xb0, 0x57, 0x66, 0x4a +DEFINE_GUIDSTRUCT("36523B11-8EE5-11d1-8CA3-0060B057664A", KSDATAFORMAT_TYPE_STANDARD_ELEMENTARY_STREAM); + # define KSDATAFORMAT_TYPE_STANDARD_ELEMENTARY_STREAM DEFINE_GUIDNAMED(KSDATAFORMAT_TYPE_STANDARD_ELEMENTARY_STREAM) + + # define STATIC_KSDATAFORMAT_TYPE_STANDARD_PES_PACKET \ + 0x36523b12L, 0x8ee5, 0x11d1, 0x8c, 0xa3, 0x00, 0x60, 0xb0, 0x57, 0x66, 0x4a +DEFINE_GUIDSTRUCT("36523B12-8EE5-11d1-8CA3-0060B057664A", KSDATAFORMAT_TYPE_STANDARD_PES_PACKET); + # define KSDATAFORMAT_TYPE_STANDARD_PES_PACKET DEFINE_GUIDNAMED(KSDATAFORMAT_TYPE_STANDARD_PES_PACKET) + + # define STATIC_KSDATAFORMAT_TYPE_STANDARD_PACK_HEADER \ + 0x36523b13L, 0x8ee5, 0x11d1, 0x8c, 0xa3, 0x00, 0x60, 0xb0, 0x57, 0x66, 0x4a +DEFINE_GUIDSTRUCT("36523B13-8EE5-11d1-8CA3-0060B057664A", KSDATAFORMAT_TYPE_STANDARD_PACK_HEADER); + # define KSDATAFORMAT_TYPE_STANDARD_PACK_HEADER DEFINE_GUIDNAMED(KSDATAFORMAT_TYPE_STANDARD_PACK_HEADER) + + # define STATIC_KSDATAFORMAT_SUBTYPE_STANDARD_MPEG1_VIDEO \ + 0x36523b21L, 0x8ee5, 0x11d1, 0x8c, 0xa3, 0x00, 0x60, 0xb0, 0x57, 0x66, 0x4a +DEFINE_GUIDSTRUCT("36523B21-8EE5-11d1-8CA3-0060B057664A", KSDATAFORMAT_SUBTYPE_STANDARD_MPEG1_VIDEO); + # define KSDATAFORMAT_SUBTYPE_STANDARD_MPEG1_VIDEO DEFINE_GUIDNAMED(KSDATAFORMAT_SUBTYPE_STANDARD_MPEG1_VIDEO) + + # define STATIC_KSDATAFORMAT_SUBTYPE_STANDARD_MPEG1_AUDIO \ + 0x36523b22L, 0x8ee5, 0x11d1, 0x8c, 0xa3, 0x00, 0x60, 0xb0, 0x57, 0x66, 0x4a +DEFINE_GUIDSTRUCT("36523B22-8EE5-11d1-8CA3-0060B057664A", KSDATAFORMAT_SUBTYPE_STANDARD_MPEG1_AUDIO); + # define KSDATAFORMAT_SUBTYPE_STANDARD_MPEG1_AUDIO DEFINE_GUIDNAMED(KSDATAFORMAT_SUBTYPE_STANDARD_MPEG1_AUDIO) + + # define STATIC_KSDATAFORMAT_SUBTYPE_STANDARD_MPEG2_VIDEO \ + 0x36523b23L, 0x8ee5, 0x11d1, 0x8c, 0xa3, 0x00, 0x60, 0xb0, 0x57, 0x66, 0x4a +DEFINE_GUIDSTRUCT("36523B23-8EE5-11d1-8CA3-0060B057664A", KSDATAFORMAT_SUBTYPE_STANDARD_MPEG2_VIDEO); + # define KSDATAFORMAT_SUBTYPE_STANDARD_MPEG2_VIDEO DEFINE_GUIDNAMED(KSDATAFORMAT_SUBTYPE_STANDARD_MPEG2_VIDEO) + + # define STATIC_KSDATAFORMAT_SUBTYPE_STANDARD_MPEG2_AUDIO \ + 0x36523b24L, 0x8ee5, 0x11d1, 0x8c, 0xa3, 0x00, 0x60, 0xb0, 0x57, 0x66, 0x4a +DEFINE_GUIDSTRUCT("36523B24-8EE5-11d1-8CA3-0060B057664A", KSDATAFORMAT_SUBTYPE_STANDARD_MPEG2_AUDIO); + # define KSDATAFORMAT_SUBTYPE_STANDARD_MPEG2_AUDIO DEFINE_GUIDNAMED(KSDATAFORMAT_SUBTYPE_STANDARD_MPEG2_AUDIO) + + # define STATIC_KSDATAFORMAT_SUBTYPE_STANDARD_AC3_AUDIO \ + 0x36523b25L, 0x8ee5, 0x11d1, 0x8c, 0xa3, 0x00, 0x60, 0xb0, 0x57, 0x66, 0x4a +DEFINE_GUIDSTRUCT("36523B25-8EE5-11d1-8CA3-0060B057664A", KSDATAFORMAT_SUBTYPE_STANDARD_AC3_AUDIO); + # define KSDATAFORMAT_SUBTYPE_STANDARD_AC3_AUDIO DEFINE_GUIDNAMED(KSDATAFORMAT_SUBTYPE_STANDARD_AC3_AUDIO) + + # define STATIC_KSDATAFORMAT_SPECIFIER_DIALECT_MPEG1_VIDEO \ + 0x36523b31L, 0x8ee5, 0x11d1, 0x8c, 0xa3, 0x00, 0x60, 0xb0, 0x57, 0x66, 0x4a +DEFINE_GUIDSTRUCT("36523B31-8EE5-11d1-8CA3-0060B057664A", KSDATAFORMAT_SPECIFIER_DIALECT_MPEG1_VIDEO); + # define KSDATAFORMAT_SPECIFIER_DIALECT_MPEG1_VIDEO DEFINE_GUIDNAMED(KSDATAFORMAT_SPECIFIER_DIALECT_MPEG1_VIDEO) + + # define STATIC_KSDATAFORMAT_SPECIFIER_DIALECT_MPEG1_AUDIO \ + 0x36523b32L, 0x8ee5, 0x11d1, 0x8c, 0xa3, 0x00, 0x60, 0xb0, 0x57, 0x66, 0x4a +DEFINE_GUIDSTRUCT("36523B32-8EE5-11d1-8CA3-0060B057664A", KSDATAFORMAT_SPECIFIER_DIALECT_MPEG1_AUDIO); + # define KSDATAFORMAT_SPECIFIER_DIALECT_MPEG1_AUDIO DEFINE_GUIDNAMED(KSDATAFORMAT_SPECIFIER_DIALECT_MPEG1_AUDIO) + + # define STATIC_KSDATAFORMAT_SPECIFIER_DIALECT_MPEG2_VIDEO \ + 0x36523b33L, 0x8ee5, 0x11d1, 0x8c, 0xa3, 0x00, 0x60, 0xb0, 0x57, 0x66, 0x4a +DEFINE_GUIDSTRUCT("36523B33-8EE5-11d1-8CA3-0060B057664A", KSDATAFORMAT_SPECIFIER_DIALECT_MPEG2_VIDEO); + # define KSDATAFORMAT_SPECIFIER_DIALECT_MPEG2_VIDEO DEFINE_GUIDNAMED(KSDATAFORMAT_SPECIFIER_DIALECT_MPEG2_VIDEO) + + # define STATIC_KSDATAFORMAT_SPECIFIER_DIALECT_MPEG2_AUDIO \ + 0x36523b34L, 0x8ee5, 0x11d1, 0x8c, 0xa3, 0x00, 0x60, 0xb0, 0x57, 0x66, 0x4a +DEFINE_GUIDSTRUCT("36523B34-8EE5-11d1-8CA3-0060B057664A", KSDATAFORMAT_SPECIFIER_DIALECT_MPEG2_AUDIO); + # define KSDATAFORMAT_SPECIFIER_DIALECT_MPEG2_AUDIO DEFINE_GUIDNAMED(KSDATAFORMAT_SPECIFIER_DIALECT_MPEG2_AUDIO) + + # define STATIC_KSDATAFORMAT_SPECIFIER_DIALECT_AC3_AUDIO \ + 0x36523b35L, 0x8ee5, 0x11d1, 0x8c, 0xa3, 0x00, 0x60, 0xb0, 0x57, 0x66, 0x4a +DEFINE_GUIDSTRUCT("36523B35-8EE5-11d1-8CA3-0060B057664A", KSDATAFORMAT_SPECIFIER_DIALECT_AC3_AUDIO); + # define KSDATAFORMAT_SPECIFIER_DIALECT_AC3_AUDIO DEFINE_GUIDNAMED(KSDATAFORMAT_SPECIFIER_DIALECT_AC3_AUDIO) + + # define STATIC_KSDATAFORMAT_SUBTYPE_DSS_VIDEO \ + 0xa0af4f81L, 0xe163, 0x11d0, 0xba, 0xd9, 0x00, 0x60, 0x97, 0x44, 0x11, 0x1a +DEFINE_GUIDSTRUCT("a0af4f81-e163-11d0-bad9-00609744111a", KSDATAFORMAT_SUBTYPE_DSS_VIDEO); + # define KSDATAFORMAT_SUBTYPE_DSS_VIDEO DEFINE_GUIDNAMED(KSDATAFORMAT_SUBTYPE_DSS_VIDEO) + + # define STATIC_KSDATAFORMAT_SUBTYPE_DSS_AUDIO \ + 0xa0af4f82L, 0xe163, 0x11d0, 0xba, 0xd9, 0x00, 0x60, 0x97, 0x44, 0x11, 0x1a +DEFINE_GUIDSTRUCT("a0af4f82-e163-11d0-bad9-00609744111a", KSDATAFORMAT_SUBTYPE_DSS_AUDIO); + # define KSDATAFORMAT_SUBTYPE_DSS_AUDIO DEFINE_GUIDNAMED(KSDATAFORMAT_SUBTYPE_DSS_AUDIO) + + # define STATIC_KSDATAFORMAT_SUBTYPE_MPEG1Packet \ + 0xe436eb80, 0x524f, 0x11ce, 0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70 +DEFINE_GUIDSTRUCT("e436eb80-524f-11ce-9F53-0020af0ba770", KSDATAFORMAT_SUBTYPE_MPEG1Packet); + # define KSDATAFORMAT_SUBTYPE_MPEG1Packet DEFINE_GUIDNAMED(KSDATAFORMAT_SUBTYPE_MPEG1Packet) + + # define STATIC_KSDATAFORMAT_SUBTYPE_MPEG1Payload \ + 0xe436eb81, 0x524f, 0x11ce, 0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70 +DEFINE_GUIDSTRUCT("e436eb81-524f-11ce-9F53-0020af0ba770", KSDATAFORMAT_SUBTYPE_MPEG1Payload); + # define KSDATAFORMAT_SUBTYPE_MPEG1Payload DEFINE_GUIDNAMED(KSDATAFORMAT_SUBTYPE_MPEG1Payload) + + # define STATIC_KSDATAFORMAT_SUBTYPE_MPEG1Video \ + 0xe436eb86, 0x524f, 0x11ce, 0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70 +DEFINE_GUIDSTRUCT("e436eb86-524f-11ce-9f53-0020af0ba770", KSDATAFORMAT_SUBTYPE_MPEG1Video); + # define KSDATAFORMAT_SUBTYPE_MPEG1Video DEFINE_GUIDNAMED(KSDATAFORMAT_SUBTYPE_MPEG1Video) + + # define STATIC_KSDATAFORMAT_SPECIFIER_MPEG1_VIDEO \ + 0x05589f82L, 0xc356, 0x11ce, 0xbf, 0x01, 0x00, 0xaa, 0x00, 0x55, 0x59, 0x5a +DEFINE_GUIDSTRUCT("05589f82-c356-11ce-bf01-00aa0055595a", KSDATAFORMAT_SPECIFIER_MPEG1_VIDEO); + # define KSDATAFORMAT_SPECIFIER_MPEG1_VIDEO DEFINE_GUIDNAMED(KSDATAFORMAT_SPECIFIER_MPEG1_VIDEO) + + # define STATIC_KSDATAFORMAT_TYPE_MPEG2_PES \ + 0xe06d8020L, 0xdb46, 0x11cf, 0xb4, 0xd1, 0x00, 0x80, 0x5f, 0x6c, 0xbb, 0xea +DEFINE_GUIDSTRUCT("e06d8020-db46-11cf-b4d1-00805f6cbbea", KSDATAFORMAT_TYPE_MPEG2_PES); + # define KSDATAFORMAT_TYPE_MPEG2_PES DEFINE_GUIDNAMED(KSDATAFORMAT_TYPE_MPEG2_PES) + + # define STATIC_KSDATAFORMAT_TYPE_MPEG2_PROGRAM \ + 0xe06d8022L, 0xdb46, 0x11cf, 0xb4, 0xd1, 0x00, 0x80, 0x5f, 0x6c, 0xbb, 0xea +DEFINE_GUIDSTRUCT("e06d8022-db46-11cf-b4d1-00805f6cbbea", KSDATAFORMAT_TYPE_MPEG2_PROGRAM); + # define KSDATAFORMAT_TYPE_MPEG2_PROGRAM DEFINE_GUIDNAMED(KSDATAFORMAT_TYPE_MPEG2_PROGRAM) + + # define STATIC_KSDATAFORMAT_TYPE_MPEG2_TRANSPORT \ + 0xe06d8023L, 0xdb46, 0x11cf, 0xb4, 0xd1, 0x00, 0x80, 0x5f, 0x6c, 0xbb, 0xea +DEFINE_GUIDSTRUCT("e06d8023-db46-11cf-b4d1-00805f6cbbea", KSDATAFORMAT_TYPE_MPEG2_TRANSPORT); + # define KSDATAFORMAT_TYPE_MPEG2_TRANSPORT DEFINE_GUIDNAMED(KSDATAFORMAT_TYPE_MPEG2_TRANSPORT) + + # define STATIC_KSDATAFORMAT_SUBTYPE_MPEG2_VIDEO \ + 0xe06d8026L, 0xdb46, 0x11cf, 0xb4, 0xd1, 0x00, 0x80, 0x5f, 0x6c, 0xbb, 0xea +DEFINE_GUIDSTRUCT("e06d8026-db46-11cf-b4d1-00805f6cbbea", KSDATAFORMAT_SUBTYPE_MPEG2_VIDEO); + # define KSDATAFORMAT_SUBTYPE_MPEG2_VIDEO DEFINE_GUIDNAMED(KSDATAFORMAT_SUBTYPE_MPEG2_VIDEO) + + # define STATIC_KSDATAFORMAT_SPECIFIER_MPEG2_VIDEO \ + 0xe06d80e3L, 0xdb46, 0x11cf, 0xb4, 0xd1, 0x00, 0x80, 0x5f, 0x6c, 0xbb, 0xea +DEFINE_GUIDSTRUCT("e06d80e3-db46-11cf-b4d1-00805f6cbbea", KSDATAFORMAT_SPECIFIER_MPEG2_VIDEO); + # define KSDATAFORMAT_SPECIFIER_MPEG2_VIDEO DEFINE_GUIDNAMED(KSDATAFORMAT_SPECIFIER_MPEG2_VIDEO) + + # define STATIC_KSPROPSETID_Mpeg2Vid \ + 0xC8E11B60L, 0x0CC9, 0x11D0, 0xBD, 0x69, 0x00, 0x35, 0x05, 0xC1, 0x03, 0xA9 +DEFINE_GUIDSTRUCT("C8E11B60-0CC9-11D0-BD69-003505C103A9", KSPROPSETID_Mpeg2Vid); + # define KSPROPSETID_Mpeg2Vid DEFINE_GUIDNAMED(KSPROPSETID_Mpeg2Vid) + +typedef enum +{ + KSPROPERTY_MPEG2VID_MODES, + KSPROPERTY_MPEG2VID_CUR_MODE, + KSPROPERTY_MPEG2VID_4_3_RECT, + KSPROPERTY_MPEG2VID_16_9_RECT, + KSPROPERTY_MPEG2VID_16_9_PANSCAN +}KSPROPERTY_MPEG2VID; + + # define KSMPEGVIDMODE_PANSCAN 0x0001 + # define KSMPEGVIDMODE_LTRBOX 0x0002 + # define KSMPEGVIDMODE_SCALE 0x0004 + +typedef struct _KSMPEGVID_RECT +{ + ULONG StartX; + ULONG StartY; + ULONG EndX; + ULONG EndY; +}KSMPEGVID_RECT, * PKSMPEGVID_RECT; + + # define STATIC_KSDATAFORMAT_SUBTYPE_MPEG2_AUDIO \ + 0xe06d802bL, 0xdb46, 0x11cf, 0xb4, 0xd1, 0x00, 0x80, 0x5f, 0x6c, 0xbb, 0xea +DEFINE_GUIDSTRUCT("e06d802b-db46-11cf-b4d1-00805f6cbbea", KSDATAFORMAT_SUBTYPE_MPEG2_AUDIO); + # define KSDATAFORMAT_SUBTYPE_MPEG2_AUDIO DEFINE_GUIDNAMED(KSDATAFORMAT_SUBTYPE_MPEG2_AUDIO) + + # define STATIC_KSDATAFORMAT_SPECIFIER_MPEG2_AUDIO \ + 0xe06d80e5L, 0xdb46, 0x11cf, 0xb4, 0xd1, 0x00, 0x80, 0x5f, 0x6c, 0xbb, 0xea +DEFINE_GUIDSTRUCT("e06d80e5-db46-11cf-b4d1-00805f6cbbea", KSDATAFORMAT_SPECIFIER_MPEG2_AUDIO); + # define KSDATAFORMAT_SPECIFIER_MPEG2_AUDIO DEFINE_GUIDNAMED(KSDATAFORMAT_SPECIFIER_MPEG2_AUDIO) + + # define STATIC_KSDATAFORMAT_SUBTYPE_LPCM_AUDIO \ + 0xe06d8032L, 0xdb46, 0x11cf, 0xb4, 0xd1, 0x00, 0x80, 0x5f, 0x6c, 0xbb, 0xea +DEFINE_GUIDSTRUCT("e06d8032-db46-11cf-b4d1-00805f6cbbea", KSDATAFORMAT_SUBTYPE_LPCM_AUDIO); + # define KSDATAFORMAT_SUBTYPE_LPCM_AUDIO DEFINE_GUIDNAMED(KSDATAFORMAT_SUBTYPE_LPCM_AUDIO) + + # define STATIC_KSDATAFORMAT_SPECIFIER_LPCM_AUDIO \ + 0xe06d80e6L, 0xdb46, 0x11cf, 0xb4, 0xd1, 0x00, 0x80, 0x5f, 0x6c, 0xbb, 0xea +DEFINE_GUIDSTRUCT("e06d80e6-db46-11cf-b4d1-00805f6cbbea", KSDATAFORMAT_SPECIFIER_LPCM_AUDIO); + # define KSDATAFORMAT_SPECIFIER_LPCM_AUDIO DEFINE_GUIDNAMED(KSDATAFORMAT_SPECIFIER_LPCM_AUDIO) + + # define STATIC_KSDATAFORMAT_SUBTYPE_AC3_AUDIO \ + 0xe06d802cL, 0xdb46, 0x11cf, 0xb4, 0xd1, 0x00, 0x80, 0x5f, 0x6c, 0xbb, 0xea +DEFINE_GUIDSTRUCT("e06d802c-db46-11cf-b4d1-00805f6cbbea", KSDATAFORMAT_SUBTYPE_AC3_AUDIO); + # define KSDATAFORMAT_SUBTYPE_AC3_AUDIO DEFINE_GUIDNAMED(KSDATAFORMAT_SUBTYPE_AC3_AUDIO) + + # define STATIC_KSDATAFORMAT_SPECIFIER_AC3_AUDIO \ + 0xe06d80e4L, 0xdb46, 0x11cf, 0xb4, 0xd1, 0x00, 0x80, 0x5f, 0x6c, 0xbb, 0xea +DEFINE_GUIDSTRUCT("e06d80e4-db46-11cf-b4d1-00805f6cbbea", KSDATAFORMAT_SPECIFIER_AC3_AUDIO); + # define KSDATAFORMAT_SPECIFIER_AC3_AUDIO DEFINE_GUIDNAMED(KSDATAFORMAT_SPECIFIER_AC3_AUDIO) + + # define STATIC_KSPROPSETID_AC3 \ + 0xBFABE720L, 0x6E1F, 0x11D0, 0xBC, 0xF2, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00 +DEFINE_GUIDSTRUCT("BFABE720-6E1F-11D0-BCF2-444553540000", KSPROPSETID_AC3); + # define KSPROPSETID_AC3 DEFINE_GUIDNAMED(KSPROPSETID_AC3) + +typedef enum +{ + KSPROPERTY_AC3_ERROR_CONCEALMENT = 1, + KSPROPERTY_AC3_ALTERNATE_AUDIO, + KSPROPERTY_AC3_DOWNMIX, + KSPROPERTY_AC3_BIT_STREAM_MODE, + KSPROPERTY_AC3_DIALOGUE_LEVEL, + KSPROPERTY_AC3_LANGUAGE_CODE, + KSPROPERTY_AC3_ROOM_TYPE +}KSPROPERTY_AC3; + +typedef struct +{ + WINBOOL fRepeatPreviousBlock; + WINBOOL fErrorInCurrentBlock; +}KSAC3_ERROR_CONCEALMENT, * PKSAC3_ERROR_CONCEALMENT; + +typedef struct +{ + WINBOOL fStereo; + ULONG DualMode; +}KSAC3_ALTERNATE_AUDIO, * PKSAC3_ALTERNATE_AUDIO; + + # define KSAC3_ALTERNATE_AUDIO_1 1 + # define KSAC3_ALTERNATE_AUDIO_2 2 + # define KSAC3_ALTERNATE_AUDIO_BOTH 3 + +typedef struct +{ + WINBOOL fDownMix; + WINBOOL fDolbySurround; +}KSAC3_DOWNMIX, * PKSAC3_DOWNMIX; + +typedef struct +{ + LONG BitStreamMode; +}KSAC3_BIT_STREAM_MODE, * PKSAC3_BIT_STREAM_MODE; + + # define KSAC3_SERVICE_MAIN_AUDIO 0 + # define KSAC3_SERVICE_NO_DIALOG 1 + # define KSAC3_SERVICE_VISUALLY_IMPAIRED 2 + # define KSAC3_SERVICE_HEARING_IMPAIRED 3 + # define KSAC3_SERVICE_DIALOG_ONLY 4 + # define KSAC3_SERVICE_COMMENTARY 5 + # define KSAC3_SERVICE_EMERGENCY_FLASH 6 + # define KSAC3_SERVICE_VOICE_OVER 7 + +typedef struct +{ + ULONG DialogueLevel; +}KSAC3_DIALOGUE_LEVEL, * PKSAC3_DIALOGUE_LEVEL; + +typedef struct +{ + WINBOOL fLargeRoom; +}KSAC3_ROOM_TYPE, * PKSAC3_ROOM_TYPE; + + # define STATIC_KSDATAFORMAT_SUBTYPE_DTS_AUDIO \ + 0xe06d8033L, 0xdb46, 0x11cf, 0xb4, 0xd1, 0x00, 0x80, 0x5f, 0x6c, 0xbb, 0xea +DEFINE_GUIDSTRUCT("e06d8033-db46-11cf-b4d1-00805f6cbbea", KSDATAFORMAT_SUBTYPE_DTS_AUDIO); + # define KSDATAFORMAT_SUBTYPE_DTS_AUDIO DEFINE_GUIDNAMED(KSDATAFORMAT_SUBTYPE_DTS_AUDIO) + + # define STATIC_KSDATAFORMAT_SUBTYPE_SDDS_AUDIO \ + 0xe06d8034L, 0xdb46, 0x11cf, 0xb4, 0xd1, 0x00, 0x80, 0x5f, 0x6c, 0xbb, 0xea +DEFINE_GUIDSTRUCT("e06d8034-db46-11cf-b4d1-00805f6cbbea", KSDATAFORMAT_SUBTYPE_SDDS_AUDIO); + # define KSDATAFORMAT_SUBTYPE_SDDS_AUDIO DEFINE_GUIDNAMED(KSDATAFORMAT_SUBTYPE_SDDS_AUDIO) + + # define STATIC_KSPROPSETID_AudioDecoderOut \ + 0x6ca6e020L, 0x43bd, 0x11d0, 0xbd, 0x6a, 0x00, 0x35, 0x05, 0xc1, 0x03, 0xa9 +DEFINE_GUIDSTRUCT("6ca6e020-43bd-11d0-bd6a-003505c103a9", KSPROPSETID_AudioDecoderOut); + # define KSPROPSETID_AudioDecoderOut DEFINE_GUIDNAMED(KSPROPSETID_AudioDecoderOut) + +typedef enum +{ + KSPROPERTY_AUDDECOUT_MODES, + KSPROPERTY_AUDDECOUT_CUR_MODE +}KSPROPERTY_AUDDECOUT; + + # define KSAUDDECOUTMODE_STEREO_ANALOG 0x0001 + # define KSAUDDECOUTMODE_PCM_51 0x0002 + # define KSAUDDECOUTMODE_SPDIFF 0x0004 + + # define STATIC_KSDATAFORMAT_SUBTYPE_SUBPICTURE \ + 0xe06d802dL, 0xdb46, 0x11cf, 0xb4, 0xd1, 0x00, 0x80, 0x5f, 0x6c, 0xbb, 0xea +DEFINE_GUIDSTRUCT("e06d802d-db46-11cf-b4d1-00805f6cbbea", KSDATAFORMAT_SUBTYPE_SUBPICTURE); + # define KSDATAFORMAT_SUBTYPE_SUBPICTURE DEFINE_GUIDNAMED(KSDATAFORMAT_SUBTYPE_SUBPICTURE) + + # define STATIC_KSPROPSETID_DvdSubPic \ + 0xac390460L, 0x43af, 0x11d0, 0xbd, 0x6a, 0x00, 0x35, 0x05, 0xc1, 0x03, 0xa9 +DEFINE_GUIDSTRUCT("ac390460-43af-11d0-bd6a-003505c103a9", KSPROPSETID_DvdSubPic); + # define KSPROPSETID_DvdSubPic DEFINE_GUIDNAMED(KSPROPSETID_DvdSubPic) + +typedef enum +{ + KSPROPERTY_DVDSUBPIC_PALETTE, + KSPROPERTY_DVDSUBPIC_HLI, + KSPROPERTY_DVDSUBPIC_COMPOSIT_ON +}KSPROPERTY_DVDSUBPIC; + +typedef struct _KS_DVD_YCrCb +{ + UCHAR Reserved; + UCHAR Y; + UCHAR Cr; + UCHAR Cb; +}KS_DVD_YCrCb, * PKS_DVD_YCrCb; + +typedef struct _KS_DVD_YUV +{ + UCHAR Reserved; + UCHAR Y; + UCHAR V; + UCHAR U; +}KS_DVD_YUV, * PKS_DVD_YUV; + +typedef struct _KSPROPERTY_SPPAL +{ + KS_DVD_YUV sppal[16]; +}KSPROPERTY_SPPAL, * PKSPROPERTY_SPPAL; + +typedef struct _KS_COLCON +{ + UCHAR emph1col : 4; + UCHAR emph2col : 4; + UCHAR backcol : 4; + UCHAR patcol : 4; + UCHAR emph1con : 4; + UCHAR emph2con : 4; + UCHAR backcon : 4; + UCHAR patcon : 4; +}KS_COLCON, * PKS_COLCON; + +typedef struct _KSPROPERTY_SPHLI +{ + USHORT HLISS; + USHORT Reserved; + ULONG StartPTM; + ULONG EndPTM; + USHORT StartX; + USHORT StartY; + USHORT StopX; + USHORT StopY; + KS_COLCON ColCon; +}KSPROPERTY_SPHLI, * PKSPROPERTY_SPHLI; + +typedef WINBOOL KSPROPERTY_COMPOSIT_ON, * PKSPROPERTY_COMPOSIT_ON; + + # define STATIC_KSPROPSETID_CopyProt \ + 0x0E8A0A40L, 0x6AEF, 0x11D0, 0x9E, 0xD0, 0x00, 0xA0, 0x24, 0xCA, 0x19, 0xB3 +DEFINE_GUIDSTRUCT("0E8A0A40-6AEF-11D0-9ED0-00A024CA19B3", KSPROPSETID_CopyProt); + # define KSPROPSETID_CopyProt DEFINE_GUIDNAMED(KSPROPSETID_CopyProt) + +typedef enum +{ + KSPROPERTY_DVDCOPY_CHLG_KEY = 0x01, + KSPROPERTY_DVDCOPY_DVD_KEY1, + KSPROPERTY_DVDCOPY_DEC_KEY2, + KSPROPERTY_DVDCOPY_TITLE_KEY, + KSPROPERTY_COPY_MACROVISION, + KSPROPERTY_DVDCOPY_REGION, + KSPROPERTY_DVDCOPY_SET_COPY_STATE, + KSPROPERTY_DVDCOPY_DISC_KEY = 0x80 +}KSPROPERTY_COPYPROT; + +typedef struct _KS_DVDCOPY_CHLGKEY +{ + BYTE ChlgKey[10]; + BYTE Reserved[2]; +}KS_DVDCOPY_CHLGKEY, * PKS_DVDCOPY_CHLGKEY; + +typedef struct _KS_DVDCOPY_BUSKEY +{ + BYTE BusKey[5]; + BYTE Reserved[1]; +}KS_DVDCOPY_BUSKEY, * PKS_DVDCOPY_BUSKEY; + +typedef struct _KS_DVDCOPY_DISCKEY +{ + BYTE DiscKey[2048]; +}KS_DVDCOPY_DISCKEY, * PKS_DVDCOPY_DISCKEY; + +typedef struct _KS_DVDCOPY_REGION +{ + UCHAR Reserved; + UCHAR RegionData; + UCHAR Reserved2[2]; +}KS_DVDCOPY_REGION, * PKS_DVDCOPY_REGION; + +typedef struct _KS_DVDCOPY_TITLEKEY +{ + ULONG KeyFlags; + ULONG ReservedNT[2]; + UCHAR TitleKey[6]; + UCHAR Reserved[2]; +}KS_DVDCOPY_TITLEKEY, * PKS_DVDCOPY_TITLEKEY; + +typedef struct _KS_COPY_MACROVISION +{ + ULONG MACROVISIONLevel; +}KS_COPY_MACROVISION, * PKS_COPY_MACROVISION; + +typedef struct _KS_DVDCOPY_SET_COPY_STATE +{ + ULONG DVDCopyState; +}KS_DVDCOPY_SET_COPY_STATE, * PKS_DVDCOPY_SET_COPY_STATE; + +typedef enum +{ + KS_DVDCOPYSTATE_INITIALIZE, + KS_DVDCOPYSTATE_INITIALIZE_TITLE, + KS_DVDCOPYSTATE_AUTHENTICATION_NOT_REQUIRED, + KS_DVDCOPYSTATE_AUTHENTICATION_REQUIRED, + KS_DVDCOPYSTATE_DONE +}KS_DVDCOPYSTATE; + +typedef enum +{ + KS_MACROVISION_DISABLED, + KS_MACROVISION_LEVEL1, + KS_MACROVISION_LEVEL2, + KS_MACROVISION_LEVEL3 +}KS_COPY_MACROVISION_LEVEL, * PKS_COPY_MACROVISION_LEVEL; + + # define KS_DVD_CGMS_RESERVED_MASK 0x00000078 + + # define KS_DVD_CGMS_COPY_PROTECT_MASK 0x00000018 + # define KS_DVD_CGMS_COPY_PERMITTED 0x00000000 + # define KS_DVD_CGMS_COPY_ONCE 0x00000010 + # define KS_DVD_CGMS_NO_COPY 0x00000018 + + # define KS_DVD_COPYRIGHT_MASK 0x00000040 + # define KS_DVD_NOT_COPYRIGHTED 0x00000000 + # define KS_DVD_COPYRIGHTED 0x00000040 + + # define KS_DVD_SECTOR_PROTECT_MASK 0x00000020 + # define KS_DVD_SECTOR_NOT_PROTECTED 0x00000000 + # define KS_DVD_SECTOR_PROTECTED 0x00000020 + + # define STATIC_KSCATEGORY_TVTUNER \ + 0xa799a800L, 0xa46d, 0x11d0, 0xa1, 0x8c, 0x00, 0xa0, 0x24, 0x01, 0xdc, 0xd4 +DEFINE_GUIDSTRUCT("a799a800-a46d-11d0-a18c-00a02401dcd4", KSCATEGORY_TVTUNER); + # define KSCATEGORY_TVTUNER DEFINE_GUIDNAMED(KSCATEGORY_TVTUNER) + + # define STATIC_KSCATEGORY_CROSSBAR \ + 0xa799a801L, 0xa46d, 0x11d0, 0xa1, 0x8c, 0x00, 0xa0, 0x24, 0x01, 0xdc, 0xd4 +DEFINE_GUIDSTRUCT("a799a801-a46d-11d0-a18c-00a02401dcd4", KSCATEGORY_CROSSBAR); + # define KSCATEGORY_CROSSBAR DEFINE_GUIDNAMED(KSCATEGORY_CROSSBAR) + + # define STATIC_KSCATEGORY_TVAUDIO \ + 0xa799a802L, 0xa46d, 0x11d0, 0xa1, 0x8c, 0x00, 0xa0, 0x24, 0x01, 0xdc, 0xd4 +DEFINE_GUIDSTRUCT("a799a802-a46d-11d0-a18c-00a02401dcd4", KSCATEGORY_TVAUDIO); + # define KSCATEGORY_TVAUDIO DEFINE_GUIDNAMED(KSCATEGORY_TVAUDIO) + + # define STATIC_KSCATEGORY_VPMUX \ + 0xa799a803L, 0xa46d, 0x11d0, 0xa1, 0x8c, 0x00, 0xa0, 0x24, 0x01, 0xdc, 0xd4 +DEFINE_GUIDSTRUCT("a799a803-a46d-11d0-a18c-00a02401dcd4", KSCATEGORY_VPMUX); + # define KSCATEGORY_VPMUX DEFINE_GUIDNAMED(KSCATEGORY_VPMUX) + + # define STATIC_KSCATEGORY_VBICODEC \ + 0x07dad660L, 0x22f1, 0x11d1, 0xa9, 0xf4, 0x00, 0xc0, 0x4f, 0xbb, 0xde, 0x8f +DEFINE_GUIDSTRUCT("07dad660-22f1-11d1-a9f4-00c04fbbde8f", KSCATEGORY_VBICODEC); + # define KSCATEGORY_VBICODEC DEFINE_GUIDNAMED(KSCATEGORY_VBICODEC) + + # define STATIC_KSDATAFORMAT_SUBTYPE_VPVideo \ + 0x5a9b6a40L, 0x1a22, 0x11d1, 0xba, 0xd9, 0x0, 0x60, 0x97, 0x44, 0x11, 0x1a +DEFINE_GUIDSTRUCT("5a9b6a40-1a22-11d1-bad9-00609744111a", KSDATAFORMAT_SUBTYPE_VPVideo); + # define KSDATAFORMAT_SUBTYPE_VPVideo DEFINE_GUIDNAMED(KSDATAFORMAT_SUBTYPE_VPVideo) + + # define STATIC_KSDATAFORMAT_SUBTYPE_VPVBI \ + 0x5a9b6a41L, 0x1a22, 0x11d1, 0xba, 0xd9, 0x0, 0x60, 0x97, 0x44, 0x11, 0x1a +DEFINE_GUIDSTRUCT("5a9b6a41-1a22-11d1-bad9-00609744111a", KSDATAFORMAT_SUBTYPE_VPVBI); + # define KSDATAFORMAT_SUBTYPE_VPVBI DEFINE_GUIDNAMED(KSDATAFORMAT_SUBTYPE_VPVBI) + + # define STATIC_KSDATAFORMAT_SPECIFIER_VIDEOINFO \ + 0x05589f80L, 0xc356, 0x11ce, 0xbf, 0x01, 0x00, 0xaa, 0x00, 0x55, 0x59, 0x5a +DEFINE_GUIDSTRUCT("05589f80-c356-11ce-bf01-00aa0055595a", KSDATAFORMAT_SPECIFIER_VIDEOINFO); + # define KSDATAFORMAT_SPECIFIER_VIDEOINFO DEFINE_GUIDNAMED(KSDATAFORMAT_SPECIFIER_VIDEOINFO) + + # define STATIC_KSDATAFORMAT_SPECIFIER_VIDEOINFO2 \ + 0xf72a76A0L, 0xeb0a, 0x11d0, 0xac, 0xe4, 0x00, 0x00, 0xc0, 0xcc, 0x16, 0xba +DEFINE_GUIDSTRUCT("f72a76A0-eb0a-11d0-ace4-0000c0cc16ba", KSDATAFORMAT_SPECIFIER_VIDEOINFO2); + # define KSDATAFORMAT_SPECIFIER_VIDEOINFO2 DEFINE_GUIDNAMED(KSDATAFORMAT_SPECIFIER_VIDEOINFO2) + + # define STATIC_KSDATAFORMAT_TYPE_ANALOGVIDEO \ + 0x0482dde1L, 0x7817, 0x11cf, 0x8a, 0x03, 0x00, 0xaa, 0x00, 0x6e, 0xcb, 0x65 +DEFINE_GUIDSTRUCT("0482dde1-7817-11cf-8a03-00aa006ecb65", KSDATAFORMAT_TYPE_ANALOGVIDEO); + # define KSDATAFORMAT_TYPE_ANALOGVIDEO DEFINE_GUIDNAMED(KSDATAFORMAT_TYPE_ANALOGVIDEO) + + # define STATIC_KSDATAFORMAT_SPECIFIER_ANALOGVIDEO \ + 0x0482dde0L, 0x7817, 0x11cf, 0x8a, 0x03, 0x00, 0xaa, 0x00, 0x6e, 0xcb, 0x65 +DEFINE_GUIDSTRUCT("0482dde0-7817-11cf-8a03-00aa006ecb65", KSDATAFORMAT_SPECIFIER_ANALOGVIDEO); + # define KSDATAFORMAT_SPECIFIER_ANALOGVIDEO DEFINE_GUIDNAMED(KSDATAFORMAT_SPECIFIER_ANALOGVIDEO) + + # define STATIC_KSDATAFORMAT_TYPE_ANALOGAUDIO \ + 0x0482dee1L, 0x7817, 0x11cf, 0x8a, 0x03, 0x00, 0xaa, 0x00, 0x6e, 0xcb, 0x65 +DEFINE_GUIDSTRUCT("0482DEE1-7817-11cf-8a03-00aa006ecb65", KSDATAFORMAT_TYPE_ANALOGAUDIO); + # define KSDATAFORMAT_TYPE_ANALOGAUDIO DEFINE_GUIDNAMED(KSDATAFORMAT_TYPE_ANALOGAUDIO) + + # define STATIC_KSDATAFORMAT_SPECIFIER_VBI \ + 0xf72a76e0L, 0xeb0a, 0x11d0, 0xac, 0xe4, 0x00, 0x00, 0xc0, 0xcc, 0x16, 0xba +DEFINE_GUIDSTRUCT("f72a76e0-eb0a-11d0-ace4-0000c0cc16ba", KSDATAFORMAT_SPECIFIER_VBI); + # define KSDATAFORMAT_SPECIFIER_VBI DEFINE_GUIDNAMED(KSDATAFORMAT_SPECIFIER_VBI) + + # define STATIC_KSDATAFORMAT_TYPE_VBI \ + 0xf72a76e1L, 0xeb0a, 0x11d0, 0xac, 0xe4, 0x00, 0x00, 0xc0, 0xcc, 0x16, 0xba +DEFINE_GUIDSTRUCT("f72a76e1-eb0a-11d0-ace4-0000c0cc16ba", KSDATAFORMAT_TYPE_VBI); + # define KSDATAFORMAT_TYPE_VBI DEFINE_GUIDNAMED(KSDATAFORMAT_TYPE_VBI) + + # define STATIC_KSDATAFORMAT_SUBTYPE_RAW8 \ + 0xca20d9a0, 0x3e3e, 0x11d1, 0x9b, 0xf9, 0x0, 0xc0, 0x4f, 0xbb, 0xde, 0xbf +DEFINE_GUIDSTRUCT("ca20d9a0-3e3e-11d1-9bf9-00c04fbbdebf", KSDATAFORMAT_SUBTYPE_RAW8); + # define KSDATAFORMAT_SUBTYPE_RAW8 DEFINE_GUIDNAMED(KSDATAFORMAT_SUBTYPE_RAW8) + + # define STATIC_KSDATAFORMAT_SUBTYPE_CC \ + 0x33214cc1, 0x11f, 0x11d2, 0xb4, 0xb1, 0x0, 0xa0, 0xd1, 0x2, 0xcf, 0xbe +DEFINE_GUIDSTRUCT("33214CC1-011F-11D2-B4B1-00A0D102CFBE", KSDATAFORMAT_SUBTYPE_CC); + # define KSDATAFORMAT_SUBTYPE_CC DEFINE_GUIDNAMED(KSDATAFORMAT_SUBTYPE_CC) + + # define STATIC_KSDATAFORMAT_SUBTYPE_NABTS \ + 0xf72a76e2L, 0xeb0a, 0x11d0, 0xac, 0xe4, 0x00, 0x00, 0xc0, 0xcc, 0x16, 0xba +DEFINE_GUIDSTRUCT("f72a76e2-eb0a-11d0-ace4-0000c0cc16ba", KSDATAFORMAT_SUBTYPE_NABTS); + # define KSDATAFORMAT_SUBTYPE_NABTS DEFINE_GUIDNAMED(KSDATAFORMAT_SUBTYPE_NABTS) + + # define STATIC_KSDATAFORMAT_SUBTYPE_TELETEXT \ + 0xf72a76e3L, 0xeb0a, 0x11d0, 0xac, 0xe4, 0x00, 0x00, 0xc0, 0xcc, 0x16, 0xba +DEFINE_GUIDSTRUCT("f72a76e3-eb0a-11d0-ace4-0000c0cc16ba", KSDATAFORMAT_SUBTYPE_TELETEXT); + # define KSDATAFORMAT_SUBTYPE_TELETEXT DEFINE_GUIDNAMED(KSDATAFORMAT_SUBTYPE_TELETEXT) + + # define KS_BI_RGB 0L + # define KS_BI_RLE8 1L + # define KS_BI_RLE4 2L + # define KS_BI_BITFIELDS 3L + +typedef struct tagKS_RGBQUAD +{ + BYTE rgbBlue; + BYTE rgbGreen; + BYTE rgbRed; + BYTE rgbReserved; +}KS_RGBQUAD, * PKS_RGBQUAD; + + # define KS_iPALETTE_COLORS 256 + # define KS_iEGA_COLORS 16 + # define KS_iMASK_COLORS 3 + # define KS_iTRUECOLOR 16 + # define KS_iRED 0 + # define KS_iGREEN 1 + # define KS_iBLUE 2 + # define KS_iPALETTE 8 + # define KS_iMAXBITS 8 + # define KS_SIZE_EGA_PALETTE (KS_iEGA_COLORS * sizeof(KS_RGBQUAD)) + # define KS_SIZE_PALETTE (KS_iPALETTE_COLORS * sizeof(KS_RGBQUAD)) + +typedef struct tagKS_BITMAPINFOHEADER +{ + DWORD biSize; + LONG biWidth; + LONG biHeight; + WORD biPlanes; + WORD biBitCount; + DWORD biCompression; + DWORD biSizeImage; + LONG biXPelsPerMeter; + LONG biYPelsPerMeter; + DWORD biClrUsed; + DWORD biClrImportant; +}KS_BITMAPINFOHEADER, * PKS_BITMAPINFOHEADER; + +typedef struct tag_KS_TRUECOLORINFO +{ + DWORD dwBitMasks[KS_iMASK_COLORS]; + KS_RGBQUAD bmiColors[KS_iPALETTE_COLORS]; +}KS_TRUECOLORINFO, * PKS_TRUECOLORINFO; + + # define KS_WIDTHBYTES(bits) ((DWORD)(((bits) + 31) & (~31)) / 8) + # define KS_DIBWIDTHBYTES(bi) (DWORD)KS_WIDTHBYTES((DWORD)(bi).biWidth * (DWORD)(bi).biBitCount) + # define KS__DIBSIZE(bi) (KS_DIBWIDTHBYTES(bi) * (DWORD)(bi).biHeight) + # define KS_DIBSIZE(bi) ((bi).biHeight < 0 ? (-1) * (KS__DIBSIZE(bi)) : KS__DIBSIZE(bi)) + +typedef LONGLONG REFERENCE_TIME; + +typedef struct tagKS_VIDEOINFOHEADER +{ + RECT rcSource; + RECT rcTarget; + DWORD dwBitRate; + DWORD dwBitErrorRate; + REFERENCE_TIME AvgTimePerFrame; + KS_BITMAPINFOHEADER bmiHeader; +}KS_VIDEOINFOHEADER, * PKS_VIDEOINFOHEADER; + +typedef struct tagKS_VIDEOINFO +{ + RECT rcSource; + RECT rcTarget; + DWORD dwBitRate; + DWORD dwBitErrorRate; + REFERENCE_TIME AvgTimePerFrame; + KS_BITMAPINFOHEADER bmiHeader; + __MINGW_EXTENSION union + { + KS_RGBQUAD bmiColors[KS_iPALETTE_COLORS]; + DWORD dwBitMasks[KS_iMASK_COLORS]; + KS_TRUECOLORINFO TrueColorInfo; + }; +}KS_VIDEOINFO, * PKS_VIDEOINFO; + + # define KS_SIZE_MASKS (KS_iMASK_COLORS * sizeof(DWORD)) + # define KS_SIZE_PREHEADER (FIELD_OFFSET(KS_VIDEOINFOHEADER, bmiHeader)) + + # define KS_SIZE_VIDEOHEADER(pbmi) ((pbmi)->bmiHeader.biSize + KS_SIZE_PREHEADER) + +typedef struct tagKS_VBIINFOHEADER +{ + ULONG StartLine; + ULONG EndLine; + ULONG SamplingFrequency; + ULONG MinLineStartTime; + ULONG MaxLineStartTime; + ULONG ActualLineStartTime; + ULONG ActualLineEndTime; + ULONG VideoStandard; + ULONG SamplesPerLine; + ULONG StrideInBytes; + ULONG BufferSize; +}KS_VBIINFOHEADER, * PKS_VBIINFOHEADER; + + # define KS_VBIDATARATE_NABTS (5727272L) + # define KS_VBIDATARATE_CC (503493L) + # define KS_VBISAMPLINGRATE_4X_NABTS ((long)(4 * KS_VBIDATARATE_NABTS)) + # define KS_VBISAMPLINGRATE_47X_NABTS ((long)(27000000)) + # define KS_VBISAMPLINGRATE_5X_NABTS ((long)(5 * KS_VBIDATARATE_NABTS)) + + # define KS_47NABTS_SCALER (KS_VBISAMPLINGRATE_47X_NABTS / (double)KS_VBIDATARATE_NABTS) + +typedef struct tagKS_AnalogVideoInfo +{ + RECT rcSource; + RECT rcTarget; + DWORD dwActiveWidth; + DWORD dwActiveHeight; + REFERENCE_TIME AvgTimePerFrame; +}KS_ANALOGVIDEOINFO, * PKS_ANALOGVIDEOINFO; + + # define KS_TVTUNER_CHANGE_BEGIN_TUNE 0x0001L + # define KS_TVTUNER_CHANGE_END_TUNE 0x0002L + +typedef struct tagKS_TVTUNER_CHANGE_INFO +{ + DWORD dwFlags; + DWORD dwCountryCode; + DWORD dwAnalogVideoStandard; + DWORD dwChannel; +}KS_TVTUNER_CHANGE_INFO, * PKS_TVTUNER_CHANGE_INFO; + +typedef enum +{ + KS_MPEG2Level_Low, + KS_MPEG2Level_Main, + KS_MPEG2Level_High1440, + KS_MPEG2Level_High +}KS_MPEG2Level; + +typedef enum +{ + KS_MPEG2Profile_Simple, + KS_MPEG2Profile_Main, + KS_MPEG2Profile_SNRScalable, + KS_MPEG2Profile_SpatiallyScalable, + KS_MPEG2Profile_High +}KS_MPEG2Profile; + + # define KS_INTERLACE_IsInterlaced 0x00000001 + # define KS_INTERLACE_1FieldPerSample 0x00000002 + # define KS_INTERLACE_Field1First 0x00000004 + # define KS_INTERLACE_UNUSED 0x00000008 + # define KS_INTERLACE_FieldPatternMask 0x00000030 + # define KS_INTERLACE_FieldPatField1Only 0x00000000 + # define KS_INTERLACE_FieldPatField2Only 0x00000010 + # define KS_INTERLACE_FieldPatBothRegular 0x00000020 + # define KS_INTERLACE_FieldPatBothIrregular 0x00000030 + # define KS_INTERLACE_DisplayModeMask 0x000000c0 + # define KS_INTERLACE_DisplayModeBobOnly 0x00000000 + # define KS_INTERLACE_DisplayModeWeaveOnly 0x00000040 + # define KS_INTERLACE_DisplayModeBobOrWeave 0x00000080 + + # define KS_MPEG2_DoPanScan 0x00000001 + # define KS_MPEG2_DVDLine21Field1 0x00000002 + # define KS_MPEG2_DVDLine21Field2 0x00000004 + # define KS_MPEG2_SourceIsLetterboxed 0x00000008 + # define KS_MPEG2_FilmCameraMode 0x00000010 + # define KS_MPEG2_LetterboxAnalogOut 0x00000020 + # define KS_MPEG2_DSS_UserData 0x00000040 + # define KS_MPEG2_DVB_UserData 0x00000080 + # define KS_MPEG2_27MhzTimebase 0x00000100 + +typedef struct tagKS_VIDEOINFOHEADER2 +{ + RECT rcSource; + RECT rcTarget; + DWORD dwBitRate; + DWORD dwBitErrorRate; + REFERENCE_TIME AvgTimePerFrame; + DWORD dwInterlaceFlags; + DWORD dwCopyProtectFlags; + DWORD dwPictAspectRatioX; + DWORD dwPictAspectRatioY; + DWORD dwReserved1; + DWORD dwReserved2; + KS_BITMAPINFOHEADER bmiHeader; +}KS_VIDEOINFOHEADER2, * PKS_VIDEOINFOHEADER2; + +typedef struct tagKS_MPEG1VIDEOINFO +{ + KS_VIDEOINFOHEADER hdr; + DWORD dwStartTimeCode; + DWORD cbSequenceHeader; + BYTE bSequenceHeader[1]; +}KS_MPEG1VIDEOINFO, * PKS_MPEG1VIDEOINFO; + + # define KS_MAX_SIZE_MPEG1_SEQUENCE_INFO 140 + # define KS_SIZE_MPEG1VIDEOINFO(pv) (FIELD_OFFSET(KS_MPEG1VIDEOINFO, bSequenceHeader[0]) + (pv)->cbSequenceHeader) + # define KS_MPEG1_SEQUENCE_INFO(pv) ((const BYTE*)(pv)->bSequenceHeader) + +typedef struct tagKS_MPEGVIDEOINFO2 +{ + KS_VIDEOINFOHEADER2 hdr; + DWORD dwStartTimeCode; + DWORD cbSequenceHeader; + DWORD dwProfile; + DWORD dwLevel; + DWORD dwFlags; + DWORD bSequenceHeader[1]; +}KS_MPEGVIDEOINFO2, * PKS_MPEGVIDEOINFO2; + + # define KS_SIZE_MPEGVIDEOINFO2(pv) (FIELD_OFFSET(KS_MPEGVIDEOINFO2, bSequenceHeader[0]) + (pv)->cbSequenceHeader) + # define KS_MPEG1_SEQUENCE_INFO(pv) ((const BYTE*)(pv)->bSequenceHeader) + + # define KS_MPEGAUDIOINFO_27MhzTimebase 0x00000001 + +typedef struct tagKS_MPEAUDIOINFO +{ + DWORD dwFlags; + DWORD dwReserved1; + DWORD dwReserved2; + DWORD dwReserved3; +}KS_MPEGAUDIOINFO, * PKS_MPEGAUDIOINFO; + +typedef struct tagKS_DATAFORMAT_VIDEOINFOHEADER +{ + KSDATAFORMAT DataFormat; + KS_VIDEOINFOHEADER VideoInfoHeader; +}KS_DATAFORMAT_VIDEOINFOHEADER, * PKS_DATAFORMAT_VIDEOINFOHEADER; + +typedef struct tagKS_DATAFORMAT_VIDEOINFOHEADER2 +{ + KSDATAFORMAT DataFormat; + KS_VIDEOINFOHEADER2 VideoInfoHeader2; +}KS_DATAFORMAT_VIDEOINFOHEADER2, * PKS_DATAFORMAT_VIDEOINFOHEADER2; + +typedef struct tagKS_DATAFORMAT_VIDEOINFO_PALETTE +{ + KSDATAFORMAT DataFormat; + KS_VIDEOINFO VideoInfo; +}KS_DATAFORMAT_VIDEOINFO_PALETTE, * PKS_DATAFORMAT_VIDEOINFO_PALETTE; + +typedef struct tagKS_DATAFORMAT_VBIINFOHEADER +{ + KSDATAFORMAT DataFormat; + KS_VBIINFOHEADER VBIInfoHeader; +}KS_DATAFORMAT_VBIINFOHEADER, * PKS_DATAFORMAT_VBIINFOHEADER; + +typedef struct _KS_VIDEO_STREAM_CONFIG_CAPS +{ + GUID guid; + ULONG VideoStandard; + SIZE InputSize; + SIZE MinCroppingSize; + SIZE MaxCroppingSize; + int CropGranularityX; + int CropGranularityY; + int CropAlignX; + int CropAlignY; + SIZE MinOutputSize; + SIZE MaxOutputSize; + int OutputGranularityX; + int OutputGranularityY; + int StretchTapsX; + int StretchTapsY; + int ShrinkTapsX; + int ShrinkTapsY; + LONGLONG MinFrameInterval; + LONGLONG MaxFrameInterval; + LONG MinBitsPerSecond; + LONG MaxBitsPerSecond; +}KS_VIDEO_STREAM_CONFIG_CAPS, * PKS_VIDEO_STREAM_CONFIG_CAPS; + +typedef struct tagKS_DATARANGE_VIDEO +{ + KSDATARANGE DataRange; + WINBOOL bFixedSizeSamples; + WINBOOL bTemporalCompression; + DWORD StreamDescriptionFlags; + DWORD MemoryAllocationFlags; + KS_VIDEO_STREAM_CONFIG_CAPS ConfigCaps; + KS_VIDEOINFOHEADER VideoInfoHeader; +}KS_DATARANGE_VIDEO, * PKS_DATARANGE_VIDEO; + +typedef struct tagKS_DATARANGE_VIDEO2 +{ + KSDATARANGE DataRange; + WINBOOL bFixedSizeSamples; + WINBOOL bTemporalCompression; + DWORD StreamDescriptionFlags; + DWORD MemoryAllocationFlags; + KS_VIDEO_STREAM_CONFIG_CAPS ConfigCaps; + KS_VIDEOINFOHEADER2 VideoInfoHeader; +}KS_DATARANGE_VIDEO2, * PKS_DATARANGE_VIDEO2; + +typedef struct tagKS_DATARANGE_MPEG1_VIDEO +{ + KSDATARANGE DataRange; + WINBOOL bFixedSizeSamples; + WINBOOL bTemporalCompression; + DWORD StreamDescriptionFlags; + DWORD MemoryAllocationFlags; + KS_VIDEO_STREAM_CONFIG_CAPS ConfigCaps; + KS_MPEG1VIDEOINFO VideoInfoHeader; +}KS_DATARANGE_MPEG1_VIDEO, * PKS_DATARANGE_MPEG1_VIDEO; + +typedef struct tagKS_DATARANGE_MPEG2_VIDEO +{ + KSDATARANGE DataRange; + WINBOOL bFixedSizeSamples; + WINBOOL bTemporalCompression; + DWORD StreamDescriptionFlags; + DWORD MemoryAllocationFlags; + KS_VIDEO_STREAM_CONFIG_CAPS ConfigCaps; + KS_MPEGVIDEOINFO2 VideoInfoHeader; +}KS_DATARANGE_MPEG2_VIDEO, * PKS_DATARANGE_MPEG2_VIDEO; + +typedef struct tagKS_DATARANGE_VIDEO_PALETTE +{ + KSDATARANGE DataRange; + WINBOOL bFixedSizeSamples; + WINBOOL bTemporalCompression; + DWORD StreamDescriptionFlags; + DWORD MemoryAllocationFlags; + KS_VIDEO_STREAM_CONFIG_CAPS ConfigCaps; + KS_VIDEOINFO VideoInfo; +}KS_DATARANGE_VIDEO_PALETTE, * PKS_DATARANGE_VIDEO_PALETTE; + +typedef struct tagKS_DATARANGE_VIDEO_VBI +{ + KSDATARANGE DataRange; + WINBOOL bFixedSizeSamples; + WINBOOL bTemporalCompression; + DWORD StreamDescriptionFlags; + DWORD MemoryAllocationFlags; + KS_VIDEO_STREAM_CONFIG_CAPS ConfigCaps; + KS_VBIINFOHEADER VBIInfoHeader; +}KS_DATARANGE_VIDEO_VBI, * PKS_DATARANGE_VIDEO_VBI; + +typedef struct tagKS_DATARANGE_ANALOGVIDEO +{ + KSDATARANGE DataRange; + KS_ANALOGVIDEOINFO AnalogVideoInfo; +}KS_DATARANGE_ANALOGVIDEO, * PKS_DATARANGE_ANALOGVIDEO; + + # define KS_VIDEOSTREAM_PREVIEW 0x0001 + # define KS_VIDEOSTREAM_CAPTURE 0x0002 + # define KS_VIDEOSTREAM_VBI 0x0010 + # define KS_VIDEOSTREAM_NABTS 0x0020 + # define KS_VIDEOSTREAM_CC 0x0100 + # define KS_VIDEOSTREAM_EDS 0x0200 + # define KS_VIDEOSTREAM_TELETEXT 0x0400 + # define KS_VIDEOSTREAM_STILL 0x1000 + # define KS_VIDEOSTREAM_IS_VPE 0x8000 + + # define KS_VIDEO_ALLOC_VPE_SYSTEM 0x0001 + # define KS_VIDEO_ALLOC_VPE_DISPLAY 0x0002 + # define KS_VIDEO_ALLOC_VPE_AGP 0x0004 + + # define STATIC_KSPROPSETID_VBICAP_PROPERTIES \ + 0xf162c607, 0x7b35, 0x496f, 0xad, 0x7f, 0x2d, 0xca, 0x3b, 0x46, 0xb7, 0x18 +DEFINE_GUIDSTRUCT("F162C607-7B35-496f-AD7F-2DCA3B46B718", KSPROPSETID_VBICAP_PROPERTIES); + # define KSPROPSETID_VBICAP_PROPERTIES DEFINE_GUIDNAMED(KSPROPSETID_VBICAP_PROPERTIES) + +typedef enum +{ + KSPROPERTY_VBICAP_PROPERTIES_PROTECTION = 0x01 +}KSPROPERTY_VBICAP; + +typedef struct _VBICAP_PROPERTIES_PROTECTION_S +{ + KSPROPERTY Property; + ULONG StreamIndex; + ULONG Status; +}VBICAP_PROPERTIES_PROTECTION_S, * PVBICAP_PROPERTIES_PROTECTION_S; + + # define KS_VBICAP_PROTECTION_MV_PRESENT 0x0001L + # define KS_VBICAP_PROTECTION_MV_HARDWARE 0x0002L + # define KS_VBICAP_PROTECTION_MV_DETECTED 0x0004L + + # define KS_NABTS_GROUPID_ORIGINAL_CONTENT_BASE 0x800 + # define KS_NABTS_GROUPID_ORIGINAL_CONTENT_ADVERTISER_BASE 0x810 + + # define KS_NABTS_GROUPID_PRODUCTION_COMPANY_CONTENT_BASE 0x820 + # define KS_NABTS_GROUPID_PRODUCTION_COMPANY_ADVERTISER_BASE 0x830 + + # define KS_NABTS_GROUPID_SYNDICATED_SHOW_CONTENT_BASE 0x840 + # define KS_NABTS_GROUPID_SYNDICATED_SHOW_ADVERTISER_BASE 0x850 + + # define KS_NABTS_GROUPID_NETWORK_WIDE_CONTENT_BASE 0x860 + # define KS_NABTS_GROUPID_NETWORK_WIDE_ADVERTISER_BASE 0x870 + + # define KS_NABTS_GROUPID_TELEVISION_STATION_CONTENT_BASE 0x880 + # define KS_NABTS_GROUPID_TELEVISION_STATION_ADVERTISER_BASE 0x890 + + # define KS_NABTS_GROUPID_LOCAL_CABLE_SYSTEM_CONTENT_BASE 0x8A0 + # define KS_NABTS_GROUPID_LOCAL_CABLE_SYSTEM_ADVERTISER_BASE 0x8B0 + + # define KS_NABTS_GROUPID_MICROSOFT_RESERVED_TEST_DATA_BASE 0x8F0 + + # define STATIC_KSDATAFORMAT_TYPE_NABTS \ + 0xe757bca0, 0x39ac, 0x11d1, 0xa9, 0xf5, 0x0, 0xc0, 0x4f, 0xbb, 0xde, 0x8f +DEFINE_GUIDSTRUCT("E757BCA0-39AC-11d1-A9F5-00C04FBBDE8F", KSDATAFORMAT_TYPE_NABTS); + # define KSDATAFORMAT_TYPE_NABTS DEFINE_GUIDNAMED(KSDATAFORMAT_TYPE_NABTS) + + # define STATIC_KSDATAFORMAT_SUBTYPE_NABTS_FEC \ + 0xe757bca1, 0x39ac, 0x11d1, 0xa9, 0xf5, 0x0, 0xc0, 0x4f, 0xbb, 0xde, 0x8f +DEFINE_GUIDSTRUCT("E757BCA1-39AC-11d1-A9F5-00C04FBBDE8F", KSDATAFORMAT_SUBTYPE_NABTS_FEC); + # define KSDATAFORMAT_SUBTYPE_NABTS_FEC DEFINE_GUIDNAMED(KSDATAFORMAT_SUBTYPE_NABTS_FEC) + + # define MAX_NABTS_VBI_LINES_PER_FIELD 11 + # define NABTS_LINES_PER_BUNDLE 16 + # define NABTS_PAYLOAD_PER_LINE 28 + # define NABTS_BYTES_PER_LINE 36 + +typedef struct _NABTSFEC_BUFFER +{ + ULONG dataSize; + USHORT groupID; + USHORT Reserved; + UCHAR data[NABTS_LINES_PER_BUNDLE * NABTS_PAYLOAD_PER_LINE]; +}NABTSFEC_BUFFER, * PNABTSFEC_BUFFER; + + # define STATIC_KSPROPSETID_VBICodecFiltering \ + 0xcafeb0caL, 0x8715, 0x11d0, 0xbd, 0x6a, 0x00, 0x35, 0xc0, 0xed, 0xba, 0xbe +DEFINE_GUIDSTRUCT("cafeb0ca-8715-11d0-bd6a-0035c0edbabe", KSPROPSETID_VBICodecFiltering); + # define KSPROPSETID_VBICodecFiltering DEFINE_GUIDNAMED(KSPROPSETID_VBICodecFiltering) + +typedef enum +{ + KSPROPERTY_VBICODECFILTERING_SCANLINES_REQUESTED_BIT_ARRAY = 0x01, + KSPROPERTY_VBICODECFILTERING_SCANLINES_DISCOVERED_BIT_ARRAY, + KSPROPERTY_VBICODECFILTERING_SUBSTREAMS_REQUESTED_BIT_ARRAY, + KSPROPERTY_VBICODECFILTERING_SUBSTREAMS_DISCOVERED_BIT_ARRAY, + KSPROPERTY_VBICODECFILTERING_STATISTICS +}KSPROPERTY_VBICODECFILTERING; + +typedef struct _VBICODECFILTERING_SCANLINES +{ + DWORD DwordBitArray[32]; +}VBICODECFILTERING_SCANLINES, * PVBICODECFILTERING_SCANLINES; + +typedef struct _VBICODECFILTERING_NABTS_SUBSTREAMS +{ + DWORD SubstreamMask[128]; +}VBICODECFILTERING_NABTS_SUBSTREAMS, * PVBICODECFILTERING_NABTS_SUBSTREAMS; + +typedef struct _VBICODECFILTERING_CC_SUBSTREAMS +{ + DWORD SubstreamMask; +}VBICODECFILTERING_CC_SUBSTREAMS, * PVBICODECFILTERING_CC_SUBSTREAMS; + + # define KS_CC_SUBSTREAM_ODD 0x0001L + # define KS_CC_SUBSTREAM_EVEN 0x0002L + + # define KS_CC_SUBSTREAM_FIELD1_MASK 0x00F0L + # define KS_CC_SUBSTREAM_SERVICE_CC1 0x0010L + # define KS_CC_SUBSTREAM_SERVICE_CC2 0x0020L + # define KS_CC_SUBSTREAM_SERVICE_T1 0x0040L + # define KS_CC_SUBSTREAM_SERVICE_T2 0x0080L + + # define KS_CC_SUBSTREAM_FIELD2_MASK 0x1F00L + # define KS_CC_SUBSTREAM_SERVICE_CC3 0x0100L + # define KS_CC_SUBSTREAM_SERVICE_CC4 0x0200L + # define KS_CC_SUBSTREAM_SERVICE_T3 0x0400L + # define KS_CC_SUBSTREAM_SERVICE_T4 0x0800L + # define KS_CC_SUBSTREAM_SERVICE_XDS 0x1000L + + # define CC_MAX_HW_DECODE_LINES 12 +typedef struct _CC_BYTE_PAIR +{ + BYTE Decoded[2]; + USHORT Reserved; +}CC_BYTE_PAIR, * PCC_BYTE_PAIR; + +typedef struct _CC_HW_FIELD +{ + VBICODECFILTERING_SCANLINES ScanlinesRequested; + ULONG fieldFlags; + LONGLONG PictureNumber; + CC_BYTE_PAIR Lines[CC_MAX_HW_DECODE_LINES]; +}CC_HW_FIELD, * PCC_HW_FIELD; + + # ifndef PACK_PRAGMAS_NOT_SUPPORTED + # include + # endif +typedef struct _NABTS_BUFFER_LINE +{ + BYTE Confidence; + BYTE Bytes[NABTS_BYTES_PER_LINE]; +}NABTS_BUFFER_LINE, * PNABTS_BUFFER_LINE; + + # define NABTS_BUFFER_PICTURENUMBER_SUPPORT 1 +typedef struct _NABTS_BUFFER +{ + VBICODECFILTERING_SCANLINES ScanlinesRequested; + LONGLONG PictureNumber; + NABTS_BUFFER_LINE NabtsLines[MAX_NABTS_VBI_LINES_PER_FIELD]; +}NABTS_BUFFER, * PNABTS_BUFFER; + # ifndef PACK_PRAGMAS_NOT_SUPPORTED + # include + # endif + + # define WST_TVTUNER_CHANGE_BEGIN_TUNE 0x1000L + # define WST_TVTUNER_CHANGE_END_TUNE 0x2000L + + # define MAX_WST_VBI_LINES_PER_FIELD 17 + # define WST_BYTES_PER_LINE 42 + +typedef struct _WST_BUFFER_LINE +{ + BYTE Confidence; + BYTE Bytes[WST_BYTES_PER_LINE]; +}WST_BUFFER_LINE, * PWST_BUFFER_LINE; + +typedef struct _WST_BUFFER +{ + VBICODECFILTERING_SCANLINES ScanlinesRequested; + WST_BUFFER_LINE WstLines[MAX_WST_VBI_LINES_PER_FIELD]; +}WST_BUFFER, * PWST_BUFFER; + +typedef struct _VBICODECFILTERING_STATISTICS_COMMON +{ + DWORD InputSRBsProcessed; + DWORD OutputSRBsProcessed; + DWORD SRBsIgnored; + DWORD InputSRBsMissing; + DWORD OutputSRBsMissing; + DWORD OutputFailures; + DWORD InternalErrors; + DWORD ExternalErrors; + DWORD InputDiscontinuities; + DWORD DSPFailures; + DWORD TvTunerChanges; + DWORD VBIHeaderChanges; + DWORD LineConfidenceAvg; + DWORD BytesOutput; +}VBICODECFILTERING_STATISTICS_COMMON, * PVBICODECFILTERING_STATISTICS_COMMON; + +typedef struct _VBICODECFILTERING_STATISTICS_COMMON_PIN +{ + DWORD SRBsProcessed; + DWORD SRBsIgnored; + DWORD SRBsMissing; + DWORD InternalErrors; + DWORD ExternalErrors; + DWORD Discontinuities; + DWORD LineConfidenceAvg; + DWORD BytesOutput; +}VBICODECFILTERING_STATISTICS_COMMON_PIN, * PVBICODECFILTERING_STATISTICS_COMMON_PIN; + +typedef struct _VBICODECFILTERING_STATISTICS_NABTS +{ + VBICODECFILTERING_STATISTICS_COMMON Common; + DWORD FECBundleBadLines; + DWORD FECQueueOverflows; + DWORD FECCorrectedLines; + DWORD FECUncorrectableLines; + DWORD BundlesProcessed; + DWORD BundlesSent2IP; + DWORD FilteredLines; +}VBICODECFILTERING_STATISTICS_NABTS, * PVBICODECFILTERING_STATISTICS_NABTS; + +typedef struct _VBICODECFILTERING_STATISTICS_NABTS_PIN +{ + VBICODECFILTERING_STATISTICS_COMMON_PIN Common; +}VBICODECFILTERING_STATISTICS_NABTS_PIN, * PVBICODECFILTERING_STATISTICS_NABTS_PIN; + +typedef struct _VBICODECFILTERING_STATISTICS_CC +{ + VBICODECFILTERING_STATISTICS_COMMON Common; +}VBICODECFILTERING_STATISTICS_CC, * PVBICODECFILTERING_STATISTICS_CC; + +typedef struct _VBICODECFILTERING_STATISTICS_CC_PIN +{ + VBICODECFILTERING_STATISTICS_COMMON_PIN Common; +}VBICODECFILTERING_STATISTICS_CC_PIN, * PVBICODECFILTERING_STATISTICS_CC_PIN; + +typedef struct _VBICODECFILTERING_STATISTICS_TELETEXT +{ + VBICODECFILTERING_STATISTICS_COMMON Common; +}VBICODECFILTERING_STATISTICS_TELETEXT, * PVBICODECFILTERING_STATISTICS_TELETEXT; + +typedef struct _VBICODECFILTERING_STATISTICS_TELETEXT_PIN +{ + VBICODECFILTERING_STATISTICS_COMMON_PIN Common; +}VBICODECFILTERING_STATISTICS_TELETEXT_PIN, * PVBICODECFILTERING_STATISTICS_TELETEXT_PIN; + +typedef struct +{ + KSPROPERTY Property; + VBICODECFILTERING_SCANLINES Scanlines; +}KSPROPERTY_VBICODECFILTERING_SCANLINES_S, * PKSPROPERTY_VBICODECFILTERING_SCANLINES_S; + +typedef struct +{ + KSPROPERTY Property; + VBICODECFILTERING_NABTS_SUBSTREAMS Substreams; +}KSPROPERTY_VBICODECFILTERING_NABTS_SUBSTREAMS_S, * PKSPROPERTY_VBICODECFILTERING_NABTS_SUBSTREAMS_S; + +typedef struct +{ + KSPROPERTY Property; + VBICODECFILTERING_CC_SUBSTREAMS Substreams; +}KSPROPERTY_VBICODECFILTERING_CC_SUBSTREAMS_S, * PKSPROPERTY_VBICODECFILTERING_CC_SUBSTREAMS_S; + +typedef struct +{ + KSPROPERTY Property; + VBICODECFILTERING_STATISTICS_COMMON Statistics; +}KSPROPERTY_VBICODECFILTERING_STATISTICS_COMMON_S, * PKSPROPERTY_VBICODECFILTERING_STATISTICS_COMMON_S; + +typedef struct +{ + KSPROPERTY Property; + VBICODECFILTERING_STATISTICS_COMMON_PIN Statistics; +}KSPROPERTY_VBICODECFILTERING_STATISTICS_COMMON_PIN_S, * PKSPROPERTY_VBICODECFILTERING_STATISTICS_COMMON_PIN_S; + +typedef struct +{ + KSPROPERTY Property; + VBICODECFILTERING_STATISTICS_NABTS Statistics; +}KSPROPERTY_VBICODECFILTERING_STATISTICS_NABTS_S, * PKSPROPERTY_VBICODECFILTERING_STATISTICS_NABTS_S; + +typedef struct +{ + KSPROPERTY Property; + VBICODECFILTERING_STATISTICS_NABTS_PIN Statistics; +}KSPROPERTY_VBICODECFILTERING_STATISTICS_NABTS_PIN_S, * PKSPROPERTY_VBICODECFILTERING_STATISTICS_NABTS_PIN_S; + +typedef struct +{ + KSPROPERTY Property; + VBICODECFILTERING_STATISTICS_CC Statistics; +}KSPROPERTY_VBICODECFILTERING_STATISTICS_CC_S, * PKSPROPERTY_VBICODECFILTERING_STATISTICS_CC_S; + +typedef struct +{ + KSPROPERTY Property; + VBICODECFILTERING_STATISTICS_CC_PIN Statistics; +}KSPROPERTY_VBICODECFILTERING_STATISTICS_CC_PIN_S, * PKSPROPERTY_VBICODECFILTERING_STATISTICS_CC_PIN_S; + + # define STATIC_PINNAME_VIDEO_CAPTURE \ + 0xfb6c4281, 0x353, 0x11d1, 0x90, 0x5f, 0x0, 0x0, 0xc0, 0xcc, 0x16, 0xba + # define STATIC_PINNAME_CAPTURE STATIC_PINNAME_VIDEO_CAPTURE +DEFINE_GUIDSTRUCT("FB6C4281-0353-11d1-905F-0000C0CC16BA", PINNAME_VIDEO_CAPTURE); + # define PINNAME_VIDEO_CAPTURE DEFINE_GUIDNAMED(PINNAME_VIDEO_CAPTURE) + # define PINNAME_CAPTURE PINNAME_VIDEO_CAPTURE + + # define STATIC_PINNAME_VIDEO_CC_CAPTURE \ + 0x1aad8061, 0x12d, 0x11d2, 0xb4, 0xb1, 0x0, 0xa0, 0xd1, 0x2, 0xcf, 0xbe + # define STATIC_PINNAME_CC_CAPTURE STATIC_PINNAME_VIDEO_CC_CAPTURE +DEFINE_GUIDSTRUCT("1AAD8061-012D-11d2-B4B1-00A0D102CFBE", PINNAME_VIDEO_CC_CAPTURE); + # define PINNAME_VIDEO_CC_CAPTURE DEFINE_GUIDNAMED(PINNAME_VIDEO_CC_CAPTURE) + + # define STATIC_PINNAME_VIDEO_NABTS_CAPTURE \ + 0x29703660, 0x498a, 0x11d2, 0xb4, 0xb1, 0x0, 0xa0, 0xd1, 0x2, 0xcf, 0xbe + # define STATIC_PINNAME_NABTS_CAPTURE STATIC_PINNAME_VIDEO_NABTS_CAPTURE +DEFINE_GUIDSTRUCT("29703660-498A-11d2-B4B1-00A0D102CFBE", PINNAME_VIDEO_NABTS_CAPTURE); + # define PINNAME_VIDEO_NABTS_CAPTURE DEFINE_GUIDNAMED(PINNAME_VIDEO_NABTS_CAPTURE) + + # define STATIC_PINNAME_VIDEO_PREVIEW \ + 0xfb6c4282, 0x353, 0x11d1, 0x90, 0x5f, 0x0, 0x0, 0xc0, 0xcc, 0x16, 0xba + # define STATIC_PINNAME_PREVIEW STATIC_PINNAME_VIDEO_PREVIEW +DEFINE_GUIDSTRUCT("FB6C4282-0353-11d1-905F-0000C0CC16BA", PINNAME_VIDEO_PREVIEW); + # define PINNAME_VIDEO_PREVIEW DEFINE_GUIDNAMED(PINNAME_VIDEO_PREVIEW) + # define PINNAME_PREVIEW PINNAME_VIDEO_PREVIEW + + # define STATIC_PINNAME_VIDEO_ANALOGVIDEOIN \ + 0xfb6c4283, 0x353, 0x11d1, 0x90, 0x5f, 0x0, 0x0, 0xc0, 0xcc, 0x16, 0xba +DEFINE_GUIDSTRUCT("FB6C4283-0353-11d1-905F-0000C0CC16BA", PINNAME_VIDEO_ANALOGVIDEOIN); + # define PINNAME_VIDEO_ANALOGVIDEOIN DEFINE_GUIDNAMED(PINNAME_VIDEO_ANALOGVIDEOIN) + + # define STATIC_PINNAME_VIDEO_VBI \ + 0xfb6c4284, 0x353, 0x11d1, 0x90, 0x5f, 0x0, 0x0, 0xc0, 0xcc, 0x16, 0xba +DEFINE_GUIDSTRUCT("FB6C4284-0353-11d1-905F-0000C0CC16BA", PINNAME_VIDEO_VBI); + # define PINNAME_VIDEO_VBI DEFINE_GUIDNAMED(PINNAME_VIDEO_VBI) + + # define STATIC_PINNAME_VIDEO_VIDEOPORT \ + 0xfb6c4285, 0x353, 0x11d1, 0x90, 0x5f, 0x0, 0x0, 0xc0, 0xcc, 0x16, 0xba +DEFINE_GUIDSTRUCT("FB6C4285-0353-11d1-905F-0000C0CC16BA", PINNAME_VIDEO_VIDEOPORT); + # define PINNAME_VIDEO_VIDEOPORT DEFINE_GUIDNAMED(PINNAME_VIDEO_VIDEOPORT) + + # define STATIC_PINNAME_VIDEO_NABTS \ + 0xfb6c4286, 0x353, 0x11d1, 0x90, 0x5f, 0x0, 0x0, 0xc0, 0xcc, 0x16, 0xba +DEFINE_GUIDSTRUCT("FB6C4286-0353-11d1-905F-0000C0CC16BA", PINNAME_VIDEO_NABTS); + # define PINNAME_VIDEO_NABTS DEFINE_GUIDNAMED(PINNAME_VIDEO_NABTS) + + # define STATIC_PINNAME_VIDEO_EDS \ + 0xfb6c4287, 0x353, 0x11d1, 0x90, 0x5f, 0x0, 0x0, 0xc0, 0xcc, 0x16, 0xba +DEFINE_GUIDSTRUCT("FB6C4287-0353-11d1-905F-0000C0CC16BA", PINNAME_VIDEO_EDS); + # define PINNAME_VIDEO_EDS DEFINE_GUIDNAMED(PINNAME_VIDEO_EDS) + + # define STATIC_PINNAME_VIDEO_TELETEXT \ + 0xfb6c4288, 0x353, 0x11d1, 0x90, 0x5f, 0x0, 0x0, 0xc0, 0xcc, 0x16, 0xba +DEFINE_GUIDSTRUCT("FB6C4288-0353-11d1-905F-0000C0CC16BA", PINNAME_VIDEO_TELETEXT); + # define PINNAME_VIDEO_TELETEXT DEFINE_GUIDNAMED(PINNAME_VIDEO_TELETEXT) + + # define STATIC_PINNAME_VIDEO_CC \ + 0xfb6c4289, 0x353, 0x11d1, 0x90, 0x5f, 0x0, 0x0, 0xc0, 0xcc, 0x16, 0xba +DEFINE_GUIDSTRUCT("FB6C4289-0353-11d1-905F-0000C0CC16BA", PINNAME_VIDEO_CC); + # define PINNAME_VIDEO_CC DEFINE_GUIDNAMED(PINNAME_VIDEO_CC) + + # define STATIC_PINNAME_VIDEO_STILL \ + 0xfb6c428A, 0x353, 0x11d1, 0x90, 0x5f, 0x0, 0x0, 0xc0, 0xcc, 0x16, 0xba +DEFINE_GUIDSTRUCT("FB6C428A-0353-11d1-905F-0000C0CC16BA", PINNAME_VIDEO_STILL); + # define PINNAME_VIDEO_STILL DEFINE_GUIDNAMED(PINNAME_VIDEO_STILL) + + # define STATIC_PINNAME_VIDEO_TIMECODE \ + 0xfb6c428B, 0x353, 0x11d1, 0x90, 0x5f, 0x0, 0x0, 0xc0, 0xcc, 0x16, 0xba +DEFINE_GUIDSTRUCT("FB6C428B-0353-11d1-905F-0000C0CC16BA", PINNAME_VIDEO_TIMECODE); + # define PINNAME_VIDEO_TIMECODE DEFINE_GUIDNAMED(PINNAME_VIDEO_TIMECODE) + + # define STATIC_PINNAME_VIDEO_VIDEOPORT_VBI \ + 0xfb6c428C, 0x353, 0x11d1, 0x90, 0x5f, 0x0, 0x0, 0xc0, 0xcc, 0x16, 0xba +DEFINE_GUIDSTRUCT("FB6C428C-0353-11d1-905F-0000C0CC16BA", PINNAME_VIDEO_VIDEOPORT_VBI); + # define PINNAME_VIDEO_VIDEOPORT_VBI DEFINE_GUIDNAMED(PINNAME_VIDEO_VIDEOPORT_VBI) + + # define KS_VIDEO_FLAG_FRAME 0x0000L + # define KS_VIDEO_FLAG_FIELD1 0x0001L + # define KS_VIDEO_FLAG_FIELD2 0x0002L + + # define KS_VIDEO_FLAG_I_FRAME 0x0000L + # define KS_VIDEO_FLAG_P_FRAME 0x0010L + # define KS_VIDEO_FLAG_B_FRAME 0x0020L + +typedef struct tagKS_FRAME_INFO +{ + ULONG ExtendedHeaderSize; + DWORD dwFrameFlags; + LONGLONG PictureNumber; + LONGLONG DropCount; + HANDLE hDirectDraw; + HANDLE hSurfaceHandle; + RECT DirectDrawRect; + + DWORD Reserved1; + DWORD Reserved2; + DWORD Reserved3; + DWORD Reserved4; +}KS_FRAME_INFO, * PKS_FRAME_INFO; + + # define KS_VBI_FLAG_FIELD1 0x0001L + # define KS_VBI_FLAG_FIELD2 0x0002L + + # define KS_VBI_FLAG_MV_PRESENT 0x0100L + # define KS_VBI_FLAG_MV_HARDWARE 0x0200L + # define KS_VBI_FLAG_MV_DETECTED 0x0400L + + # define KS_VBI_FLAG_TVTUNER_CHANGE 0x0010L + # define KS_VBI_FLAG_VBIINFOHEADER_CHANGE 0x0020L + +typedef struct tagKS_VBI_FRAME_INFO +{ + ULONG ExtendedHeaderSize; + DWORD dwFrameFlags; + LONGLONG PictureNumber; + LONGLONG DropCount; + DWORD dwSamplingFrequency; + KS_TVTUNER_CHANGE_INFO TvTunerChangeInfo; + KS_VBIINFOHEADER VBIInfoHeader; +}KS_VBI_FRAME_INFO, * PKS_VBI_FRAME_INFO; + +typedef enum +{ + KS_AnalogVideo_None = 0x00000000, + KS_AnalogVideo_NTSC_M = 0x00000001, + KS_AnalogVideo_NTSC_M_J = 0x00000002, + KS_AnalogVideo_NTSC_433 = 0x00000004, + KS_AnalogVideo_PAL_B = 0x00000010, + KS_AnalogVideo_PAL_D = 0x00000020, + KS_AnalogVideo_PAL_G = 0x00000040, + KS_AnalogVideo_PAL_H = 0x00000080, + KS_AnalogVideo_PAL_I = 0x00000100, + KS_AnalogVideo_PAL_M = 0x00000200, + KS_AnalogVideo_PAL_N = 0x00000400, + KS_AnalogVideo_PAL_60 = 0x00000800, + KS_AnalogVideo_SECAM_B = 0x00001000, + KS_AnalogVideo_SECAM_D = 0x00002000, + KS_AnalogVideo_SECAM_G = 0x00004000, + KS_AnalogVideo_SECAM_H = 0x00008000, + KS_AnalogVideo_SECAM_K = 0x00010000, + KS_AnalogVideo_SECAM_K1 = 0x00020000, + KS_AnalogVideo_SECAM_L = 0x00040000, + KS_AnalogVideo_SECAM_L1 = 0x00080000, + KS_AnalogVideo_PAL_N_COMBO = 0x00100000 +}KS_AnalogVideoStandard; + + # define KS_AnalogVideo_NTSC_Mask 0x00000007 + # define KS_AnalogVideo_PAL_Mask 0x00100FF0 + # define KS_AnalogVideo_SECAM_Mask 0x000FF000 + + # define STATIC_PROPSETID_ALLOCATOR_CONTROL \ + 0x53171960, 0x148e, 0x11d2, 0x99, 0x79, 0x0, 0x0, 0xc0, 0xcc, 0x16, 0xba +DEFINE_GUIDSTRUCT("53171960-148E-11d2-9979-0000C0CC16BA", PROPSETID_ALLOCATOR_CONTROL); + # define PROPSETID_ALLOCATOR_CONTROL DEFINE_GUIDNAMED(PROPSETID_ALLOCATOR_CONTROL) + +typedef enum +{ + KSPROPERTY_ALLOCATOR_CONTROL_HONOR_COUNT, + KSPROPERTY_ALLOCATOR_CONTROL_SURFACE_SIZE, + KSPROPERTY_ALLOCATOR_CONTROL_CAPTURE_CAPS, + KSPROPERTY_ALLOCATOR_CONTROL_CAPTURE_INTERLEAVE +}KSPROPERTY_ALLOCATOR_CONTROL; + +typedef struct +{ + ULONG CX; + ULONG CY; +}KSPROPERTY_ALLOCATOR_CONTROL_SURFACE_SIZE_S, * PKSPROPERTY_ALLOCATOR_CONTROL_SURFACE_SIZE_S; + +typedef struct +{ + ULONG InterleavedCapSupported; +}KSPROPERTY_ALLOCATOR_CONTROL_CAPTURE_CAPS_S, * PKSPROPERTY_ALLOCATOR_CONTROL_CAPTURE_CAPS_S; + +typedef struct +{ + ULONG InterleavedCapPossible; +}KSPROPERTY_ALLOCATOR_CONTROL_CAPTURE_INTERLEAVE_S, * PKSPROPERTY_ALLOCATOR_CONTROL_CAPTURE_INTERLEAVE_S; + + # define STATIC_PROPSETID_VIDCAP_VIDEOPROCAMP \ + 0xC6E13360L, 0x30AC, 0x11d0, 0xa1, 0x8c, 0x00, 0xA0, 0xC9, 0x11, 0x89, 0x56 +DEFINE_GUIDSTRUCT("C6E13360-30AC-11d0-A18C-00A0C9118956", PROPSETID_VIDCAP_VIDEOPROCAMP); + # define PROPSETID_VIDCAP_VIDEOPROCAMP DEFINE_GUIDNAMED(PROPSETID_VIDCAP_VIDEOPROCAMP) + +typedef enum +{ + KSPROPERTY_VIDEOPROCAMP_BRIGHTNESS, + KSPROPERTY_VIDEOPROCAMP_CONTRAST, + KSPROPERTY_VIDEOPROCAMP_HUE, + KSPROPERTY_VIDEOPROCAMP_SATURATION, + KSPROPERTY_VIDEOPROCAMP_SHARPNESS, + KSPROPERTY_VIDEOPROCAMP_GAMMA, + KSPROPERTY_VIDEOPROCAMP_COLORENABLE, + KSPROPERTY_VIDEOPROCAMP_WHITEBALANCE, + KSPROPERTY_VIDEOPROCAMP_BACKLIGHT_COMPENSATION, + KSPROPERTY_VIDEOPROCAMP_GAIN, + KSPROPERTY_VIDEOPROCAMP_DIGITAL_MULTIPLIER, + KSPROPERTY_VIDEOPROCAMP_DIGITAL_MULTIPLIER_LIMIT, + KSPROPERTY_VIDEOPROCAMP_WHITEBALANCE_COMPONENT, + KSPROPERTY_VIDEOPROCAMP_POWERLINE_FREQUENCY +}KSPROPERTY_VIDCAP_VIDEOPROCAMP; + +typedef struct +{ + KSPROPERTY Property; + LONG Value; + ULONG Flags; + ULONG Capabilities; +}KSPROPERTY_VIDEOPROCAMP_S, * PKSPROPERTY_VIDEOPROCAMP_S; + +typedef struct +{ + KSP_NODE NodeProperty; + LONG Value; + ULONG Flags; + ULONG Capabilities; +}KSPROPERTY_VIDEOPROCAMP_NODE_S, * PKSPROPERTY_VIDEOPROCAMP_NODE_S; + +typedef struct +{ + KSPROPERTY Property; + LONG Value1; + ULONG Flags; + ULONG Capabilities; + LONG Value2; +}KSPROPERTY_VIDEOPROCAMP_S2, * PKSPROPERTY_VIDEOPROCAMP_S2; + +typedef struct +{ + KSP_NODE NodeProperty; + LONG Value1; + ULONG Flags; + ULONG Capabilities; + LONG Value2; +}KSPROPERTY_VIDEOPROCAMP_NODE_S2, * PKSPROPERTY_VIDEOPROCAMP_NODE_S2; + + # define KSPROPERTY_VIDEOPROCAMP_FLAGS_AUTO 0X0001L + # define KSPROPERTY_VIDEOPROCAMP_FLAGS_MANUAL 0X0002L + + # define STATIC_PROPSETID_VIDCAP_SELECTOR \ + 0x1ABDAECA, 0x68B6, 0x4F83, 0x93, 0x71, 0xB4, 0x13, 0x90, 0x7C, 0x7B, 0x9F +DEFINE_GUIDSTRUCT("1ABDAECA-68B6-4F83-9371-B413907C7B9F", PROPSETID_VIDCAP_SELECTOR); + # define PROPSETID_VIDCAP_SELECTOR DEFINE_GUIDNAMED(PROPSETID_VIDCAP_SELECTOR) + +typedef enum +{ + KSPROPERTY_SELECTOR_SOURCE_NODE_ID, + KSPROPERTY_SELECTOR_NUM_SOURCES +}KSPROPERTY_VIDCAP_SELECTOR, * PKSPROPERTY_VIDCAP_SELECTOR; + +typedef struct +{ + KSPROPERTY Property; + LONG Value; + ULONG Flags; + ULONG Capabilities; +}KSPROPERTY_SELECTOR_S, * PKSPROPERTY_SELECTOR_S; + +typedef struct +{ + KSP_NODE NodeProperty; + LONG Value; + ULONG Flags; + ULONG Capabilities; +}KSPROPERTY_SELECTOR_NODE_S, * PKSPROPERTY_SELECTOR_NODE_S; + + # define STATIC_PROPSETID_TUNER \ + 0x6a2e0605L, 0x28e4, 0x11d0, 0xa1, 0x8c, 0x00, 0xa0, 0xc9, 0x11, 0x89, 0x56 +DEFINE_GUIDSTRUCT("6a2e0605-28e4-11d0-a18c-00a0c9118956", PROPSETID_TUNER); + # define PROPSETID_TUNER DEFINE_GUIDNAMED(PROPSETID_TUNER) + +typedef enum +{ + KSPROPERTY_TUNER_CAPS, + KSPROPERTY_TUNER_MODE_CAPS, + KSPROPERTY_TUNER_MODE, + KSPROPERTY_TUNER_STANDARD, + KSPROPERTY_TUNER_FREQUENCY, + KSPROPERTY_TUNER_INPUT, + KSPROPERTY_TUNER_STATUS, + KSPROPERTY_TUNER_IF_MEDIUM +}KSPROPERTY_TUNER; + +typedef enum +{ + KSPROPERTY_TUNER_MODE_TV = 0X0001, + KSPROPERTY_TUNER_MODE_FM_RADIO = 0X0002, + KSPROPERTY_TUNER_MODE_AM_RADIO = 0X0004, + KSPROPERTY_TUNER_MODE_DSS = 0X0008, + KSPROPERTY_TUNER_MODE_ATSC = 0X0010 +}KSPROPERTY_TUNER_MODES; + +typedef enum +{ + KS_TUNER_TUNING_EXACT = 1, + KS_TUNER_TUNING_FINE, + KS_TUNER_TUNING_COARSE +}KS_TUNER_TUNING_FLAGS; + +typedef enum +{ + KS_TUNER_STRATEGY_PLL = 0X01, + KS_TUNER_STRATEGY_SIGNAL_STRENGTH = 0X02, + KS_TUNER_STRATEGY_DRIVER_TUNES = 0X04 +}KS_TUNER_STRATEGY; + +typedef struct +{ + KSPROPERTY Property; + ULONG ModesSupported; + KSPIN_MEDIUM VideoMedium; + KSPIN_MEDIUM TVAudioMedium; + KSPIN_MEDIUM RadioAudioMedium; +}KSPROPERTY_TUNER_CAPS_S, * PKSPROPERTY_TUNER_CAPS_S; + +typedef struct +{ + KSPROPERTY Property; + KSPIN_MEDIUM IFMedium; +}KSPROPERTY_TUNER_IF_MEDIUM_S, * PKSPROPERTY_TUNER_IF_MEDIUM_S; + +typedef struct +{ + KSPROPERTY Property; + ULONG Mode; + ULONG StandardsSupported; + ULONG MinFrequency; + ULONG MaxFrequency; + ULONG TuningGranularity; + ULONG NumberOfInputs; + ULONG SettlingTime; + ULONG Strategy; +}KSPROPERTY_TUNER_MODE_CAPS_S, * PKSPROPERTY_TUNER_MODE_CAPS_S; + +typedef struct +{ + KSPROPERTY Property; + ULONG Mode; +}KSPROPERTY_TUNER_MODE_S, * PKSPROPERTY_TUNER_MODE_S; + +typedef struct +{ + KSPROPERTY Property; + ULONG Frequency; + ULONG LastFrequency; + ULONG TuningFlags; + ULONG VideoSubChannel; + ULONG AudioSubChannel; + ULONG Channel; + ULONG Country; +}KSPROPERTY_TUNER_FREQUENCY_S, * PKSPROPERTY_TUNER_FREQUENCY_S; + +typedef struct +{ + KSPROPERTY Property; + ULONG Standard; +}KSPROPERTY_TUNER_STANDARD_S, * PKSPROPERTY_TUNER_STANDARD_S; + +typedef struct +{ + KSPROPERTY Property; + ULONG InputIndex; +}KSPROPERTY_TUNER_INPUT_S, * PKSPROPERTY_TUNER_INPUT_S; + +typedef struct +{ + KSPROPERTY Property; + ULONG CurrentFrequency; + ULONG PLLOffset; + ULONG SignalStrength; + ULONG Busy; +}KSPROPERTY_TUNER_STATUS_S, * PKSPROPERTY_TUNER_STATUS_S; + + # define STATIC_EVENTSETID_TUNER \ + 0x6a2e0606L, 0x28e4, 0x11d0, 0xa1, 0x8c, 0x00, 0xa0, 0xc9, 0x11, 0x89, 0x56 +DEFINE_GUIDSTRUCT("6a2e0606-28e4-11d0-a18c-00a0c9118956", EVENTSETID_TUNER); + # define EVENTSETID_TUNER DEFINE_GUIDNAMED(EVENTSETID_TUNER) + +typedef enum +{ + KSEVENT_TUNER_CHANGED +}KSEVENT_TUNER; + + # define STATIC_KSNODETYPE_VIDEO_STREAMING \ + 0xDFF229E1L, 0xF70F, 0x11D0, 0xB9, 0x17, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96 +DEFINE_GUIDSTRUCT("DFF229E1-F70F-11D0-B917-00A0C9223196", KSNODETYPE_VIDEO_STREAMING); + # define KSNODETYPE_VIDEO_STREAMING DEFINE_GUIDNAMED(KSNODETYPE_VIDEO_STREAMING) + + # define STATIC_KSNODETYPE_VIDEO_INPUT_TERMINAL \ + 0xDFF229E2L, 0xF70F, 0x11D0, 0xB9, 0x17, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96 +DEFINE_GUIDSTRUCT("DFF229E2-F70F-11D0-B917-00A0C9223196", KSNODETYPE_VIDEO_INPUT_TERMINAL); + # define KSNODETYPE_VIDEO_INPUT_TERMINAL DEFINE_GUIDNAMED(KSNODETYPE_VIDEO_INPUT_TERMINAL) + + # define STATIC_KSNODETYPE_VIDEO_OUTPUT_TERMINAL \ + 0xDFF229E3L, 0xF70F, 0x11D0, 0xB9, 0x17, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96 +DEFINE_GUIDSTRUCT("DFF229E3-F70F-11D0-B917-00A0C9223196", KSNODETYPE_VIDEO_OUTPUT_TERMINAL); + # define KSNODETYPE_VIDEO_OUTPUT_TERMINAL DEFINE_GUIDNAMED(KSNODETYPE_VIDEO_OUTPUT_TERMINAL) + + # define STATIC_KSNODETYPE_VIDEO_SELECTOR \ + 0xDFF229E4L, 0xF70F, 0x11D0, 0xB9, 0x17, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96 +DEFINE_GUIDSTRUCT("DFF229E4-F70F-11D0-B917-00A0C9223196", KSNODETYPE_VIDEO_SELECTOR); + # define KSNODETYPE_VIDEO_SELECTOR DEFINE_GUIDNAMED(KSNODETYPE_VIDEO_SELECTOR) + + # define STATIC_KSNODETYPE_VIDEO_PROCESSING \ + 0xDFF229E5L, 0xF70F, 0x11D0, 0xB9, 0x17, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96 +DEFINE_GUIDSTRUCT("DFF229E5-F70F-11D0-B917-00A0C9223196", KSNODETYPE_VIDEO_PROCESSING); + # define KSNODETYPE_VIDEO_PROCESSING DEFINE_GUIDNAMED(KSNODETYPE_VIDEO_PROCESSING) + + # define STATIC_KSNODETYPE_VIDEO_CAMERA_TERMINAL \ + 0xDFF229E6L, 0xF70F, 0x11D0, 0xB9, 0x17, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96 +DEFINE_GUIDSTRUCT("DFF229E6-F70F-11D0-B917-00A0C9223196", KSNODETYPE_VIDEO_CAMERA_TERMINAL); + # define KSNODETYPE_VIDEO_CAMERA_TERMINAL DEFINE_GUIDNAMED(KSNODETYPE_VIDEO_CAMERA_TERMINAL) + + # define STATIC_KSNODETYPE_VIDEO_INPUT_MTT \ + 0xDFF229E7L, 0xF70F, 0x11D0, 0xB9, 0x17, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96 +DEFINE_GUIDSTRUCT("DFF229E7-F70F-11D0-B917-00A0C9223196", KSNODETYPE_VIDEO_INPUT_MTT); + # define KSNODETYPE_VIDEO_INPUT_MTT DEFINE_GUIDNAMED(KSNODETYPE_VIDEO_INPUT_MTT) + + # define STATIC_KSNODETYPE_VIDEO_OUTPUT_MTT \ + 0xDFF229E8L, 0xF70F, 0x11D0, 0xB9, 0x17, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96 +DEFINE_GUIDSTRUCT("DFF229E8-F70F-11D0-B917-00A0C9223196", KSNODETYPE_VIDEO_OUTPUT_MTT); + # define KSNODETYPE_VIDEO_OUTPUT_MTT DEFINE_GUIDNAMED(KSNODETYPE_VIDEO_OUTPUT_MTT) + + # define STATIC_PROPSETID_VIDCAP_VIDEOENCODER \ + 0x6a2e0610L, 0x28e4, 0x11d0, 0xa1, 0x8c, 0x00, 0xa0, 0xc9, 0x11, 0x89, 0x56 +DEFINE_GUIDSTRUCT("6a2e0610-28e4-11d0-a18c-00a0c9118956", PROPSETID_VIDCAP_VIDEOENCODER); + # define PROPSETID_VIDCAP_VIDEOENCODER DEFINE_GUIDNAMED(PROPSETID_VIDCAP_VIDEOENCODER) + +typedef enum +{ + KSPROPERTY_VIDEOENCODER_CAPS, + KSPROPERTY_VIDEOENCODER_STANDARD, + KSPROPERTY_VIDEOENCODER_COPYPROTECTION, + KSPROPERTY_VIDEOENCODER_CC_ENABLE +}KSPROPERTY_VIDCAP_VIDEOENCODER; + +typedef struct +{ + KSPROPERTY Property; + LONG Value; + ULONG Flags; + ULONG Capabilities; +}KSPROPERTY_VIDEOENCODER_S, * PKSPROPERTY_VIDEOENCODER_S; + + # define STATIC_PROPSETID_VIDCAP_VIDEODECODER \ + 0xC6E13350L, 0x30AC, 0x11d0, 0xA1, 0x8C, 0x00, 0xA0, 0xC9, 0x11, 0x89, 0x56 +DEFINE_GUIDSTRUCT("C6E13350-30AC-11d0-A18C-00A0C9118956", PROPSETID_VIDCAP_VIDEODECODER); + # define PROPSETID_VIDCAP_VIDEODECODER DEFINE_GUIDNAMED(PROPSETID_VIDCAP_VIDEODECODER) + +typedef enum +{ + KSPROPERTY_VIDEODECODER_CAPS, + KSPROPERTY_VIDEODECODER_STANDARD, + KSPROPERTY_VIDEODECODER_STATUS, + KSPROPERTY_VIDEODECODER_OUTPUT_ENABLE, + KSPROPERTY_VIDEODECODER_VCR_TIMING +}KSPROPERTY_VIDCAP_VIDEODECODER; + +typedef enum +{ + KS_VIDEODECODER_FLAGS_CAN_DISABLE_OUTPUT = 0X0001, + KS_VIDEODECODER_FLAGS_CAN_USE_VCR_LOCKING = 0X0002, + KS_VIDEODECODER_FLAGS_CAN_INDICATE_LOCKED = 0X0004 +}KS_VIDEODECODER_FLAGS; + +typedef struct +{ + KSPROPERTY Property; + ULONG StandardsSupported; + ULONG Capabilities; + ULONG SettlingTime; + ULONG HSyncPerVSync; +}KSPROPERTY_VIDEODECODER_CAPS_S, * PKSPROPERTY_VIDEODECODER_CAPS_S; + +typedef struct +{ + KSPROPERTY Property; + ULONG NumberOfLines; + ULONG SignalLocked; +}KSPROPERTY_VIDEODECODER_STATUS_S, * PKSPROPERTY_VIDEODECODER_STATUS_S; + +typedef struct +{ + KSPROPERTY Property; + ULONG Value; +}KSPROPERTY_VIDEODECODER_S, * PKSPROPERTY_VIDEODECODER_S; + + # define STATIC_EVENTSETID_VIDEODECODER \ + 0x6a2e0621L, 0x28e4, 0x11d0, 0xa1, 0x8c, 0x00, 0xa0, 0xc9, 0x11, 0x89, 0x56 +DEFINE_GUIDSTRUCT("6a2e0621-28e4-11d0-a18c-00a0c9118956", EVENTSETID_VIDEODECODER); + # define EVENTSETID_VIDEODECODER DEFINE_GUIDNAMED(EVENTSETID_VIDEODECODER) + +typedef enum +{ + KSEVENT_VIDEODECODER_CHANGED +}KSEVENT_VIDEODECODER; + + # define STATIC_PROPSETID_VIDCAP_CAMERACONTROL \ + 0xC6E13370L, 0x30AC, 0x11d0, 0xa1, 0x8C, 0x00, 0xA0, 0xC9, 0x11, 0x89, 0x56 +DEFINE_GUIDSTRUCT("C6E13370-30AC-11d0-A18C-00A0C9118956", PROPSETID_VIDCAP_CAMERACONTROL); + # define PROPSETID_VIDCAP_CAMERACONTROL DEFINE_GUIDNAMED(PROPSETID_VIDCAP_CAMERACONTROL) + +typedef enum +{ + KSPROPERTY_CAMERACONTROL_PAN, + KSPROPERTY_CAMERACONTROL_TILT, + KSPROPERTY_CAMERACONTROL_ROLL, + KSPROPERTY_CAMERACONTROL_ZOOM, + KSPROPERTY_CAMERACONTROL_EXPOSURE, + KSPROPERTY_CAMERACONTROL_IRIS, + KSPROPERTY_CAMERACONTROL_FOCUS, + KSPROPERTY_CAMERACONTROL_SCANMODE, + KSPROPERTY_CAMERACONTROL_PRIVACY, + KSPROPERTY_CAMERACONTROL_PANTILT, + KSPROPERTY_CAMERACONTROL_PAN_RELATIVE, + KSPROPERTY_CAMERACONTROL_TILT_RELATIVE, + KSPROPERTY_CAMERACONTROL_ROLL_RELATIVE, + KSPROPERTY_CAMERACONTROL_ZOOM_RELATIVE, + KSPROPERTY_CAMERACONTROL_EXPOSURE_RELATIVE, + KSPROPERTY_CAMERACONTROL_IRIS_RELATIVE, + KSPROPERTY_CAMERACONTROL_FOCUS_RELATIVE, + KSPROPERTY_CAMERACONTROL_PANTILT_RELATIVE, + KSPROPERTY_CAMERACONTROL_FOCAL_LENGTH +}KSPROPERTY_VIDCAP_CAMERACONTROL; + +typedef struct +{ + KSPROPERTY Property; + LONG Value; + ULONG Flags; + ULONG Capabilities; +}KSPROPERTY_CAMERACONTROL_S, * PKSPROPERTY_CAMERACONTROL_S; + +typedef struct +{ + KSP_NODE NodeProperty; + LONG Value; + ULONG Flags; + ULONG Capabilities; +}KSPROPERTY_CAMERACONTROL_NODE_S, PKSPROPERTY_CAMERACONTROL_NODE_S; + +typedef struct +{ + KSPROPERTY Property; + LONG Value1; + ULONG Flags; + ULONG Capabilities; + LONG Value2; +}KSPROPERTY_CAMERACONTROL_S2, * PKSPROPERTY_CAMERACONTROL_S2; + +typedef struct +{ + KSP_NODE NodeProperty; + LONG Value1; + ULONG Flags; + ULONG Capabilities; + LONG Value2; +}KSPROPERTY_CAMERACONTROL_NODE_S2, * PKSPROPERTY_CAMERACONTROL_NODE_S2; + +typedef struct +{ + KSPROPERTY Property; + LONG lOcularFocalLength; + LONG lObjectiveFocalLengthMin; + LONG lObjectiveFocalLengthMax; +}KSPROPERTY_CAMERACONTROL_FOCAL_LENGTH_S, * PKSPROPERTY_CAMERACONTROL_FOCAL_LENGTH_S; + +typedef struct +{ + KSNODEPROPERTY NodeProperty; + LONG lOcularFocalLength; + LONG lObjectiveFocalLengthMin; + LONG lObjectiveFocalLengthMax; +}KSPROPERTY_CAMERACONTROL_NODE_FOCAL_LENGTH_S, * PKSPROPERTY_CAMERACONTROL_NODE_FOCAL_LENGTH_S; + + # define KSPROPERTY_CAMERACONTROL_FLAGS_AUTO 0X0001L + # define KSPROPERTY_CAMERACONTROL_FLAGS_MANUAL 0X0002L + + # define KSPROPERTY_CAMERACONTROL_FLAGS_ABSOLUTE 0X0000L + # define KSPROPERTY_CAMERACONTROL_FLAGS_RELATIVE 0X0010L + + # ifndef __EDevCtrl__ + # define __EDevCtrl__ + + # define STATIC_PROPSETID_EXT_DEVICE \ + 0xB5730A90L, 0x1A2C, 0x11cf, 0x8c, 0x23, 0x00, 0xAA, 0x00, 0x6B, 0x68, 0x14 +DEFINE_GUIDSTRUCT("B5730A90-1A2C-11cf-8C23-00AA006B6814", PROPSETID_EXT_DEVICE); + # define PROPSETID_EXT_DEVICE DEFINE_GUIDNAMED(PROPSETID_EXT_DEVICE) + +typedef enum +{ + KSPROPERTY_EXTDEVICE_ID, + KSPROPERTY_EXTDEVICE_VERSION, + KSPROPERTY_EXTDEVICE_POWER_STATE, + KSPROPERTY_EXTDEVICE_PORT, + KSPROPERTY_EXTDEVICE_CAPABILITIES +}KSPROPERTY_EXTDEVICE; + +typedef struct tagDEVCAPS +{ + LONG CanRecord; + LONG CanRecordStrobe; + LONG HasAudio; + LONG HasVideo; + LONG UsesFiles; + LONG CanSave; + LONG DeviceType; + LONG TCRead; + LONG TCWrite; + LONG CTLRead; + LONG IndexRead; + LONG Preroll; + LONG Postroll; + LONG SyncAcc; + LONG NormRate; + LONG CanPreview; + LONG CanMonitorSrc; + LONG CanTest; + LONG VideoIn; + LONG AudioIn; + LONG Calibrate; + LONG SeekType; + LONG SimulatedHardware; +}DEVCAPS, * PDEVCAPS; + +typedef struct +{ + KSPROPERTY Property; + union + { + DEVCAPS Capabilities; + ULONG DevPort; + ULONG PowerState; + WCHAR pawchString[MAX_PATH]; + DWORD NodeUniqueID[2]; + }u; +}KSPROPERTY_EXTDEVICE_S, * PKSPROPERTY_EXTDEVICE_S; + + # define STATIC_PROPSETID_EXT_TRANSPORT \ + 0xA03CD5F0L, 0x3045, 0x11cf, 0x8c, 0x44, 0x00, 0xAA, 0x00, 0x6B, 0x68, 0x14 +DEFINE_GUIDSTRUCT("A03CD5F0-3045-11cf-8C44-00AA006B6814", PROPSETID_EXT_TRANSPORT); + # define PROPSETID_EXT_TRANSPORT DEFINE_GUIDNAMED(PROPSETID_EXT_TRANSPORT) + +typedef enum +{ + KSPROPERTY_EXTXPORT_CAPABILITIES, + KSPROPERTY_EXTXPORT_INPUT_SIGNAL_MODE, + KSPROPERTY_EXTXPORT_OUTPUT_SIGNAL_MODE, + KSPROPERTY_EXTXPORT_LOAD_MEDIUM, + KSPROPERTY_EXTXPORT_MEDIUM_INFO, + KSPROPERTY_EXTXPORT_STATE, + KSPROPERTY_EXTXPORT_STATE_NOTIFY, + KSPROPERTY_EXTXPORT_TIMECODE_SEARCH, + KSPROPERTY_EXTXPORT_ATN_SEARCH, + KSPROPERTY_EXTXPORT_RTC_SEARCH, + KSPROPERTY_RAW_AVC_CMD +}KSPROPERTY_EXTXPORT; + +typedef struct tagTRANSPORTSTATUS +{ + LONG Mode; + LONG LastError; + LONG RecordInhibit; + LONG ServoLock; + LONG MediaPresent; + LONG MediaLength; + LONG MediaSize; + LONG MediaTrackCount; + LONG MediaTrackLength; + LONG MediaTrackSide; + LONG MediaType; + LONG LinkMode; + LONG NotifyOn; +}TRANSPORTSTATUS, * PTRANSPORTSTATUS; + +typedef struct tagTRANSPORTBASICPARMS +{ + LONG TimeFormat; + LONG TimeReference; + LONG Superimpose; + LONG EndStopAction; + LONG RecordFormat; + LONG StepFrames; + LONG SetpField; + LONG Preroll; + LONG RecPreroll; + LONG Postroll; + LONG EditDelay; + LONG PlayTCDelay; + LONG RecTCDelay; + LONG EditField; + LONG FrameServo; + LONG ColorFrameServo; + LONG ServoRef; + LONG WarnGenlock; + LONG SetTracking; + TCHAR VolumeName[40]; + LONG Ballistic[20]; + LONG Speed; + LONG CounterFormat; + LONG TunerChannel; + LONG TunerNumber; + LONG TimerEvent; + LONG TimerStartDay; + LONG TimerStartTime; + LONG TimerStopDay; + LONG TimerStopTime; +}TRANSPORTBASICPARMS, * PTRANSPORTBASICPARMS; + +typedef struct tagTRANSPORTVIDEOPARMS +{ + LONG OutputMode; + LONG Input; +}TRANSPORTVIDEOPARMS, * PTRANSPORTVIDEOPARMS; + +typedef struct tagTRANSPORTAUDIOPARMS +{ + LONG EnableOutput; + LONG EnableRecord; + LONG EnableSelsync; + LONG Input; + LONG MonitorSource; +}TRANSPORTAUDIOPARMS, * PTRANSPORTAUDIOPARMS; + +typedef struct +{ + WINBOOL MediaPresent; + ULONG MediaType; + WINBOOL RecordInhibit; +}MEDIUM_INFO, * PMEDIUM_INFO; + +typedef struct +{ + ULONG Mode; + ULONG State; +}TRANSPORT_STATE, * PTRANSPORT_STATE; + +typedef struct +{ + KSPROPERTY Property; + union + { + ULONG Capabilities; + ULONG SignalMode; + ULONG LoadMedium; + MEDIUM_INFO MediumInfo; + TRANSPORT_STATE XPrtState; + struct + { + BYTE frame; + BYTE second; + BYTE minute; + BYTE hour; + }Timecode; + DWORD dwTimecode; + DWORD dwAbsTrackNumber; + struct + { + ULONG PayloadSize; + BYTE Payload[512]; + }RawAVC; + }u; +}KSPROPERTY_EXTXPORT_S, * PKSPROPERTY_EXTXPORT_S; + +typedef struct +{ + KSP_NODE NodeProperty; + union + { + ULONG Capabilities; + ULONG SignalMode; + ULONG LoadMedium; + MEDIUM_INFO MediumInfo; + TRANSPORT_STATE XPrtState; + struct + { + BYTE frame; + BYTE second; + BYTE minute; + BYTE hour; + }Timecode; + DWORD dwTimecode; + DWORD dwAbsTrackNumber; + struct + { + ULONG PayloadSize; + BYTE Payload[512]; + }RawAVC; + }u; +}KSPROPERTY_EXTXPORT_NODE_S, * PKSPROPERTY_EXTXPORT_NODE_S; + + # define STATIC_PROPSETID_TIMECODE_READER \ + 0x9B496CE1L, 0x811B, 0x11cf, 0x8C, 0x77, 0x00, 0xAA, 0x00, 0x6B, 0x68, 0x14 +DEFINE_GUIDSTRUCT("9B496CE1-811B-11cf-8C77-00AA006B6814", PROPSETID_TIMECODE_READER); + # define PROPSETID_TIMECODE_READER DEFINE_GUIDNAMED(PROPSETID_TIMECODE_READER) + +typedef enum +{ + KSPROPERTY_TIMECODE_READER, + KSPROPERTY_ATN_READER, + KSPROPERTY_RTC_READER +}KSPROPERTY_TIMECODE; + + # ifndef TIMECODE_DEFINED + # define TIMECODE_DEFINED +typedef union _timecode +{ + struct + { + WORD wFrameRate; + WORD wFrameFract; + DWORD dwFrames; + }; + DWORDLONG qw; +}TIMECODE; +typedef TIMECODE* PTIMECODE; + +typedef struct tagTIMECODE_SAMPLE +{ + LONGLONG qwTick; + TIMECODE timecode; + DWORD dwUser; + DWORD dwFlags; +}TIMECODE_SAMPLE; + +typedef TIMECODE_SAMPLE* PTIMECODE_SAMPLE; + # endif /* TIMECODE_DEFINED */ + +typedef struct +{ + KSPROPERTY Property; + TIMECODE_SAMPLE TimecodeSamp; +}KSPROPERTY_TIMECODE_S, * PKSPROPERTY_TIMECODE_S; + +typedef struct +{ + KSP_NODE NodeProperty; + TIMECODE_SAMPLE TimecodeSamp; +}KSPROPERTY_TIMECODE_NODE_S, * PKSPROPERTY_TIMECODE_NODE_S; + + # define STATIC_KSEVENTSETID_EXTDEV_Command \ + 0x109c7988L, 0xb3cb, 0x11d2, 0xb4, 0x8e, 0x00, 0x60, 0x97, 0xb3, 0x39, 0x1b +DEFINE_GUIDSTRUCT("109c7988-b3cb-11d2-b48e-006097b3391b", KSEVENTSETID_EXTDEV_Command); + # define KSEVENTSETID_EXTDEV_Command DEFINE_GUIDNAMED(KSEVENTSETID_EXTDEV_Command) + +typedef enum +{ + KSEVENT_EXTDEV_COMMAND_NOTIFY_INTERIM_READY, + KSEVENT_EXTDEV_COMMAND_CONTROL_INTERIM_READY, + KSEVENT_EXTDEV_COMMAND_BUSRESET, + KSEVENT_EXTDEV_TIMECODE_UPDATE, + KSEVENT_EXTDEV_OPERATION_MODE_UPDATE, + KSEVENT_EXTDEV_TRANSPORT_STATE_UPDATE, + KSEVENT_EXTDEV_NOTIFY_REMOVAL, + KSEVENT_EXTDEV_NOTIFY_MEDIUM_CHANGE +}KSEVENT_DEVCMD; + # endif /* __EDevCtrl__ */ + + # define STATIC_PROPSETID_VIDCAP_CROSSBAR \ + 0x6a2e0640L, 0x28e4, 0x11d0, 0xa1, 0x8c, 0x00, 0xa0, 0xc9, 0x11, 0x89, 0x56 +DEFINE_GUIDSTRUCT("6a2e0640-28e4-11d0-a18c-00a0c9118956", PROPSETID_VIDCAP_CROSSBAR); + # define PROPSETID_VIDCAP_CROSSBAR DEFINE_GUIDNAMED(PROPSETID_VIDCAP_CROSSBAR) + +typedef enum +{ + KSPROPERTY_CROSSBAR_CAPS, + KSPROPERTY_CROSSBAR_PININFO, + KSPROPERTY_CROSSBAR_CAN_ROUTE, + KSPROPERTY_CROSSBAR_ROUTE +}KSPROPERTY_VIDCAP_CROSSBAR; + +typedef struct +{ + KSPROPERTY Property; + ULONG NumberOfInputs; + ULONG NumberOfOutputs; +}KSPROPERTY_CROSSBAR_CAPS_S, * PKSPROPERTY_CROSSBAR_CAPS_S; + +typedef struct +{ + KSPROPERTY Property; + KSPIN_DATAFLOW Direction; + ULONG Index; + ULONG PinType; + ULONG RelatedPinIndex; + KSPIN_MEDIUM Medium; +}KSPROPERTY_CROSSBAR_PININFO_S, * PKSPROPERTY_CROSSBAR_PININFO_S; + +typedef struct +{ + KSPROPERTY Property; + ULONG IndexInputPin; + ULONG IndexOutputPin; + ULONG CanRoute; +}KSPROPERTY_CROSSBAR_ROUTE_S, * PKSPROPERTY_CROSSBAR_ROUTE_S; + + # define STATIC_EVENTSETID_CROSSBAR \ + 0x6a2e0641L, 0x28e4, 0x11d0, 0xa1, 0x8c, 0x00, 0xa0, 0xc9, 0x11, 0x89, 0x56 +DEFINE_GUIDSTRUCT("6a2e0641-28e4-11d0-a18c-00a0c9118956", EVENTSETID_CROSSBAR); + # define EVENTSETID_CROSSBAR DEFINE_GUIDNAMED(EVENTSETID_CROSSBAR) + +typedef enum +{ + KSEVENT_CROSSBAR_CHANGED +}KSEVENT_CROSSBAR; + +typedef enum +{ + KS_PhysConn_Video_Tuner = 1, + KS_PhysConn_Video_Composite, + KS_PhysConn_Video_SVideo, + KS_PhysConn_Video_RGB, + KS_PhysConn_Video_YRYBY, + KS_PhysConn_Video_SerialDigital, + KS_PhysConn_Video_ParallelDigital, + KS_PhysConn_Video_SCSI, + KS_PhysConn_Video_AUX, + KS_PhysConn_Video_1394, + KS_PhysConn_Video_USB, + KS_PhysConn_Video_VideoDecoder, + KS_PhysConn_Video_VideoEncoder, + KS_PhysConn_Video_SCART, + KS_PhysConn_Audio_Tuner = 4096, + KS_PhysConn_Audio_Line, + KS_PhysConn_Audio_Mic, + KS_PhysConn_Audio_AESDigital, + KS_PhysConn_Audio_SPDIFDigital, + KS_PhysConn_Audio_SCSI, + KS_PhysConn_Audio_AUX, + KS_PhysConn_Audio_1394, + KS_PhysConn_Audio_USB, + KS_PhysConn_Audio_AudioDecoder +}KS_PhysicalConnectorType; + + # define STATIC_PROPSETID_VIDCAP_TVAUDIO \ + 0x6a2e0650L, 0x28e4, 0x11d0, 0xa1, 0x8c, 0x00, 0xa0, 0xc9, 0x11, 0x89, 0x56 +DEFINE_GUIDSTRUCT("6a2e0650-28e4-11d0-a18c-00a0c9118956", PROPSETID_VIDCAP_TVAUDIO); + # define PROPSETID_VIDCAP_TVAUDIO DEFINE_GUIDNAMED(PROPSETID_VIDCAP_TVAUDIO) + +typedef enum +{ + KSPROPERTY_TVAUDIO_CAPS, + KSPROPERTY_TVAUDIO_MODE, + KSPROPERTY_TVAUDIO_CURRENTLY_AVAILABLE_MODES +}KSPROPERTY_VIDCAP_TVAUDIO; + + # define KS_TVAUDIO_MODE_MONO 0x0001 + # define KS_TVAUDIO_MODE_STEREO 0x0002 + # define KS_TVAUDIO_MODE_LANG_A 0x0010 + # define KS_TVAUDIO_MODE_LANG_B 0x0020 + # define KS_TVAUDIO_MODE_LANG_C 0x0040 + +typedef struct +{ + KSPROPERTY Property; + ULONG Capabilities; + KSPIN_MEDIUM InputMedium; + KSPIN_MEDIUM OutputMedium; +}KSPROPERTY_TVAUDIO_CAPS_S, * PKSPROPERTY_TVAUDIO_CAPS_S; + +typedef struct +{ + KSPROPERTY Property; + ULONG Mode; +}KSPROPERTY_TVAUDIO_S, * PKSPROPERTY_TVAUDIO_S; + + # define STATIC_KSEVENTSETID_VIDCAP_TVAUDIO \ + 0x6a2e0651L, 0x28e4, 0x11d0, 0xa1, 0x8c, 0x00, 0xa0, 0xc9, 0x11, 0x89, 0x56 +DEFINE_GUIDSTRUCT("6a2e0651-28e4-11d0-a18c-00a0c9118956", KSEVENTSETID_VIDCAP_TVAUDIO); + # define KSEVENTSETID_VIDCAP_TVAUDIO DEFINE_GUIDNAMED(KSEVENTSETID_VIDCAP_TVAUDIO) + +typedef enum +{ + KSEVENT_TVAUDIO_CHANGED +}KSEVENT_TVAUDIO; + + # define STATIC_PROPSETID_VIDCAP_VIDEOCOMPRESSION \ + 0xC6E13343L, 0x30AC, 0x11d0, 0xA1, 0x8C, 0x00, 0xA0, 0xC9, 0x11, 0x89, 0x56 +DEFINE_GUIDSTRUCT("C6E13343-30AC-11d0-A18C-00A0C9118956", PROPSETID_VIDCAP_VIDEOCOMPRESSION); + # define PROPSETID_VIDCAP_VIDEOCOMPRESSION DEFINE_GUIDNAMED(PROPSETID_VIDCAP_VIDEOCOMPRESSION) + +typedef enum +{ + KSPROPERTY_VIDEOCOMPRESSION_GETINFO, + KSPROPERTY_VIDEOCOMPRESSION_KEYFRAME_RATE, + KSPROPERTY_VIDEOCOMPRESSION_PFRAMES_PER_KEYFRAME, + KSPROPERTY_VIDEOCOMPRESSION_QUALITY, + KSPROPERTY_VIDEOCOMPRESSION_OVERRIDE_KEYFRAME, + KSPROPERTY_VIDEOCOMPRESSION_OVERRIDE_FRAME_SIZE, + KSPROPERTY_VIDEOCOMPRESSION_WINDOWSIZE +}KSPROPERTY_VIDCAP_VIDEOCOMPRESSION; + +typedef enum +{ + KS_CompressionCaps_CanQuality = 1, + KS_CompressionCaps_CanCrunch = 2, + KS_CompressionCaps_CanKeyFrame = 4, + KS_CompressionCaps_CanBFrame = 8, + KS_CompressionCaps_CanWindow = 0x10 +}KS_CompressionCaps; + +typedef enum +{ + KS_StreamingHint_FrameInterval = 0x0100, + KS_StreamingHint_KeyFrameRate = 0x0200, + KS_StreamingHint_PFrameRate = 0x0400, + KS_StreamingHint_CompQuality = 0x0800, + KS_StreamingHint_CompWindowSize = 0x1000 +}KS_VideoStreamingHints; + +typedef struct +{ + KSPROPERTY Property; + ULONG StreamIndex; + LONG DefaultKeyFrameRate; + LONG DefaultPFrameRate; + LONG DefaultQuality; + LONG NumberOfQualitySettings; + LONG Capabilities; +}KSPROPERTY_VIDEOCOMPRESSION_GETINFO_S, * PKSPROPERTY_VIDEOCOMPRESSION_GETINFO_S; + +typedef struct +{ + KSPROPERTY Property; + ULONG StreamIndex; + LONG Value; +}KSPROPERTY_VIDEOCOMPRESSION_S, * PKSPROPERTY_VIDEOCOMPRESSION_S; + +typedef struct +{ + KSPROPERTY Property; + ULONG StreamIndex; + LONG Value; + ULONG Flags; +}KSPROPERTY_VIDEOCOMPRESSION_S1, * PKSPROPERTY_VIDEOCOMPRESSION_S1; + + # define STATIC_KSDATAFORMAT_SUBTYPE_OVERLAY \ + 0xe436eb7fL, 0x524f, 0x11ce, 0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70 +DEFINE_GUIDSTRUCT("e436eb7f-524f-11ce-9f53-0020af0ba770", KSDATAFORMAT_SUBTYPE_OVERLAY); + # define KSDATAFORMAT_SUBTYPE_OVERLAY DEFINE_GUIDNAMED(KSDATAFORMAT_SUBTYPE_OVERLAY) + + # define STATIC_KSPROPSETID_OverlayUpdate \ + 0x490EA5CFL, 0x7681, 0x11D1, 0xA2, 0x1C, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96 +DEFINE_GUIDSTRUCT("490EA5CF-7681-11D1-A21C-00A0C9223196", KSPROPSETID_OverlayUpdate); + # define KSPROPSETID_OverlayUpdate DEFINE_GUIDNAMED(KSPROPSETID_OverlayUpdate) + +typedef enum +{ + KSPROPERTY_OVERLAYUPDATE_INTERESTS, + KSPROPERTY_OVERLAYUPDATE_CLIPLIST = 0x1, + KSPROPERTY_OVERLAYUPDATE_PALETTE = 0x2, + KSPROPERTY_OVERLAYUPDATE_COLORKEY = 0x4, + KSPROPERTY_OVERLAYUPDATE_VIDEOPOSITION = 0x8, + KSPROPERTY_OVERLAYUPDATE_DISPLAYCHANGE = 0x10, + KSPROPERTY_OVERLAYUPDATE_COLORREF = 0x10000000 +}KSPROPERTY_OVERLAYUPDATE; + +typedef struct +{ + ULONG PelsWidth; + ULONG PelsHeight; + ULONG BitsPerPel; + WCHAR DeviceID[1]; +}KSDISPLAYCHANGE, * PKSDISPLAYCHANGE; + + # define DEFINE_KSPROPERTY_ITEM_OVERLAYUPDATE_INTERESTS(Handler) \ + DEFINE_KSPROPERTY_ITEM( \ + KSPROPERTY_OVERLAYUPDATE_INTERESTS, \ + (Handler), \ + sizeof(KSPROPERTY), \ + sizeof(ULONG), \ + NULL, NULL, 0, NULL, NULL, 0) + + # define DEFINE_KSPROPERTY_ITEM_OVERLAYUPDATE_PALETTE(Handler) \ + DEFINE_KSPROPERTY_ITEM( \ + KSPROPERTY_OVERLAYUPDATE_PALETTE, \ + NULL, \ + sizeof(KSPROPERTY), \ + 0, \ + (Handler), \ + NULL, 0, NULL, NULL, 0) + + # define DEFINE_KSPROPERTY_ITEM_OVERLAYUPDATE_COLORKEY(Handler) \ + DEFINE_KSPROPERTY_ITEM( \ + KSPROPERTY_OVERLAYUPDATE_COLORKEY, \ + NULL, \ + sizeof(KSPROPERTY), \ + sizeof(COLORKEY), \ + (Handler), \ + NULL, 0, NULL, NULL, 0) + + # define DEFINE_KSPROPERTY_ITEM_OVERLAYUPDATE_CLIPLIST(Handler) \ + DEFINE_KSPROPERTY_ITEM( \ + KSPROPERTY_OVERLAYUPDATE_CLIPLIST, \ + NULL, \ + sizeof(KSPROPERTY), \ + 2 * sizeof(RECT) + sizeof(RGNDATAHEADER), \ + (Handler), \ + NULL, 0, NULL, NULL, 0) + + # define DEFINE_KSPROPERTY_ITEM_OVERLAYUPDATE_VIDEOPOSITION(Handler) \ + DEFINE_KSPROPERTY_ITEM( \ + KSPROPERTY_OVERLAYUPDATE_VIDEOPOSITION, \ + NULL, \ + sizeof(KSPROPERTY), \ + 2 * sizeof(RECT), \ + (Handler), \ + NULL, 0, NULL, NULL, 0) + + # define DEFINE_KSPROPERTY_ITEM_OVERLAYUPDATE_DISPLAYCHANGE(Handler) \ + DEFINE_KSPROPERTY_ITEM( \ + KSPROPERTY_OVERLAYUPDATE_DISPLAYCHANGE, \ + NULL, \ + sizeof(KSPROPERTY), \ + sizeof(KSDISPLAYCHANGE), \ + (Handler), \ + NULL, 0, NULL, NULL, 0) + + # define DEFINE_KSPROPERTY_ITEM_OVERLAYUPDATE_COLORREF(Handler) \ + DEFINE_KSPROPERTY_ITEM( \ + KSPROPERTY_OVERLAYUPDATE_COLORREF, \ + (Handler), \ + sizeof(KSPROPERTY), \ + sizeof(COLORREF), \ + NULL, \ + NULL, 0, NULL, NULL, 0) + + # define STATIC_PROPSETID_VIDCAP_VIDEOCONTROL \ + 0x6a2e0670L, 0x28e4, 0x11d0, 0xa1, 0x8c, 0x00, 0xa0, 0xc9, 0x11, 0x89, 0x56 +DEFINE_GUIDSTRUCT("6a2e0670-28e4-11d0-a18c-00a0c9118956", PROPSETID_VIDCAP_VIDEOCONTROL); + # define PROPSETID_VIDCAP_VIDEOCONTROL DEFINE_GUIDNAMED(PROPSETID_VIDCAP_VIDEOCONTROL) + +typedef enum +{ + KSPROPERTY_VIDEOCONTROL_CAPS, + KSPROPERTY_VIDEOCONTROL_ACTUAL_FRAME_RATE, + KSPROPERTY_VIDEOCONTROL_FRAME_RATES, + KSPROPERTY_VIDEOCONTROL_MODE +}KSPROPERTY_VIDCAP_VIDEOCONTROL; + +typedef enum +{ + KS_VideoControlFlag_FlipHorizontal = 0x0001, + KS_VideoControlFlag_FlipVertical = 0x0002, + KS_Obsolete_VideoControlFlag_ExternalTriggerEnable = 0x0010, + KS_Obsolete_VideoControlFlag_Trigger = 0x0020, + KS_VideoControlFlag_ExternalTriggerEnable = 0x0004, + KS_VideoControlFlag_Trigger = 0x0008 +}KS_VideoControlFlags; + +typedef struct +{ + KSPROPERTY Property; + ULONG StreamIndex; + ULONG VideoControlCaps; +}KSPROPERTY_VIDEOCONTROL_CAPS_S, * PKSPROPERTY_VIDEOCONTROL_CAPS_S; + +typedef struct +{ + KSPROPERTY Property; + ULONG StreamIndex; + LONG Mode; +}KSPROPERTY_VIDEOCONTROL_MODE_S, * PKSPROPERTY_VIDEOCONTROL_MODE_S; + +typedef struct +{ + KSPROPERTY Property; + ULONG StreamIndex; + ULONG RangeIndex; + SIZE Dimensions; + LONGLONG CurrentActualFrameRate; + LONGLONG CurrentMaxAvailableFrameRate; +}KSPROPERTY_VIDEOCONTROL_ACTUAL_FRAME_RATE_S, * PKSPROPERTY_VIDEOCONTROL_ACTUAL_FRAME_RATE_S; + +typedef struct +{ + KSPROPERTY Property; + ULONG StreamIndex; + ULONG RangeIndex; + SIZE Dimensions; +}KSPROPERTY_VIDEOCONTROL_FRAME_RATES_S, * PKSPROPERTY_VIDEOCONTROL_FRAME_RATES_S; + + # define STATIC_PROPSETID_VIDCAP_DROPPEDFRAMES \ + 0xC6E13344L, 0x30AC, 0x11d0, 0xa1, 0x8c, 0x00, 0xa0, 0xc9, 0x11, 0x89, 0x56 +DEFINE_GUIDSTRUCT("C6E13344-30AC-11d0-A18C-00A0C9118956", PROPSETID_VIDCAP_DROPPEDFRAMES); + # define PROPSETID_VIDCAP_DROPPEDFRAMES DEFINE_GUIDNAMED(PROPSETID_VIDCAP_DROPPEDFRAMES) + +typedef enum +{ + KSPROPERTY_DROPPEDFRAMES_CURRENT +}KSPROPERTY_VIDCAP_DROPPEDFRAMES; + +typedef struct +{ + KSPROPERTY Property; + LONGLONG PictureNumber; + LONGLONG DropCount; + ULONG AverageFrameSize; +}KSPROPERTY_DROPPEDFRAMES_CURRENT_S, * PKSPROPERTY_DROPPEDFRAMES_CURRENT_S; + + # define STATIC_KSPROPSETID_VPConfig \ + 0xbc29a660L, 0x30e3, 0x11d0, 0x9e, 0x69, 0x00, 0xc0, 0x4f, 0xd7, 0xc1, 0x5b +DEFINE_GUIDSTRUCT("bc29a660-30e3-11d0-9e69-00c04fd7c15b", KSPROPSETID_VPConfig); + # define KSPROPSETID_VPConfig DEFINE_GUIDNAMED(KSPROPSETID_VPConfig) + + # define STATIC_KSPROPSETID_VPVBIConfig \ + 0xec529b00L, 0x1a1f, 0x11d1, 0xba, 0xd9, 0x0, 0x60, 0x97, 0x44, 0x11, 0x1a +DEFINE_GUIDSTRUCT("ec529b00-1a1f-11d1-bad9-00609744111a", KSPROPSETID_VPVBIConfig); + # define KSPROPSETID_VPVBIConfig DEFINE_GUIDNAMED(KSPROPSETID_VPVBIConfig) + +typedef enum +{ + KSPROPERTY_VPCONFIG_NUMCONNECTINFO, + KSPROPERTY_VPCONFIG_GETCONNECTINFO, + KSPROPERTY_VPCONFIG_SETCONNECTINFO, + KSPROPERTY_VPCONFIG_VPDATAINFO, + KSPROPERTY_VPCONFIG_MAXPIXELRATE, + KSPROPERTY_VPCONFIG_INFORMVPINPUT, + KSPROPERTY_VPCONFIG_NUMVIDEOFORMAT, + KSPROPERTY_VPCONFIG_GETVIDEOFORMAT, + KSPROPERTY_VPCONFIG_SETVIDEOFORMAT, + KSPROPERTY_VPCONFIG_INVERTPOLARITY, + KSPROPERTY_VPCONFIG_DECIMATIONCAPABILITY, + KSPROPERTY_VPCONFIG_SCALEFACTOR, + KSPROPERTY_VPCONFIG_DDRAWHANDLE, + KSPROPERTY_VPCONFIG_VIDEOPORTID, + KSPROPERTY_VPCONFIG_DDRAWSURFACEHANDLE, + KSPROPERTY_VPCONFIG_SURFACEPARAMS +}KSPROPERTY_VPCONFIG; + + # define STATIC_CLSID_KsIBasicAudioInterfaceHandler \ + 0xb9f8ac3e, 0x0f71, 0x11d2, 0xb7, 0x2c, 0x00, 0xc0, 0x4f, 0xb6, 0xbd, 0x3d +DEFINE_GUIDSTRUCT("b9f8ac3e-0f71-11d2-b72c-00c04fb6bd3d", CLSID_KsIBasicAudioInterfaceHandler); + # define CLSID_KsIBasicAudioInterfaceHandler DEFINE_GUIDNAMED(CLSID_KsIBasicAudioInterfaceHandler) + + # ifdef __IVPType__ +typedef struct +{ + AMVPSIZE Size; + DWORD MaxPixelsPerSecond; + DWORD Reserved; +}KSVPMAXPIXELRATE, * PKSVPMAXPIXELRATE; + +typedef struct +{ + KSPROPERTY Property; + AMVPSIZE Size; +}KSVPSIZE_PROP, * PKSVPSIZE_PROP; + +typedef struct +{ + DWORD dwPitch; + DWORD dwXOrigin; + DWORD dwYOrigin; +}KSVPSURFACEPARAMS, * PKSVPSURFACEPARAMS; + # else /* __IVPType__ */ + + # ifndef __DDRAW_INCLUDED__ + # define DDPF_FOURCC 0x00000004l + +typedef struct _DDPIXELFORMAT +{ + DWORD dwSize; + DWORD dwFlags; + DWORD dwFourCC; + __MINGW_EXTENSION union + { + DWORD dwRGBBitCount; + DWORD dwYUVBitCount; + DWORD dwZBufferBitDepth; + DWORD dwAlphaBitDepth; + }; + __MINGW_EXTENSION union + { + DWORD dwRBitMask; + DWORD dwYBitMask; + }; + __MINGW_EXTENSION union + { + DWORD dwGBitMask; + DWORD dwUBitMask; + }; + __MINGW_EXTENSION union + { + DWORD dwBBitMask; + DWORD dwVBitMask; + }; + __MINGW_EXTENSION union + { + DWORD dwRGBAlphaBitMask; + DWORD dwYUVAlphaBitMask; + DWORD dwRGBZBitMask; + DWORD dwYUVZBitMask; + }; +}DDPIXELFORMAT, * LPDDPIXELFORMAT; + # endif /* __DDRAW_INCLUDED__ */ + + # ifndef __DVP_INCLUDED__ +typedef struct _DDVIDEOPORTCONNECT +{ + DWORD dwSize; + DWORD dwPortWidth; + GUID guidTypeID; + DWORD dwFlags; + ULONG_PTR dwReserved1; +}DDVIDEOPORTCONNECT, * LPDDVIDEOPORTCONNECT; + + # define DDVPTYPE_E_HREFH_VREFH \ + 0x54F39980L, 0xDA60, 0x11CF, 0x9B, 0x06, 0x00, 0xA0, 0xC9, 0x03, 0xA3, 0xB8 + + # define DDVPTYPE_E_HREFL_VREFL \ + 0xE09C77E0L, 0xDA60, 0x11CF, 0x9B, 0x06, 0x00, 0xA0, 0xC9, 0x03, 0xA3, 0xB8 + # endif /* __DVP_INCLUDED__ */ + +typedef enum +{ + KS_PixAspectRatio_NTSC4x3, + KS_PixAspectRatio_NTSC16x9, + KS_PixAspectRatio_PAL4x3, + KS_PixAspectRatio_PAL16x9 +}KS_AMPixAspectRatio; + +typedef enum +{ + KS_AMVP_DO_NOT_CARE, + KS_AMVP_BEST_BANDWIDTH, + KS_AMVP_INPUT_SAME_AS_OUTPUT +}KS_AMVP_SELECTFORMATBY; + +typedef enum +{ + KS_AMVP_MODE_WEAVE, + KS_AMVP_MODE_BOBINTERLEAVED, + KS_AMVP_MODE_BOBNONINTERLEAVED, + KS_AMVP_MODE_SKIPEVEN, + KS_AMVP_MODE_SKIPODD +}KS_AMVP_MODE; + +typedef struct tagKS_AMVPDIMINFO +{ + DWORD dwFieldWidth; + DWORD dwFieldHeight; + DWORD dwVBIWidth; + DWORD dwVBIHeight; + RECT rcValidRegion; +}KS_AMVPDIMINFO, * PKS_AMVPDIMINFO; + +typedef struct tagKS_AMVPDATAINFO +{ + DWORD dwSize; + DWORD dwMicrosecondsPerField; + KS_AMVPDIMINFO amvpDimInfo; + DWORD dwPictAspectRatioX; + DWORD dwPictAspectRatioY; + WINBOOL bEnableDoubleClock; + WINBOOL bEnableVACT; + WINBOOL bDataIsInterlaced; + LONG lHalfLinesOdd; + WINBOOL bFieldPolarityInverted; + DWORD dwNumLinesInVREF; + LONG lHalfLinesEven; + DWORD dwReserved1; +}KS_AMVPDATAINFO, * PKS_AMVPDATAINFO; + +typedef struct tagKS_AMVPSIZE +{ + DWORD dwWidth; + DWORD dwHeight; +}KS_AMVPSIZE, * PKS_AMVPSIZE; + +typedef struct +{ + KS_AMVPSIZE Size; + DWORD MaxPixelsPerSecond; + DWORD Reserved; +}KSVPMAXPIXELRATE, * PKSVPMAXPIXELRATE; + +typedef struct +{ + KSPROPERTY Property; + KS_AMVPSIZE Size; +}KSVPSIZE_PROP, * PKSVPSIZE_PROP; + +typedef struct +{ + DWORD dwPitch; + DWORD dwXOrigin; + DWORD dwYOrigin; +}KSVPSURFACEPARAMS, * PKSVPSURFACEPARAMS; + # endif /* __IVPType__ */ + + # define STATIC_KSEVENTSETID_VPNotify \ + 0x20c5598eL, 0xd3c8, 0x11d0, 0x8d, 0xfc, 0x00, 0xc0, 0x4f, 0xd7, 0xc0, 0x8b +DEFINE_GUIDSTRUCT("20c5598e-d3c8-11d0-8dfc-00c04fd7c08b", KSEVENTSETID_VPNotify); + # define KSEVENTSETID_VPNotify DEFINE_GUIDNAMED(KSEVENTSETID_VPNotify) + +typedef enum +{ + KSEVENT_VPNOTIFY_FORMATCHANGE +}KSEVENT_VPNOTIFY; + + # define STATIC_KSEVENTSETID_VIDCAPTOSTI \ + 0xdb47de20, 0xf628, 0x11d1, 0xba, 0x41, 0x0, 0xa0, 0xc9, 0xd, 0x2b, 0x5 +DEFINE_GUIDSTRUCT("DB47DE20-F628-11d1-BA41-00A0C90D2B05", KSEVENTSETID_VIDCAPTOSTI); + # define KSEVENTSETID_VIDCAPNotify DEFINE_GUIDNAMED(KSEVENTSETID_VIDCAPTOSTI) + +typedef enum +{ + KSEVENT_VIDCAPTOSTI_EXT_TRIGGER, + KSEVENT_VIDCAP_AUTO_UPDATE, + KSEVENT_VIDCAP_SEARCH +}KSEVENT_VIDCAPTOSTI; + +typedef enum +{ + KSPROPERTY_EXTENSION_UNIT_INFO, + KSPROPERTY_EXTENSION_UNIT_CONTROL, + KSPROPERTY_EXTENSION_UNIT_PASS_THROUGH = 0xffff +}KSPROPERTY_EXTENSION_UNIT, * PKSPROPERTY_EXTENSION_UNIT; + + # define STATIC_KSEVENTSETID_VPVBINotify \ + 0xec529b01L, 0x1a1f, 0x11d1, 0xba, 0xd9, 0x0, 0x60, 0x97, 0x44, 0x11, 0x1a +DEFINE_GUIDSTRUCT("ec529b01-1a1f-11d1-bad9-00609744111a", KSEVENTSETID_VPVBINotify); + # define KSEVENTSETID_VPVBINotify DEFINE_GUIDNAMED(KSEVENTSETID_VPVBINotify) + +typedef enum +{ + KSEVENT_VPVBINOTIFY_FORMATCHANGE +}KSEVENT_VPVBINOTIFY; + + # define STATIC_KSDATAFORMAT_TYPE_AUXLine21Data \ + 0x670aea80L, 0x3a82, 0x11d0, 0xb7, 0x9b, 0x00, 0xaa, 0x00, 0x37, 0x67, 0xa7 +DEFINE_GUIDSTRUCT("670aea80-3a82-11d0-b79b-00aa003767a7", KSDATAFORMAT_TYPE_AUXLine21Data); + # define KSDATAFORMAT_TYPE_AUXLine21Data DEFINE_GUIDNAMED(KSDATAFORMAT_TYPE_AUXLine21Data) + + # define STATIC_KSDATAFORMAT_SUBTYPE_Line21_BytePair \ + 0x6e8d4a22L, 0x310c, 0x11d0, 0xb7, 0x9a, 0x00, 0xaa, 0x00, 0x37, 0x67, 0xa7 +DEFINE_GUIDSTRUCT("6e8d4a22-310c-11d0-b79a-00aa003767a7", KSDATAFORMAT_SUBTYPE_Line21_BytePair); + # define KSDATAFORMAT_SUBTYPE_Line21_BytePair DEFINE_GUIDNAMED(KSDATAFORMAT_SUBTYPE_Line21_BytePair) + + # define STATIC_KSDATAFORMAT_SUBTYPE_Line21_GOPPacket \ + 0x6e8d4a23L, 0x310c, 0x11d0, 0xb7, 0x9a, 0x00, 0xaa, 0x00, 0x37, 0x67, 0xa7 +DEFINE_GUIDSTRUCT("6e8d4a23-310c-11d0-b79a-00aa003767a7", KSDATAFORMAT_SUBTYPE_Line21_GOPPacket); + # define KSDATAFORMAT_SUBTYPE_Line21_GOPPacket DEFINE_GUIDNAMED(KSDATAFORMAT_SUBTYPE_Line21_GOPPacket) + +typedef struct _KSGOP_USERDATA +{ + ULONG sc; + ULONG reserved1; + BYTE cFields; + CHAR l21Data[3]; +}KSGOP_USERDATA, * PKSGOP_USERDATA; + + # define STATIC_KSDATAFORMAT_TYPE_DVD_ENCRYPTED_PACK \ + 0xed0b916a, 0x044d, 0x11d1, 0xaa, 0x78, 0x00, 0xc0, 0x4f, 0xc3, 0x1d, 0x60 +DEFINE_GUIDSTRUCT("ed0b916a-044d-11d1-aa78-00c04fc31d60", KSDATAFORMAT_TYPE_DVD_ENCRYPTED_PACK); + # define KSDATAFORMAT_TYPE_DVD_ENCRYPTED_PACK DEFINE_GUIDNAMED(KSDATAFORMAT_TYPE_DVD_ENCRYPTED_PACK) + + # define KS_AM_UseNewCSSKey 0x1 + + # define STATIC_KSPROPSETID_TSRateChange \ + 0xa503c5c0, 0x1d1d, 0x11d1, 0xad, 0x80, 0x44, 0x45, 0x53, 0x54, 0x0, 0x0 +DEFINE_GUIDSTRUCT("A503C5C0-1D1D-11D1-AD80-444553540000", KSPROPSETID_TSRateChange); + # define KSPROPSETID_TSRateChange DEFINE_GUIDNAMED(KSPROPSETID_TSRateChange) + +typedef enum +{ + KS_AM_RATE_SimpleRateChange = 1, + KS_AM_RATE_ExactRateChange = 2, + KS_AM_RATE_MaxFullDataRate = 3, + KS_AM_RATE_Step = 4 +}KS_AM_PROPERTY_TS_RATE_CHANGE; + +typedef struct +{ + REFERENCE_TIME StartTime; + LONG Rate; +}KS_AM_SimpleRateChange, * PKS_AM_SimpleRateChange; + +typedef struct +{ + REFERENCE_TIME OutputZeroTime; + LONG Rate; +}KS_AM_ExactRateChange, * PKS_AM_ExactRateChange; + +typedef LONG KS_AM_MaxFullDataRate; +typedef DWORD KS_AM_Step; + + # define STATIC_KSCATEGORY_ENCODER \ + 0x19689bf6, 0xc384, 0x48fd, 0xad, 0x51, 0x90, 0xe5, 0x8c, 0x79, 0xf7, 0xb +DEFINE_GUIDSTRUCT("19689BF6-C384-48fd-AD51-90E58C79F70B", KSCATEGORY_ENCODER); + # define KSCATEGORY_ENCODER DEFINE_GUIDNAMED(KSCATEGORY_ENCODER) + + # define STATIC_KSCATEGORY_MULTIPLEXER \ + 0x7a5de1d3, 0x1a1, 0x452c, 0xb4, 0x81, 0x4f, 0xa2, 0xb9, 0x62, 0x71, 0xe8 +DEFINE_GUIDSTRUCT("7A5DE1D3-01A1-452c-B481-4FA2B96271E8", KSCATEGORY_MULTIPLEXER); + # define KSCATEGORY_MULTIPLEXER DEFINE_GUIDNAMED(KSCATEGORY_MULTIPLEXER) + + # ifndef __ENCODER_API_GUIDS__ + # define __ENCODER_API_GUIDS__ + + # define STATIC_ENCAPIPARAM_BITRATE \ + 0x49cc4c43, 0xca83, 0x4ad4, 0xa9, 0xaf, 0xf3, 0x69, 0x6a, 0xf6, 0x66, 0xdf +DEFINE_GUIDSTRUCT("49CC4C43-CA83-4ad4-A9AF-F3696AF666DF", ENCAPIPARAM_BITRATE); + # define ENCAPIPARAM_BITRATE DEFINE_GUIDNAMED(ENCAPIPARAM_BITRATE) + + # define STATIC_ENCAPIPARAM_PEAK_BITRATE \ + 0x703f16a9, 0x3d48, 0x44a1, 0xb0, 0x77, 0x1, 0x8d, 0xff, 0x91, 0x5d, 0x19 +DEFINE_GUIDSTRUCT("703F16A9-3D48-44a1-B077-018DFF915D19", ENCAPIPARAM_PEAK_BITRATE); + # define ENCAPIPARAM_PEAK_BITRATE DEFINE_GUIDNAMED(ENCAPIPARAM_PEAK_BITRATE) + + # define STATIC_ENCAPIPARAM_BITRATE_MODE \ + 0xee5fb25c, 0xc713, 0x40d1, 0x9d, 0x58, 0xc0, 0xd7, 0x24, 0x1e, 0x25, 0xf +DEFINE_GUIDSTRUCT("EE5FB25C-C713-40d1-9D58-C0D7241E250F", ENCAPIPARAM_BITRATE_MODE); + # define ENCAPIPARAM_BITRATE_MODE DEFINE_GUIDNAMED(ENCAPIPARAM_BITRATE_MODE) + + # define STATIC_CODECAPI_CHANGELISTS \ + 0x62b12acf, 0xf6b0, 0x47d9, 0x94, 0x56, 0x96, 0xf2, 0x2c, 0x4e, 0x0b, 0x9d +DEFINE_GUIDSTRUCT("62B12ACF-F6B0-47D9-9456-96F22C4E0B9D", CODECAPI_CHANGELISTS); + # define CODECAPI_CHANGELISTS DEFINE_GUIDNAMED(CODECAPI_CHANGELISTS) + + # define STATIC_CODECAPI_VIDEO_ENCODER \ + 0x7112e8e1, 0x3d03, 0x47ef, 0x8e, 0x60, 0x03, 0xf1, 0xcf, 0x53, 0x73, 0x01 +DEFINE_GUIDSTRUCT("7112E8E1-3D03-47EF-8E60-03F1CF537301", CODECAPI_VIDEO_ENCODER); + # define CODECAPI_VIDEO_ENCODER DEFINE_GUIDNAMED(CODECAPI_VIDEO_ENCODER) + + # define STATIC_CODECAPI_AUDIO_ENCODER \ + 0xb9d19a3e, 0xf897, 0x429c, 0xbc, 0x46, 0x81, 0x38, 0xb7, 0x27, 0x2b, 0x2d +DEFINE_GUIDSTRUCT("B9D19A3E-F897-429C-BC46-8138B7272B2D", CODECAPI_AUDIO_ENCODER); + # define CODECAPI_AUDIO_ENCODER DEFINE_GUIDNAMED(CODECAPI_AUDIO_ENCODER) + + # define STATIC_CODECAPI_SETALLDEFAULTS \ + 0x6c5e6a7c, 0xacf8, 0x4f55, 0xa9, 0x99, 0x1a, 0x62, 0x81, 0x09, 0x05, 0x1b +DEFINE_GUIDSTRUCT("6C5E6A7C-ACF8-4F55-A999-1A628109051B", CODECAPI_SETALLDEFAULTS); + # define CODECAPI_SETALLDEFAULTS DEFINE_GUIDNAMED(CODECAPI_SETALLDEFAULTS) + + # define STATIC_CODECAPI_ALLSETTINGS \ + 0x6a577e92, 0x83e1, 0x4113, 0xad, 0xc2, 0x4f, 0xce, 0xc3, 0x2f, 0x83, 0xa1 +DEFINE_GUIDSTRUCT("6A577E92-83E1-4113-ADC2-4FCEC32F83A1", CODECAPI_ALLSETTINGS); + # define CODECAPI_ALLSETTINGS DEFINE_GUIDNAMED(CODECAPI_ALLSETTINGS) + + # define STATIC_CODECAPI_SUPPORTSEVENTS \ + 0x0581af97, 0x7693, 0x4dbd, 0x9d, 0xca, 0x3f, 0x9e, 0xbd, 0x65, 0x85, 0xa1 +DEFINE_GUIDSTRUCT("0581AF97-7693-4DBD-9DCA-3F9EBD6585A1", CODECAPI_SUPPORTSEVENTS); + # define CODECAPI_SUPPORTSEVENTS DEFINE_GUIDNAMED(CODECAPI_SUPPORTSEVENTS) + + # define STATIC_CODECAPI_CURRENTCHANGELIST \ + 0x1cb14e83, 0x7d72, 0x4657, 0x83, 0xfd, 0x47, 0xa2, 0xc5, 0xb9, 0xd1, 0x3d +DEFINE_GUIDSTRUCT("1CB14E83-7D72-4657-83FD-47A2C5B9D13D", CODECAPI_CURRENTCHANGELIST); + # define CODECAPI_CURRENTCHANGELIST DEFINE_GUIDNAMED(CODECAPI_CURRENTCHANGELIST) + # endif /* __ENCODER_API_GUIDS__ */ + + # ifndef __ENCODER_API_DEFINES__ + # define __ENCODER_API_DEFINES__ +typedef enum +{ + ConstantBitRate = 0, + VariableBitRateAverage, + VariableBitRatePeak +}VIDEOENCODER_BITRATE_MODE; + # endif /* __ENCODER_API_DEFINES__ */ + + # define STATIC_KSPROPSETID_Jack \ + 0x4509f757, 0x2d46, 0x4637, 0x8e, 0x62, 0xce, 0x7d, 0xb9, 0x44, 0xf5, 0x7b +DEFINE_GUIDSTRUCT("4509F757-2D46-4637-8E62-CE7DB944F57B", KSPROPSETID_Jack); + # define KSPROPSETID_Jack DEFINE_GUIDNAMED(KSPROPSETID_Jack) + +typedef enum +{ + KSPROPERTY_JACK_DESCRIPTION = 1, + KSPROPERTY_JACK_DESCRIPTION2, + KSPROPERTY_JACK_SINK_INFO +}KSPROPERTY_JACK; + +typedef enum +{ + eConnTypeUnknown, + eConnType3Point5mm, + eConnTypeQuarter, + eConnTypeAtapiInternal, + eConnTypeRCA, + eConnTypeOptical, + eConnTypeOtherDigital, + eConnTypeOtherAnalog, + eConnTypeMultichannelAnalogDIN, + eConnTypeXlrProfessional, + eConnTypeRJ11Modem, + eConnTypeCombination +}EPcxConnectionType; + +typedef enum +{ + eGeoLocRear = 0x1, + eGeoLocFront, + eGeoLocLeft, + eGeoLocRight, + eGeoLocTop, + eGeoLocBottom, + eGeoLocRearPanel, + eGeoLocRiser, + eGeoLocInsideMobileLid, + eGeoLocDrivebay, + eGeoLocHDMI, + eGeoLocOutsideMobileLid, + eGeoLocATAPI, + eGeoLocReserved5, + eGeoLocReserved6, + EPcxGeoLocation_enum_count +}EPcxGeoLocation; + +typedef enum +{ + eGenLocPrimaryBox = 0, + eGenLocInternal, + eGenLocSeparate, + eGenLocOther, + EPcxGenLocation_enum_count +}EPcxGenLocation; + +typedef enum +{ + ePortConnJack = 0, + ePortConnIntegratedDevice, + ePortConnBothIntegratedAndJack, + ePortConnUnknown +}EPxcPortConnection; + +typedef struct +{ + DWORD ChannelMapping; + COLORREF Color; + EPcxConnectionType ConnectionType; + EPcxGeoLocation GeoLocation; + EPcxGenLocation GenLocation; + EPxcPortConnection PortConnection; + BOOL IsConnected; +}KSJACK_DESCRIPTION, * PKSJACK_DESCRIPTION; + +typedef enum +{ + KSJACK_SINK_CONNECTIONTYPE_HDMI = 0, + KSJACK_SINK_CONNECTIONTYPE_DISPLAYPORT, +}KSJACK_SINK_CONNECTIONTYPE; + + # define MAX_SINK_DESCRIPTION_NAME_LENGTH 32 +typedef struct _tagKSJACK_SINK_INFORMATION +{ + KSJACK_SINK_CONNECTIONTYPE ConnType; + WORD ManufacturerId; + WORD ProductId; + WORD AudioLatency; + BOOL HDCPCapable; + BOOL AICapable; + UCHAR SinkDescriptionLength; + WCHAR SinkDescription[MAX_SINK_DESCRIPTION_NAME_LENGTH]; + LUID PortId; +}KSJACK_SINK_INFORMATION, * PKSJACK_SINK_INFORMATION; + + # define JACKDESC2_PRESENCE_DETECT_CAPABILITY 0x00000001 + # define JACKDESC2_DYNAMIC_FORMAT_CHANGE_CAPABILITY 0x00000002 + +typedef struct _tagKSJACK_DESCRIPTION2 +{ + DWORD DeviceStateInfo; + DWORD JackCapabilities; +}KSJACK_DESCRIPTION2, * PKSJACK_DESCRIPTION2; + +#endif /* _KSMEDIA_ */ + From 376f2894db13d01cac964c702cd09b9facdcea99 Mon Sep 17 00:00:00 2001 From: Tobias Schlemmer Date: Fri, 2 May 2014 21:35:34 +0200 Subject: [PATCH 10/45] Revert "Removed Windows kernel streaming code because it was incomplete and uncompilable. The code still exists in the winks branch." This reverts commit d07f6011cfdb3ba59cbd409b7005d5676cdca4d4. --- RtMidi.cpp | 1045 ++++++++++++++++++++++++++++++++++++++ RtMidi.h | 40 +- doc/doxygen/tutorial.txt | 13 +- doc/release.txt | 1 - readme | 2 +- 5 files changed, 1095 insertions(+), 6 deletions(-) diff --git a/RtMidi.cpp b/RtMidi.cpp index 07e23168..2101c377 100644 --- a/RtMidi.cpp +++ b/RtMidi.cpp @@ -78,6 +78,9 @@ void RtMidi :: getCompiledApi( std::vector &apis ) throw() #if defined(__WINDOWS_MM__) apis.push_back( WINDOWS_MM ); #endif +#if defined(__WINDOWS_KS__) + apis.push_back( WINDOWS_KS ); +#endif #if defined(__RTMIDI_DUMMY__) apis.push_back( RTMIDI_DUMMY ); #endif @@ -105,6 +108,10 @@ void RtMidiIn :: openMidiApi( RtMidi::Api api, const std::string clientName, uns if ( api == WINDOWS_MM ) rtapi_ = new MidiInWinMM( clientName, queueSizeLimit ); #endif +#if defined(__WINDOWS_KS__) + if ( api == WINDOWS_KS ) + rtapi_ = new MidiInWinKS( clientName, queueSizeLimit ); +#endif #if defined(__MACOSX_CORE__) if ( api == MACOSX_CORE ) rtapi_ = new MidiInCore( clientName, queueSizeLimit ); @@ -174,6 +181,10 @@ void RtMidiOut :: openMidiApi( RtMidi::Api api, const std::string clientName ) if ( api == WINDOWS_MM ) rtapi_ = new MidiOutWinMM( clientName ); #endif +#if defined(__WINDOWS_KS__) + if ( api == WINDOWS_KS ) + rtapi_ = new MidiOutWinKS( clientName ); +#endif #if defined(__MACOSX_CORE__) if ( api == MACOSX_CORE ) rtapi_ = new MidiOutCore( clientName ); @@ -2423,6 +2434,1040 @@ void MidiOutWinMM :: sendMessage( std::vector *message ) #endif // __WINDOWS_MM__ +// *********************************************************************// +// API: WINDOWS Kernel Streaming +// +// Written by Sebastien Alaiwan, 2012. +// +// NOTE BY GARY: much of the KS-specific code below probably should go in a separate file. +// +// *********************************************************************// + +#if defined(__WINDOWS_KS__) + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ks.h" +#include "ksmedia.h" + +#define INSTANTIATE_GUID(a) GUID const a = { STATIC_ ## a } + +INSTANTIATE_GUID(GUID_NULL); +INSTANTIATE_GUID(KSPROPSETID_Pin); +INSTANTIATE_GUID(KSPROPSETID_Connection); +INSTANTIATE_GUID(KSPROPSETID_Topology); +INSTANTIATE_GUID(KSINTERFACESETID_Standard); +INSTANTIATE_GUID(KSMEDIUMSETID_Standard); +INSTANTIATE_GUID(KSDATAFORMAT_TYPE_MUSIC); +INSTANTIATE_GUID(KSDATAFORMAT_SUBTYPE_MIDI); +INSTANTIATE_GUID(KSDATAFORMAT_SPECIFIER_NONE); + +#undef INSTANTIATE_GUID + +typedef std::basic_string tstring; + +inline bool IsValid(HANDLE handle) +{ + return handle != NULL && handle != INVALID_HANDLE_VALUE; +} + +class ComException : public std::runtime_error +{ +private: + static std::string MakeString(std::string const& s, HRESULT hr) + { + std::stringstream ss; + ss << "(error 0x" << std::hex << hr << ")"; + return s + ss.str(); + } + +public: + ComException(std::string const& s, HRESULT hr) : + std::runtime_error(MakeString(s, hr)) + { + } +}; + +template +class CKsEnumFilters +{ +public: + ~CKsEnumFilters() + { + DestroyLists(); + } + + void EnumFilters(GUID const* categories, size_t numCategories) + { + DestroyLists(); + + if (categories == 0) + throw std::runtime_error("CKsEnumFilters: invalid argument"); + + // Get a handle to the device set specified by the guid + HDEVINFO hDevInfo = ::SetupDiGetClassDevs(&categories[0], NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); + if (!IsValid(hDevInfo)) + throw std::runtime_error("CKsEnumFilters: no devices found"); + + // Loop through members of the set and get details for each + for ( int iClassMember=0; iClassMember++ ) { + try { + SP_DEVICE_INTERFACE_DATA DID; + DID.cbSize = sizeof(DID); + DID.Reserved = 0; + + bool fRes = ::SetupDiEnumDeviceInterfaces(hDevInfo, NULL, &categories[0], iClassMember, &DID); + if (!fRes) + break; + + // Get filter friendly name + HKEY hRegKey = ::SetupDiOpenDeviceInterfaceRegKey(hDevInfo, &DID, 0, KEY_READ); + if (hRegKey == INVALID_HANDLE_VALUE) + throw std::runtime_error("CKsEnumFilters: interface has no registry"); + + char friendlyName[256]; + DWORD dwSize = sizeof friendlyName; + LONG lval = ::RegQueryValueEx(hRegKey, TEXT("FriendlyName"), NULL, NULL, (LPBYTE)friendlyName, &dwSize); + ::RegCloseKey(hRegKey); + if (lval != ERROR_SUCCESS) + throw std::runtime_error("CKsEnumFilters: interface has no friendly name"); + + // Get details for the device registered in this class + DWORD const cbItfDetails = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA) + MAX_PATH * sizeof(WCHAR); + std::vector buffer(cbItfDetails); + + SP_DEVICE_INTERFACE_DETAIL_DATA* pDevInterfaceDetails = reinterpret_cast(&buffer[0]); + pDevInterfaceDetails->cbSize = sizeof(*pDevInterfaceDetails); + + SP_DEVINFO_DATA DevInfoData; + DevInfoData.cbSize = sizeof(DevInfoData); + DevInfoData.Reserved = 0; + + fRes = ::SetupDiGetDeviceInterfaceDetail(hDevInfo, &DID, pDevInterfaceDetails, cbItfDetails, NULL, &DevInfoData); + if (!fRes) + throw std::runtime_error("CKsEnumFilters: could not get interface details"); + + // check additional category guids which may (or may not) have been supplied + for (size_t i=1; i < numCategories; ++i) { + SP_DEVICE_INTERFACE_DATA DIDAlias; + DIDAlias.cbSize = sizeof(DIDAlias); + DIDAlias.Reserved = 0; + + fRes = ::SetupDiGetDeviceInterfaceAlias(hDevInfo, &DID, &categories[i], &DIDAlias); + if (!fRes) + throw std::runtime_error("CKsEnumFilters: could not get interface alias"); + + // Check if the this interface alias is enabled. + if (!DIDAlias.Flags || (DIDAlias.Flags & SPINT_REMOVED)) + throw std::runtime_error("CKsEnumFilters: interface alias is not enabled"); + } + + std::auto_ptr pFilter(new TFilterType(pDevInterfaceDetails->DevicePath, friendlyName)); + + pFilter->Instantiate(); + pFilter->FindMidiPins(); + pFilter->Validate(); + + m_Filters.push_back(pFilter.release()); + } + catch (std::runtime_error const& e) { + } + } + + ::SetupDiDestroyDeviceInfoList(hDevInfo); + } + +private: + void DestroyLists() + { + for (size_t i=0;i < m_Filters.size();++i) + delete m_Filters[i]; + m_Filters.clear(); + } + +public: + // TODO: make this private. + std::vector m_Filters; +}; + +class CKsObject +{ +public: + CKsObject(HANDLE handle) : m_handle(handle) + { + } + +protected: + HANDLE m_handle; + + void SetProperty(REFGUID guidPropertySet, ULONG nProperty, void* pvValue, ULONG cbValue) + { + KSPROPERTY ksProperty; + memset(&ksProperty, 0, sizeof ksProperty); + ksProperty.Set = guidPropertySet; + ksProperty.Id = nProperty; + ksProperty.Flags = KSPROPERTY_TYPE_SET; + + HRESULT hr = DeviceIoControlKsProperty(ksProperty, pvValue, cbValue); + if (FAILED(hr)) + throw ComException("CKsObject::SetProperty: could not set property", hr); + } + +private: + + HRESULT DeviceIoControlKsProperty(KSPROPERTY& ksProperty, void* pvValue, ULONG cbValue) + { + ULONG ulReturned; + return ::DeviceIoControl( + m_handle, + IOCTL_KS_PROPERTY, + &ksProperty, + sizeof(ksProperty), + pvValue, + cbValue, + &ulReturned, + NULL); + } +}; + +class CKsPin; + +class CKsFilter : public CKsObject +{ + friend class CKsPin; + +public: + CKsFilter(tstring const& name, std::string const& sFriendlyName); + virtual ~CKsFilter(); + + virtual void Instantiate(); + + template + T GetPinProperty(ULONG nPinId, ULONG nProperty) + { + ULONG ulReturned = 0; + T value; + + KSP_PIN ksPProp; + ksPProp.Property.Set = KSPROPSETID_Pin; + ksPProp.Property.Id = nProperty; + ksPProp.Property.Flags = KSPROPERTY_TYPE_GET; + ksPProp.PinId = nPinId; + ksPProp.Reserved = 0; + + HRESULT hr = ::DeviceIoControl( + m_handle, + IOCTL_KS_PROPERTY, + &ksPProp, + sizeof(KSP_PIN), + &value, + sizeof(value), + &ulReturned, + NULL); + if (FAILED(hr)) + throw ComException("CKsFilter::GetPinProperty: failed to retrieve property", hr); + + return value; + } + + void GetPinPropertyMulti(ULONG nPinId, REFGUID guidPropertySet, ULONG nProperty, PKSMULTIPLE_ITEM* ppKsMultipleItem) + { + HRESULT hr; + + KSP_PIN ksPProp; + ksPProp.Property.Set = guidPropertySet; + ksPProp.Property.Id = nProperty; + ksPProp.Property.Flags = KSPROPERTY_TYPE_GET; + ksPProp.PinId = nPinId; + ksPProp.Reserved = 0; + + ULONG cbMultipleItem = 0; + hr = ::DeviceIoControl(m_handle, + IOCTL_KS_PROPERTY, + &ksPProp.Property, + sizeof(KSP_PIN), + NULL, + 0, + &cbMultipleItem, + NULL); + if (FAILED(hr)) + throw ComException("CKsFilter::GetPinPropertyMulti: cannot get property", hr); + + *ppKsMultipleItem = (PKSMULTIPLE_ITEM) new BYTE[cbMultipleItem]; + + ULONG ulReturned = 0; + hr = ::DeviceIoControl( + m_handle, + IOCTL_KS_PROPERTY, + &ksPProp, + sizeof(KSP_PIN), + (PVOID)*ppKsMultipleItem, + cbMultipleItem, + &ulReturned, + NULL); + if (FAILED(hr)) + throw ComException("CKsFilter::GetPinPropertyMulti: cannot get property", hr); + } + + std::string const& GetFriendlyName() const + { + return m_sFriendlyName; + } + +protected: + + std::vector m_Pins; // this list owns the pins. + + std::vector m_RenderPins; + std::vector m_CapturePins; + +private: + std::string const m_sFriendlyName; // friendly name eg "Virus TI Synth" + tstring const m_sName; // Filter path, eg "\\?\usb#vid_133e&pid_0815...\vtimidi02" +}; + +class CKsPin : public CKsObject +{ +public: + CKsPin(CKsFilter* pFilter, ULONG nId); + virtual ~CKsPin(); + + virtual void Instantiate(); + + void ClosePin(); + + void SetState(KSSTATE ksState); + + void WriteData(KSSTREAM_HEADER* pKSSTREAM_HEADER, OVERLAPPED* pOVERLAPPED); + void ReadData(KSSTREAM_HEADER* pKSSTREAM_HEADER, OVERLAPPED* pOVERLAPPED); + + KSPIN_DATAFLOW GetDataFlow() const + { + return m_DataFlow; + } + + bool IsSink() const + { + return m_Communication == KSPIN_COMMUNICATION_SINK + || m_Communication == KSPIN_COMMUNICATION_BOTH; + } + + +protected: + PKSPIN_CONNECT m_pKsPinConnect; // creation parameters of pin + CKsFilter* const m_pFilter; + + ULONG m_cInterfaces; + PKSIDENTIFIER m_pInterfaces; + PKSMULTIPLE_ITEM m_pmiInterfaces; + + ULONG m_cMediums; + PKSIDENTIFIER m_pMediums; + PKSMULTIPLE_ITEM m_pmiMediums; + + ULONG m_cDataRanges; + PKSDATARANGE m_pDataRanges; + PKSMULTIPLE_ITEM m_pmiDataRanges; + + KSPIN_DATAFLOW m_DataFlow; + KSPIN_COMMUNICATION m_Communication; +}; + +CKsFilter::CKsFilter(tstring const& sName, std::string const& sFriendlyName) : + CKsObject(INVALID_HANDLE_VALUE), + m_sFriendlyName(sFriendlyName), + m_sName(sName) +{ + if (sName.empty()) + throw std::runtime_error("CKsFilter::CKsFilter: name can't be empty"); +} + +CKsFilter::~CKsFilter() +{ + for (size_t i=0;i < m_Pins.size();++i) + delete m_Pins[i]; + + if (IsValid(m_handle)) + ::CloseHandle(m_handle); +} + +void CKsFilter::Instantiate() +{ + m_handle = CreateFile( + m_sName.c_str(), + GENERIC_READ | GENERIC_WRITE, + 0, + NULL, + OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, + NULL); + + if (!IsValid(m_handle)) + { + DWORD const dwError = GetLastError(); + throw ComException("CKsFilter::Instantiate: can't open driver", HRESULT_FROM_WIN32(dwError)); + } +} + +CKsPin::CKsPin(CKsFilter* pFilter, ULONG PinId) : + CKsObject(INVALID_HANDLE_VALUE), + m_pKsPinConnect(NULL), + m_pFilter(pFilter) +{ + m_Communication = m_pFilter->GetPinProperty(PinId, KSPROPERTY_PIN_COMMUNICATION); + m_DataFlow = m_pFilter->GetPinProperty(PinId, KSPROPERTY_PIN_DATAFLOW); + + // Interfaces + m_pFilter->GetPinPropertyMulti( + PinId, + KSPROPSETID_Pin, + KSPROPERTY_PIN_INTERFACES, + &m_pmiInterfaces); + + m_cInterfaces = m_pmiInterfaces->Count; + m_pInterfaces = (PKSPIN_INTERFACE)(m_pmiInterfaces + 1); + + // Mediums + m_pFilter->GetPinPropertyMulti( + PinId, + KSPROPSETID_Pin, + KSPROPERTY_PIN_MEDIUMS, + &m_pmiMediums); + + m_cMediums = m_pmiMediums->Count; + m_pMediums = (PKSPIN_MEDIUM)(m_pmiMediums + 1); + + // Data ranges + m_pFilter->GetPinPropertyMulti( + PinId, + KSPROPSETID_Pin, + KSPROPERTY_PIN_DATARANGES, + &m_pmiDataRanges); + + m_cDataRanges = m_pmiDataRanges->Count; + m_pDataRanges = (PKSDATARANGE)(m_pmiDataRanges + 1); +} + +CKsPin::~CKsPin() +{ + ClosePin(); + + delete[] (BYTE*)m_pKsPinConnect; + delete[] (BYTE*)m_pmiDataRanges; + delete[] (BYTE*)m_pmiInterfaces; + delete[] (BYTE*)m_pmiMediums; +} + +void CKsPin::ClosePin() +{ + if (IsValid(m_handle)) { + SetState(KSSTATE_STOP); + ::CloseHandle(m_handle); + } + m_handle = INVALID_HANDLE_VALUE; +} + +void CKsPin::SetState(KSSTATE ksState) +{ + SetProperty(KSPROPSETID_Connection, KSPROPERTY_CONNECTION_STATE, &ksState, sizeof(ksState)); +} + +void CKsPin::Instantiate() +{ + if (!m_pKsPinConnect) + throw std::runtime_error("CKsPin::Instanciate: abstract pin"); + + DWORD const dwResult = KsCreatePin(m_pFilter->m_handle, m_pKsPinConnect, GENERIC_WRITE | GENERIC_READ, &m_handle); + if (dwResult != ERROR_SUCCESS) + throw ComException("CKsMidiCapFilter::CreateRenderPin: Pin instanciation failed", HRESULT_FROM_WIN32(dwResult)); +} + +void CKsPin::WriteData(KSSTREAM_HEADER* pKSSTREAM_HEADER, OVERLAPPED* pOVERLAPPED) +{ + DWORD cbWritten; + BOOL fRes = ::DeviceIoControl( + m_handle, + IOCTL_KS_WRITE_STREAM, + NULL, + 0, + pKSSTREAM_HEADER, + pKSSTREAM_HEADER->Size, + &cbWritten, + pOVERLAPPED); + if (!fRes) { + DWORD const dwError = GetLastError(); + if (dwError != ERROR_IO_PENDING) + throw ComException("CKsPin::WriteData: DeviceIoControl failed", HRESULT_FROM_WIN32(dwError)); + } +} + +void CKsPin::ReadData(KSSTREAM_HEADER* pKSSTREAM_HEADER, OVERLAPPED* pOVERLAPPED) +{ + DWORD cbReturned; + BOOL fRes = ::DeviceIoControl( + m_handle, + IOCTL_KS_READ_STREAM, + NULL, + 0, + pKSSTREAM_HEADER, + pKSSTREAM_HEADER->Size, + &cbReturned, + pOVERLAPPED); + if (!fRes) { + DWORD const dwError = GetLastError(); + if (dwError != ERROR_IO_PENDING) + throw ComException("CKsPin::ReadData: DeviceIoControl failed", HRESULT_FROM_WIN32(dwError)); + } +} + +class CKsMidiFilter : public CKsFilter +{ +public: + void FindMidiPins(); + +protected: + CKsMidiFilter(tstring const& sPath, std::string const& sFriendlyName); +}; + +class CKsMidiPin : public CKsPin +{ +public: + CKsMidiPin(CKsFilter* pFilter, ULONG nId); +}; + +class CKsMidiRenFilter : public CKsMidiFilter +{ +public: + CKsMidiRenFilter(tstring const& sPath, std::string const& sFriendlyName); + CKsMidiPin* CreateRenderPin(); + + void Validate() + { + if (m_RenderPins.empty()) + throw std::runtime_error("Could not find a MIDI render pin"); + } +}; + +class CKsMidiCapFilter : public CKsMidiFilter +{ +public: + CKsMidiCapFilter(tstring const& sPath, std::string const& sFriendlyName); + CKsMidiPin* CreateCapturePin(); + + void Validate() + { + if (m_CapturePins.empty()) + throw std::runtime_error("Could not find a MIDI capture pin"); + } +}; + +CKsMidiFilter::CKsMidiFilter(tstring const& sPath, std::string const& sFriendlyName) : + CKsFilter(sPath, sFriendlyName) +{ +} + +void CKsMidiFilter::FindMidiPins() +{ + ULONG numPins = GetPinProperty(0, KSPROPERTY_PIN_CTYPES); + + for (ULONG iPin = 0; iPin < numPins; ++iPin) { + try { + KSPIN_COMMUNICATION com = GetPinProperty(iPin, KSPROPERTY_PIN_COMMUNICATION); + if (com != KSPIN_COMMUNICATION_SINK && com != KSPIN_COMMUNICATION_BOTH) + throw std::runtime_error("Unknown pin communication value"); + + m_Pins.push_back(new CKsMidiPin(this, iPin)); + } + catch (std::runtime_error const&) { + // pin instanciation has failed, continue to the next pin. + } + } + + m_RenderPins.clear(); + m_CapturePins.clear(); + + for (size_t i = 0; i < m_Pins.size(); ++i) { + CKsPin* const pPin = m_Pins[i]; + + if (pPin->IsSink()) { + if (pPin->GetDataFlow() == KSPIN_DATAFLOW_IN) + m_RenderPins.push_back(pPin); + else + m_CapturePins.push_back(pPin); + } + } + + if (m_RenderPins.empty() && m_CapturePins.empty()) + throw std::runtime_error("No valid pins found on the filter."); +} + +CKsMidiRenFilter::CKsMidiRenFilter(tstring const& sPath, std::string const& sFriendlyName) : + CKsMidiFilter(sPath, sFriendlyName) +{ +} + +CKsMidiPin* CKsMidiRenFilter::CreateRenderPin() +{ + if (m_RenderPins.empty()) + throw std::runtime_error("Could not find a MIDI render pin"); + + CKsMidiPin* pPin = (CKsMidiPin*)m_RenderPins[0]; + pPin->Instantiate(); + return pPin; +} + +CKsMidiCapFilter::CKsMidiCapFilter(tstring const& sPath, std::string const& sFriendlyName) : + CKsMidiFilter(sPath, sFriendlyName) +{ +} + +CKsMidiPin* CKsMidiCapFilter::CreateCapturePin() +{ + if (m_CapturePins.empty()) + throw std::runtime_error("Could not find a MIDI capture pin"); + + CKsMidiPin* pPin = (CKsMidiPin*)m_CapturePins[0]; + pPin->Instantiate(); + return pPin; +} + +CKsMidiPin::CKsMidiPin(CKsFilter* pFilter, ULONG nId) : + CKsPin(pFilter, nId) +{ + DWORD const cbPinCreateSize = sizeof(KSPIN_CONNECT) + sizeof(KSDATAFORMAT); + m_pKsPinConnect = (PKSPIN_CONNECT) new BYTE[cbPinCreateSize]; + + m_pKsPinConnect->Interface.Set = KSINTERFACESETID_Standard; + m_pKsPinConnect->Interface.Id = KSINTERFACE_STANDARD_STREAMING; + m_pKsPinConnect->Interface.Flags = 0; + m_pKsPinConnect->Medium.Set = KSMEDIUMSETID_Standard; + m_pKsPinConnect->Medium.Id = KSMEDIUM_TYPE_ANYINSTANCE; + m_pKsPinConnect->Medium.Flags = 0; + m_pKsPinConnect->PinId = nId; + m_pKsPinConnect->PinToHandle = NULL; + m_pKsPinConnect->Priority.PriorityClass = KSPRIORITY_NORMAL; + m_pKsPinConnect->Priority.PrioritySubClass = 1; + + // point m_pDataFormat to just after the pConnect struct + KSDATAFORMAT* m_pDataFormat = (KSDATAFORMAT*)(m_pKsPinConnect + 1); + m_pDataFormat->FormatSize = sizeof(KSDATAFORMAT); + m_pDataFormat->Flags = 0; + m_pDataFormat->SampleSize = 0; + m_pDataFormat->Reserved = 0; + m_pDataFormat->MajorFormat = GUID(KSDATAFORMAT_TYPE_MUSIC); + m_pDataFormat->SubFormat = GUID(KSDATAFORMAT_SUBTYPE_MIDI); + m_pDataFormat->Specifier = GUID(KSDATAFORMAT_SPECIFIER_NONE); + + bool hasStdStreamingInterface = false; + bool hasStdStreamingMedium = false; + + for ( ULONG i = 0; i < m_cInterfaces; i++ ) { + if (m_pInterfaces[i].Set == KSINTERFACESETID_Standard + && m_pInterfaces[i].Id == KSINTERFACE_STANDARD_STREAMING) + hasStdStreamingInterface = true; + } + + for (ULONG i = 0; i < m_cMediums; i++) { + if (m_pMediums[i].Set == KSMEDIUMSETID_Standard + && m_pMediums[i].Id == KSMEDIUM_STANDARD_DEVIO) + hasStdStreamingMedium = true; + } + + if (!hasStdStreamingInterface) // No standard streaming interfaces on the pin + throw std::runtime_error("CKsMidiPin::CKsMidiPin: no standard streaming interface"); + + if (!hasStdStreamingMedium) // No standard streaming mediums on the pin + throw std::runtime_error("CKsMidiPin::CKsMidiPin: no standard streaming medium"); + + bool hasMidiDataRange = false; + + BYTE const* pDataRangePtr = reinterpret_cast(m_pDataRanges); + + for (ULONG i = 0; i < m_cDataRanges; ++i) { + KSDATARANGE const* pDataRange = reinterpret_cast(pDataRangePtr); + + if (pDataRange->SubFormat == KSDATAFORMAT_SUBTYPE_MIDI) { + hasMidiDataRange = true; + break; + } + + pDataRangePtr += pDataRange->FormatSize; + } + + if (!hasMidiDataRange) // No MIDI dataranges on the pin + throw std::runtime_error("CKsMidiPin::CKsMidiPin: no MIDI datarange"); +} + + +struct WindowsKsData +{ + WindowsKsData() : m_pPin(NULL), m_Buffer(1024), m_hInputThread(NULL) + { + memset(&overlapped, 0, sizeof(OVERLAPPED)); + m_hExitEvent = ::CreateEvent(NULL, FALSE, FALSE, NULL); + overlapped.hEvent = ::CreateEvent(NULL, FALSE, FALSE, NULL); + m_hInputThread = NULL; + } + + ~WindowsKsData() + { + ::CloseHandle(overlapped.hEvent); + ::CloseHandle(m_hExitEvent); + } + + OVERLAPPED overlapped; + CKsPin* m_pPin; + std::vector m_Buffer; + std::auto_ptr > m_pCaptureEnum; + std::auto_ptr > m_pRenderEnum; + HANDLE m_hInputThread; + HANDLE m_hExitEvent; +}; + +// *********************************************************************// +// API: WINDOWS Kernel Streaming +// Class Definitions: MidiInWinKS +// *********************************************************************// + +static DWORD WINAPI midiKsInputThread(VOID* pUser) +{ + MidiInApi::RtMidiInData* data = static_cast(pUser); + WindowsKsData* apiData = static_cast(data->apiData); + + HANDLE hEvents[] = { apiData->overlapped.hEvent, apiData->m_hExitEvent }; + + while ( true ) { + KSSTREAM_HEADER packet; + memset(&packet, 0, sizeof packet); + packet.Size = sizeof(KSSTREAM_HEADER); + packet.PresentationTime.Time = 0; + packet.PresentationTime.Numerator = 1; + packet.PresentationTime.Denominator = 1; + packet.Data = &apiData->m_Buffer[0]; + packet.DataUsed = 0; + packet.FrameExtent = apiData->m_Buffer.size(); + apiData->m_pPin->ReadData(&packet, &apiData->overlapped); + + DWORD dwRet = ::WaitForMultipleObjects(2, hEvents, FALSE, INFINITE); + + if ( dwRet == WAIT_OBJECT_0 ) { + // parse packet + unsigned char* pData = (unsigned char*)packet.Data; + unsigned int iOffset = 0; + + while ( iOffset < packet.DataUsed ) { + KSMUSICFORMAT* pMusic = (KSMUSICFORMAT*)&pData[iOffset]; + iOffset += sizeof(KSMUSICFORMAT); + + MidiInApi::MidiMessage message; + message.timeStamp = 0; + for(size_t i=0;i < pMusic->ByteCount;++i) + message.bytes.push_back(pData[iOffset+i]); + + if ( data->usingCallback ) { + RtMidiIn::RtMidiCallback callback = (RtMidiIn::RtMidiCallback)data->userCallback; + callback(message.timeStamp, &message.bytes, data->userData); + } + else { + // As long as we haven't reached our queue size limit, push the message. + if ( data->queue.size < data->queue.ringSize ) { + data->queue.ring[data->queue.back++] = message; + if(data->queue.back == data->queue.ringSize) + data->queue.back = 0; + data->queue.size++; + } + else + std::cerr << "\nRtMidiIn: message queue limit reached!!\n\n"; + } + + iOffset += pMusic->ByteCount; + + // re-align on 32 bits + if ( iOffset % 4 != 0 ) + iOffset += (4 - iOffset % 4); + } + } + else + break; + } + return 0; +} + +MidiInWinKS :: MidiInWinKS( const std::string clientName, unsigned int queueSizeLimit ) : MidiInApi( queueSizeLimit ) +{ + initialize( clientName ); +} + +void MidiInWinKS :: initialize( const std::string& clientName ) +{ + WindowsKsData* data = new WindowsKsData; + apiData_ = (void*)data; + inputData_.apiData = data; + + GUID const aguidEnumCats[] = + { + { STATIC_KSCATEGORY_AUDIO }, { STATIC_KSCATEGORY_CAPTURE } + }; + data->m_pCaptureEnum.reset(new CKsEnumFilters ); + data->m_pCaptureEnum->EnumFilters(aguidEnumCats, 2); +} + +MidiInWinKS :: ~MidiInWinKS() +{ + WindowsKsData* data = static_cast(apiData_); + try { + if ( data->m_pPin ) + closePort(); + } + catch(...) { + } + + delete data; +} + +void MidiInWinKS :: openPort( unsigned int portNumber, const std::string portName ) +{ + WindowsKsData* data = static_cast(apiData_); + + if ( portNumber < 0 || portNumber >= data->m_pCaptureEnum->m_Filters.size() ) { + std::stringstream ost; + ost << "MidiInWinKS::openPort: the 'portNumber' argument (" << portNumber << ") is invalid."; + errorString_ = ost.str(); + error( RtMidiError::WARNING, errorString_ ); + return; + } + + CKsMidiCapFilter* pFilter = data->m_pCaptureEnum->m_Filters[portNumber]; + data->m_pPin = pFilter->CreateCapturePin(); + + if ( data->m_pPin == NULL ) { + std::stringstream ost; + ost << "MidiInWinKS::openPort: KS error opening port (could not create pin)"; + errorString_ = ost.str(); + error( RtMidiError::WARNING, errorString_ ); + return; + } + + data->m_pPin->SetState(KSSTATE_RUN); + + DWORD threadId; + data->m_hInputThread = ::CreateThread(NULL, 0, &midiKsInputThread, &inputData_, 0, &threadId); + if ( data->m_hInputThread == NULL ) { + std::stringstream ost; + ost << "MidiInWinKS::openPort: Could not create input thread : Windows error " << GetLastError() << std::endl;; + errorString_ = ost.str(); + error( RtMidiError::WARNING, errorString_ ); + return; + } + + connected_ = true; +} + +void MidiInWinKS :: openVirtualPort( const std::string portName ) +{ + // This function cannot be implemented for the Windows KS MIDI API. + errorString_ = "MidiInWinKS::openVirtualPort: cannot be implemented in Windows KS MIDI API!"; + error( RtMidiError::WARNING, errorString_ ); +} + +unsigned int MidiInWinKS :: getPortCount() +{ + WindowsKsData* data = static_cast(apiData_); + return (unsigned int)data->m_pCaptureEnum->m_Filters.size(); +} + +std::string MidiInWinKS :: getPortName(unsigned int portNumber) +{ + WindowsKsData* data = static_cast(apiData_); + + if (portNumber < 0 || portNumber >= data->m_pCaptureEnum->m_Filters.size()) { + std::stringstream ost; + ost << "MidiInWinKS::getPortName: the 'portNumber' argument (" << portNumber << ") is invalid."; + errorString_ = ost.str(); + error( RtMidiError::WARNING, errorString_ ); + return; + } + + CKsMidiCapFilter* pFilter = data->m_pCaptureEnum->m_Filters[portNumber]; + return pFilter->GetFriendlyName(); +} + +void MidiInWinKS :: closePort() +{ + WindowsKsData* data = static_cast(apiData_); + connected_ = false; + + if (data->m_hInputThread) { + ::SignalObjectAndWait(data->m_hExitEvent, data->m_hInputThread, INFINITE, FALSE); + ::CloseHandle(data->m_hInputThread); + } + + if (data->m_pPin) { + data->m_pPin->SetState(KSSTATE_PAUSE); + data->m_pPin->SetState(KSSTATE_STOP); + data->m_pPin->ClosePin(); + data->m_pPin = NULL; + } +} + +// *********************************************************************// +// API: WINDOWS Kernel Streaming +// Class Definitions: MidiOutWinKS +// *********************************************************************// + +MidiOutWinKS :: MidiOutWinKS( const std::string clientName ) : MidiOutApi() +{ + initialize( clientName ); +} + +void MidiOutWinKS :: initialize( const std::string& clientName ) +{ + WindowsKsData* data = new WindowsKsData; + + data->m_pPin = NULL; + data->m_pRenderEnum.reset(new CKsEnumFilters ); + GUID const aguidEnumCats[] = + { + { STATIC_KSCATEGORY_AUDIO }, { STATIC_KSCATEGORY_RENDER } + }; + data->m_pRenderEnum->EnumFilters(aguidEnumCats, 2); + + apiData_ = (void*)data; +} + +MidiOutWinKS :: ~MidiOutWinKS() +{ + // Close a connection if it exists. + closePort(); + + // Cleanup. + WindowsKsData* data = static_cast(apiData_); + delete data; +} + +void MidiOutWinKS :: openPort( unsigned int portNumber, const std::string portName ) +{ + WindowsKsData* data = static_cast(apiData_); + + if (portNumber < 0 || portNumber >= data->m_pRenderEnum->m_Filters.size()) { + std::stringstream ost; + ost << "MidiOutWinKS::openPort: the 'portNumber' argument (" << portNumber << ") is invalid."; + errorString_ = ost.str(); + error( RtMidiError::WARNING, errorString_ ); + return; + } + + CKsMidiRenFilter* pFilter = data->m_pRenderEnum->m_Filters[portNumber]; + data->m_pPin = pFilter->CreateRenderPin(); + + if (data->m_pPin == NULL) { + std::stringstream ost; + ost << "MidiOutWinKS::openPort: KS error opening port (could not create pin)"; + errorString_ = ost.str(); + error( RtMidiError::WARNING, errorString_ ); + return; + } + + data->m_pPin->SetState(KSSTATE_RUN); + connected_ = true; +} + +void MidiOutWinKS :: openVirtualPort( const std::string portName ) +{ + // This function cannot be implemented for the Windows KS MIDI API. + errorString_ = "MidiOutWinKS::openVirtualPort: cannot be implemented in Windows KS MIDI API!"; + error( RtMidiError::WARNING, errorString_ ); +} + +unsigned int MidiOutWinKS :: getPortCount() +{ + WindowsKsData* data = static_cast(apiData_); + return (unsigned int)data->m_pRenderEnum->m_Filters.size(); +} + +std::string MidiOutWinKS :: getPortName( unsigned int portNumber ) +{ + WindowsKsData* data = static_cast(apiData_); + + if ( portNumber < 0 || portNumber >= data->m_pRenderEnum->m_Filters.size() ) { + std::stringstream ost; + ost << "MidiOutWinKS::getPortName: the 'portNumber' argument (" << portNumber << ") is invalid."; + errorString_ = ost.str(); + error( RtMidiError::WARNING, errorString_ ); + return; + } + + CKsMidiRenFilter* pFilter = data->m_pRenderEnum->m_Filters[portNumber]; + return pFilter->GetFriendlyName(); +} + +void MidiOutWinKS :: closePort() +{ + WindowsKsData* data = static_cast(apiData_); + connected_ = false; + + if ( data->m_pPin ) { + data->m_pPin->SetState(KSSTATE_PAUSE); + data->m_pPin->SetState(KSSTATE_STOP); + data->m_pPin->ClosePin(); + data->m_pPin = NULL; + } +} + +void MidiOutWinKS :: sendMessage(std::vector* pMessage) +{ + std::vector const& msg = *pMessage; + WindowsKsData* data = static_cast(apiData_); + size_t iNumMidiBytes = msg.size(); + size_t pos = 0; + + // write header + KSMUSICFORMAT* pKsMusicFormat = reinterpret_cast(&data->m_Buffer[pos]); + pKsMusicFormat->TimeDeltaMs = 0; + pKsMusicFormat->ByteCount = iNumMidiBytes; + pos += sizeof(KSMUSICFORMAT); + + // write MIDI bytes + if ( pos + iNumMidiBytes > data->m_Buffer.size() ) { + std::stringstream ost; + ost << "KsMidiInput::Write: MIDI buffer too small. Required " << pos + iNumMidiBytes << " bytes, only has " << data->m_Buffer.size(); + errorString_ = ost.str(); + error( RtMidiError::WARNING, errorString_ ); + return; + } + + if ( data->m_pPin == NULL ) { + std::stringstream ost; + ost << "MidiOutWinKS::sendMessage: port is not open"; + errorString_ = ost.str(); + error( RtMidiError::WARNING, errorString_ ); + return; + } + + memcpy(&data->m_Buffer[pos], &msg[0], iNumMidiBytes); + pos += iNumMidiBytes; + + KSSTREAM_HEADER packet; + memset(&packet, 0, sizeof packet); + packet.Size = sizeof(packet); + packet.PresentationTime.Time = 0; + packet.PresentationTime.Numerator = 1; + packet.PresentationTime.Denominator = 1; + packet.Data = const_cast(&data->m_Buffer[0]); + packet.DataUsed = ((pos+3)/4)*4; + packet.FrameExtent = data->m_Buffer.size(); + + data->m_pPin->WriteData(&packet, NULL); +} + +#endif // __WINDOWS_KS__ //*********************************************************************// // API: UNIX JACK diff --git a/RtMidi.h b/RtMidi.h index 9a878884..7fb3157c 100644 --- a/RtMidi.h +++ b/RtMidi.h @@ -124,6 +124,7 @@ class RtMidi LINUX_ALSA, /*!< The Advanced Linux Sound Architecture API. */ UNIX_JACK, /*!< The JACK Low-Latency MIDI Server API. */ WINDOWS_MM, /*!< The Microsoft Multimedia MIDI API. */ + WINDOWS_KS, /*!< The Microsoft Kernel Streaming MIDI API. */ RTMIDI_DUMMY /*!< A compilable but non-functional API. */ }; @@ -565,7 +566,7 @@ inline void RtMidiOut :: setErrorCallback( RtMidiErrorCallback errorCallback ) { // // **************************************************************** // -#if !defined(__LINUX_ALSA__) && !defined(__UNIX_JACK__) && !defined(__MACOSX_CORE__) && !defined(__WINDOWS_MM__) +#if !defined(__LINUX_ALSA__) && !defined(__UNIX_JACK__) && !defined(__MACOSX_CORE__) && !defined(__WINDOWS_MM__) && !defined(__WINDOWS_KS__) #define __RTMIDI_DUMMY__ #endif @@ -723,6 +724,43 @@ class MidiOutWinMM: public MidiOutApi #endif +#if defined(__WINDOWS_KS__) + +class MidiInWinKS: public MidiInApi +{ + public: + MidiInWinKS( const std::string clientName, unsigned int queueSizeLimit ); + ~MidiInWinKS( void ); + RtMidi::Api getCurrentApi( void ) { return RtMidi::WINDOWS_KS; }; + void openPort( unsigned int portNumber, const std::string portName ); + void openVirtualPort( const std::string portName ); + void closePort( void ); + unsigned int getPortCount( void ); + std::string getPortName( unsigned int portNumber ); + + protected: + void initialize( const std::string& clientName ); +}; + +class MidiOutWinKS: public MidiOutApi +{ + public: + MidiOutWinKS( const std::string clientName ); + ~MidiOutWinKS( void ); + RtMidi::Api getCurrentApi( void ) { return RtMidi::WINDOWS_KS; }; + void openPort( unsigned int portNumber, const std::string portName ); + void openVirtualPort( const std::string portName ); + void closePort( void ); + unsigned int getPortCount( void ); + std::string getPortName( unsigned int portNumber ); + void sendMessage( std::vector *message ); + + protected: + void initialize( const std::string& clientName ); +}; + +#endif + #if defined(__RTMIDI_DUMMY__) class MidiInDummy: public MidiInApi diff --git a/doc/doxygen/tutorial.txt b/doc/doxygen/tutorial.txt index aba7f3bd..d6dc8266 100644 --- a/doc/doxygen/tutorial.txt +++ b/doc/doxygen/tutorial.txt @@ -4,7 +4,7 @@ \section intro Introduction -RtMidi is a set of C++ classes (RtMidiIn, RtMidiOut and API-specific classes) that provides a common API (Application Programming Interface) for realtime MIDI input/output across Linux (ALSA & JACK), Macintosh OS X (CoreMIDI & JACK), and Windows (Multimedia Library) operating systems. RtMidi significantly simplifies the process of interacting with computer MIDI hardware and software. It was designed with the following goals: +RtMidi is a set of C++ classes (RtMidiIn, RtMidiOut and API-specific classes) that provides a common API (Application Programming Interface) for realtime MIDI input/output across Linux (ALSA & JACK), Macintosh OS X (CoreMIDI & JACK), and Windows (Multimedia Library & Kernel Streaming) operating systems. RtMidi significantly simplifies the process of interacting with computer MIDI hardware and software. It was designed with the following goals:

    • object oriented C++ design
    • @@ -19,7 +19,7 @@ MIDI input and output functionality are separated into two classes, RtMidiIn and \section whatsnew What's New (Version 2.1) -A minor API change was made. The RtError class was renamed RtMidiError and embedded directly in RtMidi.h. Thus, all references to RtError should be renamed to RtMidiError and the RtError.h file should be deleted. The Windows Kernel Streaming support was removed because it was uncompilable and incomplete. +A minor API change was made. The RtError class was renamed RtMidiError and embedded directly in RtMidi.h. Thus, all references to RtError should be renamed to RtMidiError and the RtError.h file should be deleted. \section download Download @@ -375,6 +375,13 @@ In order to compile RtMidi for a specific OS and API, it is necessary to supply winmm.lib, multithreaded compiler specific + + Windows + Kernel Streaming + __WINDOWS_KS__ + ks.h, ksmedia.h, setupapi.lib, ksuser.lib, multithreaded + compiler specific +

      @@ -386,7 +393,7 @@ If you are having problems getting RtMidi to run on your system, try passing the \section multi Using Simultaneous Multiple APIs -Support for each MIDI API is encapsulated in specific MidiInApi or MidiOutApi subclasses, making it possible to compile and instantiate multiple API-specific subclasses on a given operating system. For example, one can compile both CoreMIDI and JACK support on the OS-X operating system by providing the appropriate preprocessor definitions for each. In a run-time situation, one might first attempt to determine whether any JACK ports are available. This can be done by specifying the api argument RtMidi::UNIX_JACK when attempting to create an instance of RtMidiIn or RtMidiOut. If no available ports are found, then an instance of RtMidi with the api argument RtMidi::MACOSX_CORE can be created. Alternately, if no api argument is specified, RtMidi will first look for JACK ports and if none are found, then CoreMIDI ports (in linux, the search order is JACK and then ALSA. In theory, it should also be possible to have separate instances of RtMidi open at the same time with different underlying API support, though this has not been tested. +Support for each MIDI API is encapsulated in specific MidiInApi or MidiOutApi subclasses, making it possible to compile and instantiate multiple API-specific subclasses on a given operating system. For example, one can compile both CoreMIDI and JACK support on the OS-X operating system by providing the appropriate preprocessor definitions for each. In a run-time situation, one might first attempt to determine whether any JACK ports are available. This can be done by specifying the api argument RtMidi::UNIX_JACK when attempting to create an instance of RtMidiIn or RtMidiOut. If no available ports are found, then an instance of RtMidi with the api argument RtMidi::MACOSX_CORE can be created. Alternately, if no api argument is specified, RtMidi will first look for JACK ports and if none are found, then CoreMIDI ports (in linux, the search order is JACK and then ALSA; in Windows, the search order is WinMM and then WinKS). In theory, it should also be possible to have separate instances of RtMidi open at the same time with different underlying API support, though this has not been tested. The static function RtMidi::getCompiledApi() is provided to determine the available compiled API support. The function RtMidi::getCurrentApi() indicates the API selected for a given RtMidi instance. diff --git a/doc/release.txt b/doc/release.txt index d08f706e..83debcc9 100644 --- a/doc/release.txt +++ b/doc/release.txt @@ -16,7 +16,6 @@ v2.1.0: (30 March 2014) - Windows update to avoid lockups when shutting down while sending/receiving sysex messages (ptarabbia) - OS-X fix to avoid empty messages in callbacks when ignoring sysex messages and split sysexes are received (codepainters) - ALSA openPort fix to better distinguish sender and receiver (Russell Smyth) -- Windows Kernel Streaming support removed because it was uncompilable and incomplete v2.0.1: (26 July 2012) - small fixes for problems reported by Chris Arndt (scoping, preprocessor, and include) diff --git a/readme b/readme index 4d56ed58..69f095b0 100644 --- a/readme +++ b/readme @@ -1,4 +1,4 @@ -RtMidi - a set of C++ classes that provide a common API for realtime MIDI input/output across Linux (ALSA & JACK), Macintosh OS X (CoreMidi & JACK) and Windows (Multimedia). +RtMidi - a set of C++ classes that provide a common API for realtime MIDI input/output across Linux (ALSA & JACK), Macintosh OS X (CoreMidi & JACK) and Windows (Multimedia & Kernel Streaming). By Gary P. Scavone, 2003-2014. From c55bdf8ef95b80b432bdf334e4ffe60882f5f427 Mon Sep 17 00:00:00 2001 From: Tobias Schlemmer Date: Wed, 26 Mar 2014 20:30:35 +0100 Subject: [PATCH 11/45] Partially define an API for reliable port selection. --- RtMidi.h | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 53 insertions(+), 2 deletions(-) diff --git a/RtMidi.h b/RtMidi.h index 7fb3157c..42e80b7d 100644 --- a/RtMidi.h +++ b/RtMidi.h @@ -130,6 +130,27 @@ class RtMidi //! A static function to determine the current RtMidi version. static std::string getVersion( void ) throw(); + //! Define a port Id type. + typedef void * PortIdType; + + //! A port descriptor type. + struct PortDescriptor { + std::string Name; /*!< The Name of the port */ + std::string Path; /*!< API dependent path that allows to uniquely identify the port */ + PortIdType id; /*!< API dependent id of the port */ + void * api; /*!< API to be called when the port shall be opened */ + } + + //! Define a port Id type. + typedef void * PortIdType; + + //! A port descriptor type. + struct PortDescriptor { + std::string Name; /*!< The Name of the port */ + std::string Path; /*!< API dependent path that allows to uniquely identify the port */ + PortIdType id; /*!< API dependent id of the port */ + void * api; /*!< API to be called when the port shall be opened */ + } //! A static function to determine the available compiled MIDI APIs. /*! @@ -142,9 +163,18 @@ class RtMidi //! Pure virtual openPort() function. virtual void openPort( unsigned int portNumber = 0, const std::string portName = std::string( "RtMidi" ) ) = 0; + //! Pure virtual openPort() function. + virtual void openPort( const PortIdType portId, const std::string portName = std::string( "RtMidi" ) ) = 0; + + //! Pure virtual openPort() function. + virtual void openPort( const PortDescriptor & port, const std::string portName = std::string( "RtMidi" ) ) = 0; + //! Pure virtual openVirtualPort() function. virtual void openVirtualPort( const std::string portName = std::string( "RtMidi" ) ) = 0; + //! Pure virtual getPortList() function. + virtual std::list getPortList(); + //! Pure virtual getPortCount() function. virtual unsigned int getPortCount() = 0; @@ -247,6 +277,20 @@ class RtMidiIn : public RtMidi */ void openPort( unsigned int portNumber = 0, const std::string portName = std::string( "RtMidi Input" ) ); + //! Open a MIDI input connection given as string representation of the API dependent port id. + /*! + \param portId An API dependent port id must be specified. + \param portName An optional name for the applicaction port that is used to connect to portId can be specified. + */ + virtual void openPort( const PortIdType portId, const std::string portName = std::string( "RtMidi" ) ) = 0; + + //! Open a MIDI input connection given by a port descriptor. + /*! + \param port A port descriptor of the port must be specified. + \param portName An optional name for the applicaction port that is used to connect to portId can be specified. + */ + virtual void openPort( const PortDescriptor & port, const std::string portName = std::string( "RtMidi" ) ) = 0; + //! Create a virtual input port, with optional name, to allow software connections (OS X, JACK and ALSA only). /*! This function creates a virtual MIDI input port to which other @@ -256,9 +300,16 @@ class RtMidiIn : public RtMidi \param portName An optional name for the application port that is used to connect to portId can be specified. + */ void openVirtualPort( const std::string portName = std::string( "RtMidi Input" ) ); + //! Return a list of all available ports of the current API. + /*! + \return This function returns a list of port descriptors. + */ + virtual std::list getPortList(); + //! Set a callback function to be invoked for incoming MIDI messages. /*! The callback function will be called whenever an incoming MIDI @@ -476,8 +527,8 @@ class MidiInApi : public MidiApi // A MIDI structure used internally by the class to store incoming // messages. Each message represents one and only one MIDI message. - struct MidiMessage { - std::vector bytes; + struct MidiMessage { + std::vector bytes; double timeStamp; // Default constructor. From 4b69660998548d3b3c445fab76411a3ba81fb453 Mon Sep 17 00:00:00 2001 From: Tobias Schlemmer Date: Thu, 27 Mar 2014 08:47:44 +0100 Subject: [PATCH 12/45] Mark RtMidi.h to be C++. This helps certain editors to select the correct mode that usually interpet .h files as C headers. --- RtMidi.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RtMidi.h b/RtMidi.h index 42e80b7d..ce7431ac 100644 --- a/RtMidi.h +++ b/RtMidi.h @@ -1,4 +1,4 @@ -/**********************************************************************/ +/********************* -*- C++ -*- ****************************************/ /*! \class RtMidi \brief An abstract base class for realtime MIDI input/output. From 060c2620f0cd4da8c009c773c7d49b9f79581e0e Mon Sep 17 00:00:00 2001 From: Tobias Schlemmer Date: Thu, 27 Mar 2014 19:35:28 +0100 Subject: [PATCH 13/45] Merge port Id type into PortDescriptor and go further with cascading the API. --- RtMidi.h | 145 +++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 120 insertions(+), 25 deletions(-) diff --git a/RtMidi.h b/RtMidi.h index ce7431ac..0f9ee3e0 100644 --- a/RtMidi.h +++ b/RtMidi.h @@ -112,6 +112,8 @@ class RtMidiError : public std::exception typedef void (*RtMidiErrorCallback)( RtMidiError::Type type, const std::string &errorText ); class MidiApi; +class RtMidiIn; +class RtMidiOut; class RtMidi { @@ -130,16 +132,91 @@ class RtMidi //! A static function to determine the current RtMidi version. static std::string getVersion( void ) throw(); - //! Define a port Id type. - typedef void * PortIdType; //! A port descriptor type. + /*! This will be used with scoped pointers to store system dependent + * data for identifying the port. + */ struct PortDescriptor { - std::string Name; /*!< The Name of the port */ - std::string Path; /*!< API dependent path that allows to uniquely identify the port */ - PortIdType id; /*!< API dependent id of the port */ - void * api; /*!< API to be called when the port shall be opened */ - } + //! Flags for formatting a string description of the port. + /*! These flags just mark the requirements that the string + should fulfil. An API may return the same string for + different requirements e.g. the same short and long + name. */ + enum NamingType { + SHORT_NAME =0, /*!< A short human readable name + depending on the API + e.g. “Ensoniq AudioPCI” */ + LONG_NAME, /*!< A complete human readable + name depending on the API + e.g. "Ensoniq AudioPCI: ES1371" */ + SESSION_PATH, /*!< A unique description that can + be used to identify the port + during runtime. It may be a + cryptic string. */ + STORAGE_PATH, /*!< A unique description that is + optimised for storage in + configuration files. This is a + more textual representation that + is more robust to small changes in + the surrounding environment than + \ref SESSION_PATH */ + UNIQUE_NAME = 0x10, /*!< Make all names uniqe. This + is usually done by adding + numbers to the end of the + string */ + INCLUDE_API = 0x20 /*!< Add a string describing the + API at the beginning of the + string. */ + }; + + //! Flags describing the capabilities of a given port. + enum PortCapabilities { + INPUT = 1, /*!< Ports that can be read from. */ + OUTPUT = 2, /*!< Ports that can be written to. */ + INOUTPUT = 3 /*!< Ports that allow reading and writing (INPUT | OUTPUT) */ + }; + + //! Default constructor. + /*! + * Derived classes should have a constructor. + */ + PortIdType() {}; + + //! Get the MIDI api for the current port. + /*! This is the only information RtMidi needs to know: Which + * API should handle this object. + * + * \return API that can handle this object. + */ + virtual MidiApi * getAPI() = 0; + + //! A virtual destructor + /*! As we might have to destruct the object from the application code + * each port id must have a virtual destructor. + */ + virtual ~PortIdType() = 0; + + //! Return the port name + /*! + * \param flags A description of the requirements of the returned name. + * \return A name that is formatted according to \ref flags. + * \sa NamingTypes + */ + virtual std::string getName(int flags = SHORT_NAME | UNIQUE_NAME) = 0; + + //! Get capabilities + /*! \return a capabilities flag describing the capabilities of the port. + * \sa PortCapabilities + */ + virtual int getCapabilities(); + }; + + //! A list of port descriptors. + /*! Port descriptors are stored as shared pointers. This avoids + unnecessary duplication of the data structure and handles automatic + deletion if all references have been removed. */ + typedef std::list > PortList; //! Define a port Id type. typedef void * PortIdType; @@ -163,9 +240,6 @@ class RtMidi //! Pure virtual openPort() function. virtual void openPort( unsigned int portNumber = 0, const std::string portName = std::string( "RtMidi" ) ) = 0; - //! Pure virtual openPort() function. - virtual void openPort( const PortIdType portId, const std::string portName = std::string( "RtMidi" ) ) = 0; - //! Pure virtual openPort() function. virtual void openPort( const PortDescriptor & port, const std::string portName = std::string( "RtMidi" ) ) = 0; @@ -173,7 +247,7 @@ class RtMidi virtual void openVirtualPort( const std::string portName = std::string( "RtMidi" ) ) = 0; //! Pure virtual getPortList() function. - virtual std::list getPortList(); + virtual std::list getPortList(int capabilities = PortDescriptor:: INOUTPUT) = 0; //! Pure virtual getPortCount() function. virtual unsigned int getPortCount() = 0; @@ -187,6 +261,9 @@ class RtMidi //! Returns true if a port is open and false if not. virtual bool isPortOpen( void ) const = 0; + //! Returns a port descirptor if the port is open + virtual std::scoped_ptr getDescriptor() = 0; + //! Set an error callback function to be invoked when an error has occured. /*! The callback function will be called whenever an error has occured. It is best @@ -277,13 +354,6 @@ class RtMidiIn : public RtMidi */ void openPort( unsigned int portNumber = 0, const std::string portName = std::string( "RtMidi Input" ) ); - //! Open a MIDI input connection given as string representation of the API dependent port id. - /*! - \param portId An API dependent port id must be specified. - \param portName An optional name for the applicaction port that is used to connect to portId can be specified. - */ - virtual void openPort( const PortIdType portId, const std::string portName = std::string( "RtMidi" ) ) = 0; - //! Open a MIDI input connection given by a port descriptor. /*! \param port A port descriptor of the port must be specified. @@ -306,9 +376,12 @@ class RtMidiIn : public RtMidi //! Return a list of all available ports of the current API. /*! + \param capabilities an opitonnal parameter that describes which + device types are returned. \return This function returns a list of port descriptors. + \note An API is not required to return all output ports from RtMidiIn. */ - virtual std::list getPortList(); + virtual std::list getPortList(int capabilities = PortDescriptor:: INPUT); //! Set a callback function to be invoked for incoming MIDI messages. /*! @@ -336,6 +409,9 @@ class RtMidiIn : public RtMidi //! Returns true if a port is open and false if not. virtual bool isPortOpen() const; + //! Returns a port descirptor if the port is open + virtual std::scoped_ptr getDescriptor() = 0; + //! Return the number of available MIDI input ports. /*! \return This function returns the number of MIDI ports of the selected API. @@ -418,7 +494,7 @@ class RtMidiOut : public RtMidi //! Returns the MIDI API specifier for the current instance of RtMidiOut. RtMidi::Api getCurrentApi( void ) throw(); - //! Open a MIDI output connection. + //! Open a MIDI output connection given by an enumeration number. /*! An optional port number greater than 0 can be specified. Otherwise, the default or first port found is opened. An @@ -427,11 +503,12 @@ class RtMidiOut : public RtMidi */ void openPort( unsigned int portNumber = 0, const std::string portName = std::string( "RtMidi Output" ) ); - //! Close an open MIDI connection (if one exists). - void closePort( void ); - - //! Returns true if a port is open and false if not. - virtual bool isPortOpen() const; + //! Open a MIDI output connection given by a port descriptor. + /*! + \param port A port descriptor of the port must be specified. + \param portName An optional name for the applicaction port that is used to connect to portId can be specified. + */ + virtual void openPort( const PortDescriptor & port, const std::string portName = std::string( "RtMidi Output" ) ) = 0; //! Create a virtual output port, with optional name, to allow software connections (OS X, JACK and ALSA only). /*! @@ -444,6 +521,24 @@ class RtMidiOut : public RtMidi */ void openVirtualPort( const std::string portName = std::string( "RtMidi Output" ) ); + //! Close an open MIDI connection (if one exists). + void closePort( void ); + + //! Returns true if a port is open and false if not. + virtual bool isPortOpen() const; + + //! Returns a port descirptor if the port is open + virtual std::scoped_ptr getDescriptor() = 0; + + //! Return a list of all available ports of the current API. + /*! + \param capabilities an opitonnal parameter that describes which + device types are returned. + \return This function returns a list of port descriptors. + \note An API is not required to return all input ports from RtMidiOut. + */ + virtual std::list getPortList(int capabilities = PortDescriptor::OUTPUT); + //! Return the number of available MIDI output ports. unsigned int getPortCount( void ); From 772ce7c2f736266ca86ece65ae48ab6313c932f1 Mon Sep 17 00:00:00 2001 From: Tobias Schlemmer Date: Fri, 28 Mar 2014 09:16:42 +0100 Subject: [PATCH 14/45] Complete the API part of the new PortDescriptor based API This includes also some reorganisation that moves the common global/local API out of RtMIDI and the backend api. --- RtMidi.h | 535 +++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 346 insertions(+), 189 deletions(-) diff --git a/RtMidi.h b/RtMidi.h index 0f9ee3e0..b1ab82f0 100644 --- a/RtMidi.h +++ b/RtMidi.h @@ -49,6 +49,8 @@ #include #include #include +#include +#include /************************************************************************/ /*! \class RtMidiError @@ -80,7 +82,7 @@ class RtMidiError : public std::exception //! The constructor. RtMidiError( const std::string& message, Type type = RtMidiError::UNSPECIFIED ) throw() : message_(message), type_(type) {} - + //! The destructor. virtual ~RtMidiError( void ) throw() {} @@ -111,11 +113,241 @@ class RtMidiError : public std::exception */ typedef void (*RtMidiErrorCallback)( RtMidiError::Type type, const std::string &errorText ); -class MidiApi; -class RtMidiIn; -class RtMidiOut; +class MidiApi { + //! A port descriptor type. + /*! This will be used with scoped pointers to store system dependent + * data for identifying the port. + */ + struct PortDescriptor { + //! Flags for formatting a string description of the port. + /*! These flags just mark the requirements that the string + should fulfil. An API may return the same string for + different requirements e.g. the same short and long + name. */ + enum NamingType { + SHORT_NAME =0, /*!< A short human readable name + depending on the API + e.g. “Ensoniq AudioPCI” */ + LONG_NAME, /*!< A complete human readable + name depending on the API + e.g. "Ensoniq AudioPCI: ES1371" */ + SESSION_PATH, /*!< A unique description that can + be used to identify the port + during runtime. It may be a + cryptic string. */ + STORAGE_PATH, /*!< A unique description that is + optimised for storage in + configuration files. This is a + more textual representation that + is more robust to small changes in + the surrounding environment than + \ref SESSION_PATH */ + UNIQUE_NAME = 0x10, /*!< Make all names uniqe. This + is usually done by adding + numbers to the end of the + string */ + INCLUDE_API = 0x20 /*!< Add a string describing the + API at the beginning of the + string. */ + }; + + //! Flags describing the capabilities of a given port. + enum PortCapabilities { + INPUT = 1, /*!< Ports that can be read from. */ + OUTPUT = 2, /*!< Ports that can be written to. */ + INOUTPUT = 3 /*!< Ports that allow reading and writing (INPUT | OUTPUT) */ + }; + + +#if __cplusplus < 201103L + class Pointer { + protected: + struct countPointer { + int count; + PortDescriptor * descriptor; + }; + public: + Pointer(PortDescriptor * p):ptr(new countPointer) { + ptr->count = 1; + ptr->descriptor = p; + } + Pointer(Pointer & other): + ptr(other.ptr) { + ptr->count++; + } + + ~Pointer() { + if (!ptr) return; + if (!ptr->descriptor) { + delete ptr; + return; + } + if (!(--ptr->count)) { + delete ptr->descriptor; + delete ptr; + } + } + + PortDescriptor * operator -> () { + if (!ptr) return 0; + // this should throw an exception + + return ptr->descriptor; + } + protected: + countPointer * ptr; + }; +#else + typedef shared_ptr Pointer; +#endif + + + //! Default constructor. + /*! + * Derived classes should have a constructor. + */ + PortDescriptor() {}; + + //! A virtual destructor + /*! As we might have to destruct the object from the application code + * each port id must have a virtual destructor. + */ + virtual ~PortDescriptor() = 0; + + //! Get the MIDI api for the current port. + /*! This is the only information RtMidi needs to know: Which + * API should handle this object. + * + * \return API that can handle this object. + */ + virtual MidiApi * getAPI() = 0; + + //! Return the port name + /*! + * \param flags A description of the requirements of the returned name. + * \return A name that is formatted according to \ref flags. + * \sa NamingTypes + */ + virtual std::string getName(int flags = SHORT_NAME | UNIQUE_NAME) = 0; + + //! Get capabilities + /*! \return a capabilities flag describing the capabilities of the port. + * \sa PortCapabilities + */ + virtual int getCapabilities(); + }; + + //! A list of port descriptors. + /*! Port descriptors are stored as shared pointers. This avoids + unnecessary duplication of the data structure and handles automatic + deletion if all references have been removed. */ + typedef std::list PortList; + + //! Pure virtal function to create a virtual port, with optional name. + /*! + This function creates a virtual MIDI port to which other + software applications can connect. This type of functionality + is currently only supported by the Macintosh OS-X, any JACK, + and Linux ALSA APIs (the function returns an error for the other APIs). + + \param portName An optional name for the applicaction port that is + used to connect to portId can be specified. + */ + virtual void openVirtualPort( const std::string portName = std::string( "RtMidi" ) ) = 0; + + //! Pure virtual function to open a MIDI connection given by enumeration number. + /*! \param portNumber An optional port number greater than 0 + can be specified. Otherwise, the default or first port + found is opened. + + \param portName An optional name for the applicaction port + that will be generated to connect to portId can be + specified. + */ + virtual void openPort( unsigned int portNumber = 0, const std::string portName = std::string( "RtMidi" ) ) = 0; + + //! Pure virtual function to open a MIDI connection given by a port descriptor. + /*! + \param port A port descriptor of the port must be specified. + \param portName An optional name for the applicaction port that is used to connect to portId can be specified. + */ + virtual void openPort( const PortDescriptor & port, const std::string portName = std::string( "RtMidi" ) ) = 0; + + //! Pure virtual function to return a port descirptor if the port is open + virtual PortDescriptor::Pointer getDescriptor() = 0; + + //! Pure virtual function to return a list of all available ports of the current API. + /*! + \param capabilities an optional parameter that describes which + device types are returned. + + \return This function returns a list of port descriptors. + + \note An input API may but need not necessarily report + output devices which cannot be used as input if + \ref PortDescriptor::OUTPUT is passed as \ref capabilities parameter. + */ + virtual MidiApi::PortList getPortList(int capabilities = PortDescriptor:: INOUTPUT) = 0; + + //! Pure virtual to return the number of available MIDI ports of the current API. + /*! + \return This function returns the number of MIDI ports of + the selected API. + + \note Only ports are counted that can be used with the + current API so an input API does ignore all output devices + and vice versa. + + \sa getPortName + */ + virtual unsigned int getPortCount() = 0; + + //! Pure virtual function to return a string identifier for the specified MIDI port number. + /*! + \param portNumber Number of the device to be referred to. + \return The name of the port with the given Id is returned. + \retval An empty string is returned if an invalid port specifier is provided. + + \note Only ports are counted that can be used with the + current API so an input API does ignore all output devices + and vice versa. + + \sa getPortCount() + */ + std::string getPortName( unsigned int portNumber = 0 ); + + //! Pure virtual function to close an open MIDI connection (if one exists). + virtual void closePort( void ) = 0; + + // ! A basic error reporting function for RtMidi classes. + // static void error( RtMidiError::Type type, std::string &errorString ); + + //! Pure virtual function to return whether a port is open or not. + /*! \retval true if a port is open and + \retval false if the port is not open (e.g. not opend or closed). + */ + virtual bool isPortOpen( void ) const = 0; + + //! Pure virtual function to set an error callback function to be invoked when an error has occured. + /*! + The callback function will be called whenever an error has occured. It is best + to set the error callback function before opening a port. + */ + virtual void setErrorCallback( RtMidiErrorCallback errorCallback = NULL ) = 0; +} + +/**********************************************************************/ +/*! \class RtMidi + \brief A global class that implements basic backend API handling. + + This class enhances \ref MidiApi by some functionality to handle + backend API objects. It serves as base class for the public RtMidi + API. -class RtMidi + by Gary P. Scavone, 2003-2014. +*/ +/**********************************************************************/ +class RtMidi : public MidiApi { public: @@ -133,102 +365,6 @@ class RtMidi //! A static function to determine the current RtMidi version. static std::string getVersion( void ) throw(); - //! A port descriptor type. - /*! This will be used with scoped pointers to store system dependent - * data for identifying the port. - */ - struct PortDescriptor { - //! Flags for formatting a string description of the port. - /*! These flags just mark the requirements that the string - should fulfil. An API may return the same string for - different requirements e.g. the same short and long - name. */ - enum NamingType { - SHORT_NAME =0, /*!< A short human readable name - depending on the API - e.g. “Ensoniq AudioPCI” */ - LONG_NAME, /*!< A complete human readable - name depending on the API - e.g. "Ensoniq AudioPCI: ES1371" */ - SESSION_PATH, /*!< A unique description that can - be used to identify the port - during runtime. It may be a - cryptic string. */ - STORAGE_PATH, /*!< A unique description that is - optimised for storage in - configuration files. This is a - more textual representation that - is more robust to small changes in - the surrounding environment than - \ref SESSION_PATH */ - UNIQUE_NAME = 0x10, /*!< Make all names uniqe. This - is usually done by adding - numbers to the end of the - string */ - INCLUDE_API = 0x20 /*!< Add a string describing the - API at the beginning of the - string. */ - }; - - //! Flags describing the capabilities of a given port. - enum PortCapabilities { - INPUT = 1, /*!< Ports that can be read from. */ - OUTPUT = 2, /*!< Ports that can be written to. */ - INOUTPUT = 3 /*!< Ports that allow reading and writing (INPUT | OUTPUT) */ - }; - - //! Default constructor. - /*! - * Derived classes should have a constructor. - */ - PortIdType() {}; - - //! Get the MIDI api for the current port. - /*! This is the only information RtMidi needs to know: Which - * API should handle this object. - * - * \return API that can handle this object. - */ - virtual MidiApi * getAPI() = 0; - - //! A virtual destructor - /*! As we might have to destruct the object from the application code - * each port id must have a virtual destructor. - */ - virtual ~PortIdType() = 0; - - //! Return the port name - /*! - * \param flags A description of the requirements of the returned name. - * \return A name that is formatted according to \ref flags. - * \sa NamingTypes - */ - virtual std::string getName(int flags = SHORT_NAME | UNIQUE_NAME) = 0; - - //! Get capabilities - /*! \return a capabilities flag describing the capabilities of the port. - * \sa PortCapabilities - */ - virtual int getCapabilities(); - }; - - //! A list of port descriptors. - /*! Port descriptors are stored as shared pointers. This avoids - unnecessary duplication of the data structure and handles automatic - deletion if all references have been removed. */ - typedef std::list > PortList; - - //! Define a port Id type. - typedef void * PortIdType; - - //! A port descriptor type. - struct PortDescriptor { - std::string Name; /*!< The Name of the port */ - std::string Path; /*!< API dependent path that allows to uniquely identify the port */ - PortIdType id; /*!< API dependent id of the port */ - void * api; /*!< API to be called when the port shall be opened */ - } - //! A static function to determine the available compiled MIDI APIs. /*! The values returned in the std::vector can be compared against @@ -237,40 +373,6 @@ class RtMidi */ static void getCompiledApi( std::vector &apis ) throw(); - //! Pure virtual openPort() function. - virtual void openPort( unsigned int portNumber = 0, const std::string portName = std::string( "RtMidi" ) ) = 0; - - //! Pure virtual openPort() function. - virtual void openPort( const PortDescriptor & port, const std::string portName = std::string( "RtMidi" ) ) = 0; - - //! Pure virtual openVirtualPort() function. - virtual void openVirtualPort( const std::string portName = std::string( "RtMidi" ) ) = 0; - - //! Pure virtual getPortList() function. - virtual std::list getPortList(int capabilities = PortDescriptor:: INOUTPUT) = 0; - - //! Pure virtual getPortCount() function. - virtual unsigned int getPortCount() = 0; - - //! Pure virtual getPortName() function. - virtual std::string getPortName( unsigned int portNumber = 0 ) = 0; - - //! Pure virtual closePort() function. - virtual void closePort( void ) = 0; - - //! Returns true if a port is open and false if not. - virtual bool isPortOpen( void ) const = 0; - - //! Returns a port descirptor if the port is open - virtual std::scoped_ptr getDescriptor() = 0; - - //! Set an error callback function to be invoked when an error has occured. - /*! - The callback function will be called whenever an error has occured. It is best - to set the error callback function before opening a port. - */ - virtual void setErrorCallback( RtMidiErrorCallback errorCallback = NULL ) = 0; - protected: RtMidi(); @@ -346,6 +448,18 @@ class RtMidiIn : public RtMidi //! Returns the MIDI API specifier for the current instance of RtMidiIn. RtMidi::Api getCurrentApi( void ) throw(); + //! Create a virtual input port, with optional name, to allow software connections (OS X, JACK and ALSA only). + /*! + This function creates a virtual MIDI input port to which other + software applications can connect. This type of functionality + is currently only supported by the Macintosh OS-X, any JACK, + and Linux ALSA APIs (the function returns an error for the other APIs). + + \param portName An optional name for the applicaction port that is + used to connect to portId can be specified. + */ + void openVirtualPort( const std::string portName = std::string( "RtMidi Input" ) ); + //! Open a MIDI input connection given by enumeration number. /*! \param portNumber An optional port number greater than 0 can be specified. @@ -359,8 +473,9 @@ class RtMidiIn : public RtMidi \param port A port descriptor of the port must be specified. \param portName An optional name for the applicaction port that is used to connect to portId can be specified. */ - virtual void openPort( const PortDescriptor & port, const std::string portName = std::string( "RtMidi" ) ) = 0; + void openPort( const PortDescriptor & port, const std::string portName = std::string( "RtMidi" ) ) = 0; +<<<<<<< HEAD //! Create a virtual input port, with optional name, to allow software connections (OS X, JACK and ALSA only). /*! This function creates a virtual MIDI input port to which other @@ -371,17 +486,38 @@ class RtMidiIn : public RtMidi \param portName An optional name for the application port that is used to connect to portId can be specified. - */ - void openVirtualPort( const std::string portName = std::string( "RtMidi Input" ) ); +======= + //! Returns a port descirptor if the port is open + virtual MidiApi::PortDescriptor::Pointer getDescriptor() = 0; - //! Return a list of all available ports of the current API. + //! Return a list of all available input ports of the current API. /*! - \param capabilities an opitonnal parameter that describes which + \param capabilities an optional parameter that describes which device types are returned. \return This function returns a list of port descriptors. - \note An API is not required to return all output ports from RtMidiIn. + \note An Output API is not required to return all output ports from RtMidiIn. + */ + virtual MidiApi::PortList getPortList(int capabilities = PortDescriptor:: INPUT); + + //! Return the number of available MIDI input ports. + /*! + \return This function returns the number of midi ports of the selected API. +>>>>>>> 70db5a0... Complete the API part of the new PortDescriptor based API */ - virtual std::list getPortList(int capabilities = PortDescriptor:: INPUT); + unsigned int getPortCount(); + + //! Return a string identifier for the specified MIDI input port number. + /*! + \return The name of the port with the given Id is returned. + \retval An empty string is returned if an invalid port specifier is provided. + */ + std::string getPortName( unsigned int portNumber = 0 ); + + //! Close an open MIDI connection (if one exists). + void closePort( void ); + + //! Returns true if a port is open and false if not. + virtual bool isPortOpen() const; //! Set a callback function to be invoked for incoming MIDI messages. /*! @@ -403,28 +539,6 @@ class RtMidiIn : public RtMidi */ void cancelCallback(); - //! Close an open MIDI connection (if one exists). - void closePort( void ); - - //! Returns true if a port is open and false if not. - virtual bool isPortOpen() const; - - //! Returns a port descirptor if the port is open - virtual std::scoped_ptr getDescriptor() = 0; - - //! Return the number of available MIDI input ports. - /*! - \return This function returns the number of MIDI ports of the selected API. - */ - unsigned int getPortCount(); - - //! Return a string identifier for the specified MIDI input port number. - /*! - \return The name of the port with the given Id is returned. - \retval An empty string is returned if an invalid port specifier is provided. - */ - std::string getPortName( unsigned int portNumber = 0 ); - //! Specify whether certain MIDI message types should be queued or ignored during input. /*! By default, MIDI timing and active sensing messages are ignored @@ -494,6 +608,17 @@ class RtMidiOut : public RtMidi //! Returns the MIDI API specifier for the current instance of RtMidiOut. RtMidi::Api getCurrentApi( void ) throw(); + //! Create a virtual output port, with optional name, to allow software connections (OS X and ALSA only). + /*! + This function creates a virtual MIDI output port to which other + software applications can connect. This type of functionality + is currently only supported by the Macintosh OS-X and Linux ALSA + APIs (the function does nothing with the other APIs). An + exception is thrown if an error occurs while attempting to create + the virtual port. + */ + void openVirtualPort( const std::string portName = std::string( "RtMidi Output" ) ); + //! Open a MIDI output connection given by an enumeration number. /*! An optional port number greater than 0 can be specified. @@ -510,16 +635,11 @@ class RtMidiOut : public RtMidi */ virtual void openPort( const PortDescriptor & port, const std::string portName = std::string( "RtMidi Output" ) ) = 0; - //! Create a virtual output port, with optional name, to allow software connections (OS X, JACK and ALSA only). - /*! - This function creates a virtual MIDI output port to which other - software applications can connect. This type of functionality - is currently only supported by the Macintosh OS-X, Linux ALSA - and JACK APIs (the function does nothing with the other APIs). - An exception is thrown if an error occurs while attempting to - create the virtual port. - */ - void openVirtualPort( const std::string portName = std::string( "RtMidi Output" ) ); + //! Returns a port descirptor if the port is open + /*! \return Port descriptor of the currently open port + * \retval 0 iff the port s not open + */ + virtual MidiApi::PortDescriptor::Pointer getDescriptor() = 0; //! Close an open MIDI connection (if one exists). void closePort( void ); @@ -527,9 +647,6 @@ class RtMidiOut : public RtMidi //! Returns true if a port is open and false if not. virtual bool isPortOpen() const; - //! Returns a port descirptor if the port is open - virtual std::scoped_ptr getDescriptor() = 0; - //! Return a list of all available ports of the current API. /*! \param capabilities an opitonnal parameter that describes which @@ -537,14 +654,15 @@ class RtMidiOut : public RtMidi \return This function returns a list of port descriptors. \note An API is not required to return all input ports from RtMidiOut. */ - virtual std::list getPortList(int capabilities = PortDescriptor::OUTPUT); + virtual MidiApi::PortList getPortList(int capabilities = PortDescriptor::OUTPUT); //! Return the number of available MIDI output ports. unsigned int getPortCount( void ); //! Return a string identifier for the specified MIDI port type and number. /*! - An empty string is returned if an invalid port specifier is provided. + \return The name of the port with the given Id is returned. + \retval An empty string is returned if an invalid port specifier is provided. */ std::string getPortName( unsigned int portNumber = 0 ); @@ -580,21 +698,17 @@ class RtMidiOut : public RtMidi // // **************************************************************** // -class MidiApi +class MidiBackendApi: public MidiApi { public: MidiApi(); virtual ~MidiApi(); - virtual RtMidi::Api getCurrentApi( void ) = 0; - virtual void openPort( unsigned int portNumber, const std::string portName ) = 0; - virtual void openVirtualPort( const std::string portName ) = 0; - virtual void closePort( void ) = 0; virtual unsigned int getPortCount( void ) = 0; virtual std::string getPortName( unsigned int portNumber ) = 0; - inline bool isPortOpen() const { return connected_; } + bool isPortOpen() const { return connected_; } void setErrorCallback( RtMidiErrorCallback errorCallback ); //! A basic error reporting function for RtMidi classes. @@ -609,7 +723,7 @@ class MidiApi RtMidiErrorCallback errorCallback_; }; -class MidiInApi : public MidiApi +class MidiInApi : public MidiBackendApi { public: @@ -668,7 +782,7 @@ class MidiInApi : public MidiApi RtMidiInData inputData_; }; -class MidiOutApi : public MidiApi +class MidiOutApi : public MidiBackendApi { public: @@ -726,6 +840,9 @@ class MidiInCore: public MidiInApi RtMidi::Api getCurrentApi( void ) { return RtMidi::MACOSX_CORE; }; void openPort( unsigned int portNumber, const std::string portName ); void openVirtualPort( const std::string portName ); + void openPort( const PortDescriptor & port, const std::string portName); + MidiApi::PortDescriptor::Pointer getDescriptor(); + MidiApi::PortList getPortList(int capabilities); void closePort( void ); unsigned int getPortCount( void ); std::string getPortName( unsigned int portNumber ); @@ -742,6 +859,9 @@ class MidiOutCore: public MidiOutApi RtMidi::Api getCurrentApi( void ) { return RtMidi::MACOSX_CORE; }; void openPort( unsigned int portNumber, const std::string portName ); void openVirtualPort( const std::string portName ); + void openPort( const PortDescriptor & port, const std::string portName); + MidiApi::PortDescriptor::Pointer getDescriptor(); + MidiApi::PortList getPortList(int capabilities); void closePort( void ); unsigned int getPortCount( void ); std::string getPortName( unsigned int portNumber ); @@ -763,6 +883,9 @@ class MidiInJack: public MidiInApi RtMidi::Api getCurrentApi( void ) { return RtMidi::UNIX_JACK; }; void openPort( unsigned int portNumber, const std::string portName ); void openVirtualPort( const std::string portName ); + void openPort( const PortDescriptor & port, const std::string portName); + MidiApi::PortDescriptor::Pointer getDescriptor(); + MidiApi::PortList getPortList(int capabilities); void closePort( void ); unsigned int getPortCount( void ); std::string getPortName( unsigned int portNumber ); @@ -782,6 +905,9 @@ class MidiOutJack: public MidiOutApi RtMidi::Api getCurrentApi( void ) { return RtMidi::UNIX_JACK; }; void openPort( unsigned int portNumber, const std::string portName ); void openVirtualPort( const std::string portName ); + void openPort( const PortDescriptor & port, const std::string portName); + MidiApi::PortDescriptor::Pointer getDescriptor(); + MidiApi::PortList getPortList(int capabilities); void closePort( void ); unsigned int getPortCount( void ); std::string getPortName( unsigned int portNumber ); @@ -806,6 +932,9 @@ class MidiInAlsa: public MidiInApi RtMidi::Api getCurrentApi( void ) { return RtMidi::LINUX_ALSA; }; void openPort( unsigned int portNumber, const std::string portName ); void openVirtualPort( const std::string portName ); + void openPort( const PortDescriptor & port, const std::string portName); + MidiApi::PortDescriptor::Pointer getDescriptor(); + MidiApi::PortList getPortList(int capabilities); void closePort( void ); unsigned int getPortCount( void ); std::string getPortName( unsigned int portNumber ); @@ -822,6 +951,9 @@ class MidiOutAlsa: public MidiOutApi RtMidi::Api getCurrentApi( void ) { return RtMidi::LINUX_ALSA; }; void openPort( unsigned int portNumber, const std::string portName ); void openVirtualPort( const std::string portName ); + void openPort( const PortDescriptor & port, const std::string portName); + MidiApi::PortDescriptor::Pointer getDescriptor(); + MidiApi::PortList getPortList(int capabilities); void closePort( void ); unsigned int getPortCount( void ); std::string getPortName( unsigned int portNumber ); @@ -843,6 +975,9 @@ class MidiInWinMM: public MidiInApi RtMidi::Api getCurrentApi( void ) { return RtMidi::WINDOWS_MM; }; void openPort( unsigned int portNumber, const std::string portName ); void openVirtualPort( const std::string portName ); + void openPort( const PortDescriptor & port, const std::string portName); + MidiApi::PortDescriptor::Pointer getDescriptor(); + MidiApi::PortList getPortList(int capabilities); void closePort( void ); unsigned int getPortCount( void ); std::string getPortName( unsigned int portNumber ); @@ -859,6 +994,9 @@ class MidiOutWinMM: public MidiOutApi RtMidi::Api getCurrentApi( void ) { return RtMidi::WINDOWS_MM; }; void openPort( unsigned int portNumber, const std::string portName ); void openVirtualPort( const std::string portName ); + void openPort( const PortDescriptor & port, const std::string portName); + MidiApi::PortDescriptor::Pointer getDescriptor(); + MidiApi::PortList getPortList(int capabilities); void closePort( void ); unsigned int getPortCount( void ); std::string getPortName( unsigned int portNumber ); @@ -880,6 +1018,9 @@ class MidiInWinKS: public MidiInApi RtMidi::Api getCurrentApi( void ) { return RtMidi::WINDOWS_KS; }; void openPort( unsigned int portNumber, const std::string portName ); void openVirtualPort( const std::string portName ); + void openPort( const PortDescriptor & port, const std::string portName); + MidiApi::PortDescriptor::Pointer getDescriptor(); + MidiApi::PortList getPortList(int capabilities); void closePort( void ); unsigned int getPortCount( void ); std::string getPortName( unsigned int portNumber ); @@ -896,6 +1037,9 @@ class MidiOutWinKS: public MidiOutApi RtMidi::Api getCurrentApi( void ) { return RtMidi::WINDOWS_KS; }; void openPort( unsigned int portNumber, const std::string portName ); void openVirtualPort( const std::string portName ); + void openPort( const PortDescriptor & port, const std::string portName); + MidiApi::PortDescriptor::Pointer getDescriptor(); + MidiApi::PortList getPortList(int capabilities); void closePort( void ); unsigned int getPortCount( void ); std::string getPortName( unsigned int portNumber ); @@ -912,10 +1056,17 @@ class MidiOutWinKS: public MidiOutApi class MidiInDummy: public MidiInApi { public: - MidiInDummy( const std::string /*clientName*/, unsigned int queueSizeLimit ) : MidiInApi( queueSizeLimit ) { errorString_ = "MidiInDummy: This class provides no functionality."; error( RtMidiError::WARNING, errorString_ ); } + MidiInDummy( const std::string /*clientName*/, unsigned int queueSizeLimit ) + : MidiInApi( queueSizeLimit ) { + errorString_ = "MidiInDummy: This class provides no functionality."; + error( RtMidiError::WARNING, errorString_ ); + } RtMidi::Api getCurrentApi( void ) { return RtMidi::RTMIDI_DUMMY; } void openPort( unsigned int /*portNumber*/, const std::string /*portName*/ ) {} void openVirtualPort( const std::string /*portName*/ ) {} + void openPort( const PortDescriptor & port, const std::string portName) {} + MidiApi::PortDescriptor::Pointer getDescriptor() { return 0; } + MidiApi::PortList getPortList(int capabilities) { return MidiApi::PortList(); } void closePort( void ) {} unsigned int getPortCount( void ) { return 0; } std::string getPortName( unsigned int portNumber ) { return ""; } @@ -927,10 +1078,16 @@ class MidiInDummy: public MidiInApi class MidiOutDummy: public MidiOutApi { public: - MidiOutDummy( const std::string /*clientName*/ ) { errorString_ = "MidiOutDummy: This class provides no functionality."; error( RtMidiError::WARNING, errorString_ ); } + MidiOutDummy( const std::string /*clientName*/ ) { + errorString_ = "MidiOutDummy: This class provides no functionality."; + error( RtMidiError::WARNING, errorString_ ); + } RtMidi::Api getCurrentApi( void ) { return RtMidi::RTMIDI_DUMMY; } void openPort( unsigned int /*portNumber*/, const std::string /*portName*/ ) {} void openVirtualPort( const std::string /*portName*/ ) {} + void openPort( const PortDescriptor & port, const std::string portName) {} + MidiApi::PortDescriptor::Pointer getDescriptor() { return 0; } + MidiApi::PortList getPortList(int capabilities) { return MidiApi::PortList(); } void closePort( void ) {} unsigned int getPortCount( void ) { return 0; } std::string getPortName( unsigned int /*portNumber*/ ) { return ""; } From 3a4c48911a3c63448fd15dd44d920a3c258fc953 Mon Sep 17 00:00:00 2001 From: Tobias Schlemmer Date: Sat, 29 Mar 2014 09:58:12 +0100 Subject: [PATCH 15/45] Revert renaming MidiApi into MidiBackendApi and rename the other MidiApi. The new MidiApi is now called CommonMidiApi. This avoids some compilation errors. --- RtMidi.h | 80 +++++++++++++++++++++++++++++--------------------------- 1 file changed, 41 insertions(+), 39 deletions(-) diff --git a/RtMidi.h b/RtMidi.h index b1ab82f0..4e8764bd 100644 --- a/RtMidi.h +++ b/RtMidi.h @@ -113,7 +113,8 @@ class RtMidiError : public std::exception */ typedef void (*RtMidiErrorCallback)( RtMidiError::Type type, const std::string &errorText ); -class MidiApi { +class CommonMidiApi { +public: //! A port descriptor type. /*! This will be used with scoped pointers to store system dependent * data for identifying the port. @@ -220,7 +221,7 @@ class MidiApi { * * \return API that can handle this object. */ - virtual MidiApi * getAPI() = 0; + virtual CommonMidiApi * getAPI() = 0; //! Return the port name /*! @@ -287,7 +288,7 @@ class MidiApi { output devices which cannot be used as input if \ref PortDescriptor::OUTPUT is passed as \ref capabilities parameter. */ - virtual MidiApi::PortList getPortList(int capabilities = PortDescriptor:: INOUTPUT) = 0; + virtual CommonMidiApi::PortList getPortList(int capabilities = PortDescriptor:: INOUTPUT) = 0; //! Pure virtual to return the number of available MIDI ports of the current API. /*! @@ -340,14 +341,15 @@ class MidiApi { /*! \class RtMidi \brief A global class that implements basic backend API handling. - This class enhances \ref MidiApi by some functionality to handle + This class enhances \ref CommonMidiApi by some functionality to handle backend API objects. It serves as base class for the public RtMidi API. by Gary P. Scavone, 2003-2014. */ /**********************************************************************/ -class RtMidi : public MidiApi +class MidiApi; +class RtMidi : public CommonMidiApi { public: @@ -374,11 +376,11 @@ class RtMidi : public MidiApi static void getCompiledApi( std::vector &apis ) throw(); protected: + MidiApi *rtapi_; RtMidi(); virtual ~RtMidi(); - MidiApi *rtapi_; }; /**********************************************************************/ @@ -488,7 +490,7 @@ class RtMidiIn : public RtMidi ======= //! Returns a port descirptor if the port is open - virtual MidiApi::PortDescriptor::Pointer getDescriptor() = 0; + virtual CommonMidiApi::PortDescriptor::Pointer getDescriptor(); //! Return a list of all available input ports of the current API. /*! @@ -497,7 +499,7 @@ class RtMidiIn : public RtMidi \return This function returns a list of port descriptors. \note An Output API is not required to return all output ports from RtMidiIn. */ - virtual MidiApi::PortList getPortList(int capabilities = PortDescriptor:: INPUT); + virtual CommonMidiApi::PortList getPortList(int capabilities = PortDescriptor:: INPUT); //! Return the number of available MIDI input ports. /*! @@ -639,7 +641,7 @@ class RtMidiOut : public RtMidi /*! \return Port descriptor of the currently open port * \retval 0 iff the port s not open */ - virtual MidiApi::PortDescriptor::Pointer getDescriptor() = 0; + virtual CommonMidiApi::PortDescriptor::Pointer getDescriptor(); //! Close an open MIDI connection (if one exists). void closePort( void ); @@ -654,7 +656,7 @@ class RtMidiOut : public RtMidi \return This function returns a list of port descriptors. \note An API is not required to return all input ports from RtMidiOut. */ - virtual MidiApi::PortList getPortList(int capabilities = PortDescriptor::OUTPUT); + virtual CommonMidiApi::PortList getPortList(int capabilities = PortDescriptor::OUTPUT); //! Return the number of available MIDI output ports. unsigned int getPortCount( void ); @@ -698,7 +700,7 @@ class RtMidiOut : public RtMidi // // **************************************************************** // -class MidiBackendApi: public MidiApi +class MidiApi: public CommonMidiApi { public: @@ -723,7 +725,7 @@ class MidiBackendApi: public MidiApi RtMidiErrorCallback errorCallback_; }; -class MidiInApi : public MidiBackendApi +class MidiInApi : public MidiApi { public: @@ -782,7 +784,7 @@ class MidiInApi : public MidiBackendApi RtMidiInData inputData_; }; -class MidiOutApi : public MidiBackendApi +class MidiOutApi : public MidiApi { public: @@ -841,8 +843,8 @@ class MidiInCore: public MidiInApi void openPort( unsigned int portNumber, const std::string portName ); void openVirtualPort( const std::string portName ); void openPort( const PortDescriptor & port, const std::string portName); - MidiApi::PortDescriptor::Pointer getDescriptor(); - MidiApi::PortList getPortList(int capabilities); + CommonMidiApi::PortDescriptor::Pointer getDescriptor(); + CommonMidiApi::PortList getPortList(int capabilities); void closePort( void ); unsigned int getPortCount( void ); std::string getPortName( unsigned int portNumber ); @@ -860,8 +862,8 @@ class MidiOutCore: public MidiOutApi void openPort( unsigned int portNumber, const std::string portName ); void openVirtualPort( const std::string portName ); void openPort( const PortDescriptor & port, const std::string portName); - MidiApi::PortDescriptor::Pointer getDescriptor(); - MidiApi::PortList getPortList(int capabilities); + CommonMidiApi::PortDescriptor::Pointer getDescriptor(); + CommonMidiApi::PortList getPortList(int capabilities); void closePort( void ); unsigned int getPortCount( void ); std::string getPortName( unsigned int portNumber ); @@ -884,8 +886,8 @@ class MidiInJack: public MidiInApi void openPort( unsigned int portNumber, const std::string portName ); void openVirtualPort( const std::string portName ); void openPort( const PortDescriptor & port, const std::string portName); - MidiApi::PortDescriptor::Pointer getDescriptor(); - MidiApi::PortList getPortList(int capabilities); + CommonMidiApi::PortDescriptor::Pointer getDescriptor(); + CommonMidiApi::PortList getPortList(int capabilities); void closePort( void ); unsigned int getPortCount( void ); std::string getPortName( unsigned int portNumber ); @@ -906,8 +908,8 @@ class MidiOutJack: public MidiOutApi void openPort( unsigned int portNumber, const std::string portName ); void openVirtualPort( const std::string portName ); void openPort( const PortDescriptor & port, const std::string portName); - MidiApi::PortDescriptor::Pointer getDescriptor(); - MidiApi::PortList getPortList(int capabilities); + CommonMidiApi::PortDescriptor::Pointer getDescriptor(); + CommonMidiApi::PortList getPortList(int capabilities); void closePort( void ); unsigned int getPortCount( void ); std::string getPortName( unsigned int portNumber ); @@ -929,12 +931,12 @@ class MidiInAlsa: public MidiInApi public: MidiInAlsa( const std::string clientName, unsigned int queueSizeLimit ); ~MidiInAlsa( void ); - RtMidi::Api getCurrentApi( void ) { return RtMidi::LINUX_ALSA; }; + RtMidi::Api getCurrentApi( void ) throw() { return RtMidi::LINUX_ALSA; }; void openPort( unsigned int portNumber, const std::string portName ); void openVirtualPort( const std::string portName ); void openPort( const PortDescriptor & port, const std::string portName); - MidiApi::PortDescriptor::Pointer getDescriptor(); - MidiApi::PortList getPortList(int capabilities); + CommonMidiApi::PortDescriptor::Pointer getDescriptor(); + CommonMidiApi::PortList getPortList(int capabilities); void closePort( void ); unsigned int getPortCount( void ); std::string getPortName( unsigned int portNumber ); @@ -948,12 +950,12 @@ class MidiOutAlsa: public MidiOutApi public: MidiOutAlsa( const std::string clientName ); ~MidiOutAlsa( void ); - RtMidi::Api getCurrentApi( void ) { return RtMidi::LINUX_ALSA; }; + RtMidi::Api getCurrentApi( void ) throw() { return RtMidi::LINUX_ALSA; }; void openPort( unsigned int portNumber, const std::string portName ); void openVirtualPort( const std::string portName ); void openPort( const PortDescriptor & port, const std::string portName); - MidiApi::PortDescriptor::Pointer getDescriptor(); - MidiApi::PortList getPortList(int capabilities); + CommonMidiApi::PortDescriptor::Pointer getDescriptor(); + CommonMidiApi::PortList getPortList(int capabilities); void closePort( void ); unsigned int getPortCount( void ); std::string getPortName( unsigned int portNumber ); @@ -976,8 +978,8 @@ class MidiInWinMM: public MidiInApi void openPort( unsigned int portNumber, const std::string portName ); void openVirtualPort( const std::string portName ); void openPort( const PortDescriptor & port, const std::string portName); - MidiApi::PortDescriptor::Pointer getDescriptor(); - MidiApi::PortList getPortList(int capabilities); + CommonMidiApi::PortDescriptor::Pointer getDescriptor(); + CommonMidiApi::PortList getPortList(int capabilities); void closePort( void ); unsigned int getPortCount( void ); std::string getPortName( unsigned int portNumber ); @@ -995,8 +997,8 @@ class MidiOutWinMM: public MidiOutApi void openPort( unsigned int portNumber, const std::string portName ); void openVirtualPort( const std::string portName ); void openPort( const PortDescriptor & port, const std::string portName); - MidiApi::PortDescriptor::Pointer getDescriptor(); - MidiApi::PortList getPortList(int capabilities); + CommonMidiApi::PortDescriptor::Pointer getDescriptor(); + CommonMidiApi::PortList getPortList(int capabilities); void closePort( void ); unsigned int getPortCount( void ); std::string getPortName( unsigned int portNumber ); @@ -1019,8 +1021,8 @@ class MidiInWinKS: public MidiInApi void openPort( unsigned int portNumber, const std::string portName ); void openVirtualPort( const std::string portName ); void openPort( const PortDescriptor & port, const std::string portName); - MidiApi::PortDescriptor::Pointer getDescriptor(); - MidiApi::PortList getPortList(int capabilities); + CommonMidiApi::PortDescriptor::Pointer getDescriptor(); + CommonMidiApi::PortList getPortList(int capabilities); void closePort( void ); unsigned int getPortCount( void ); std::string getPortName( unsigned int portNumber ); @@ -1038,8 +1040,8 @@ class MidiOutWinKS: public MidiOutApi void openPort( unsigned int portNumber, const std::string portName ); void openVirtualPort( const std::string portName ); void openPort( const PortDescriptor & port, const std::string portName); - MidiApi::PortDescriptor::Pointer getDescriptor(); - MidiApi::PortList getPortList(int capabilities); + CommonMidiApi::PortDescriptor::Pointer getDescriptor(); + CommonMidiApi::PortList getPortList(int capabilities); void closePort( void ); unsigned int getPortCount( void ); std::string getPortName( unsigned int portNumber ); @@ -1065,8 +1067,8 @@ class MidiInDummy: public MidiInApi void openPort( unsigned int /*portNumber*/, const std::string /*portName*/ ) {} void openVirtualPort( const std::string /*portName*/ ) {} void openPort( const PortDescriptor & port, const std::string portName) {} - MidiApi::PortDescriptor::Pointer getDescriptor() { return 0; } - MidiApi::PortList getPortList(int capabilities) { return MidiApi::PortList(); } + CommonMidiApi::PortDescriptor::Pointer getDescriptor() { return 0; } + CommonMidiApi::PortList getPortList(int capabilities) { return CommonMidiApi::PortList(); } void closePort( void ) {} unsigned int getPortCount( void ) { return 0; } std::string getPortName( unsigned int portNumber ) { return ""; } @@ -1086,8 +1088,8 @@ class MidiOutDummy: public MidiOutApi void openPort( unsigned int /*portNumber*/, const std::string /*portName*/ ) {} void openVirtualPort( const std::string /*portName*/ ) {} void openPort( const PortDescriptor & port, const std::string portName) {} - MidiApi::PortDescriptor::Pointer getDescriptor() { return 0; } - MidiApi::PortList getPortList(int capabilities) { return MidiApi::PortList(); } + CommonMidiApi::PortDescriptor::Pointer getDescriptor() { return 0; } + CommonMidiApi::PortList getPortList(int capabilities) { return CommonMidiApi::PortList(); } void closePort( void ) {} unsigned int getPortCount( void ) { return 0; } std::string getPortName( unsigned int /*portNumber*/ ) { return ""; } From 53114d05d87c8c9233a69b61679f1ba270ed981e Mon Sep 17 00:00:00 2001 From: Tobias Schlemmer Date: Sat, 29 Mar 2014 09:59:24 +0100 Subject: [PATCH 16/45] Fix some compiler errros. --- RtMidi.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/RtMidi.h b/RtMidi.h index 4e8764bd..cea4445b 100644 --- a/RtMidi.h +++ b/RtMidi.h @@ -172,7 +172,7 @@ class CommonMidiApi { ptr->count = 1; ptr->descriptor = p; } - Pointer(Pointer & other): + Pointer(const Pointer & other): ptr(other.ptr) { ptr->count++; } @@ -335,7 +335,7 @@ class CommonMidiApi { to set the error callback function before opening a port. */ virtual void setErrorCallback( RtMidiErrorCallback errorCallback = NULL ) = 0; -} +}; /**********************************************************************/ /*! \class RtMidi @@ -475,7 +475,7 @@ class RtMidiIn : public RtMidi \param port A port descriptor of the port must be specified. \param portName An optional name for the applicaction port that is used to connect to portId can be specified. */ - void openPort( const PortDescriptor & port, const std::string portName = std::string( "RtMidi" ) ) = 0; + void openPort( const PortDescriptor & port, const std::string portName = std::string( "RtMidi" ) ); <<<<<<< HEAD //! Create a virtual input port, with optional name, to allow software connections (OS X, JACK and ALSA only). @@ -635,7 +635,7 @@ class RtMidiOut : public RtMidi \param port A port descriptor of the port must be specified. \param portName An optional name for the applicaction port that is used to connect to portId can be specified. */ - virtual void openPort( const PortDescriptor & port, const std::string portName = std::string( "RtMidi Output" ) ) = 0; + virtual void openPort( const PortDescriptor & port, const std::string portName = std::string( "RtMidi Output" ) ); //! Returns a port descirptor if the port is open /*! \return Port descriptor of the currently open port From aeffadecb4f4f56d26c55e888d89f7282d1d334b Mon Sep 17 00:00:00 2001 From: Tobias Schlemmer Date: Sat, 29 Mar 2014 10:01:34 +0100 Subject: [PATCH 17/45] Add missing inline functions and reformat existing ones. This should be better readable. --- RtMidi.h | 131 ++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 111 insertions(+), 20 deletions(-) diff --git a/RtMidi.h b/RtMidi.h index cea4445b..433514d0 100644 --- a/RtMidi.h +++ b/RtMidi.h @@ -713,6 +713,10 @@ class MidiApi: public CommonMidiApi bool isPortOpen() const { return connected_; } void setErrorCallback( RtMidiErrorCallback errorCallback ); + + //! Returns the MIDI API specifier for the current instance of RtMidiIn. + virtual RtMidi::Api getCurrentApi( void ) throw(); + //! A basic error reporting function for RtMidi classes. void error( RtMidiError::Type type, std::string errorString ); @@ -799,28 +803,115 @@ class MidiOutApi : public MidiApi // // **************************************************************** // -inline RtMidi::Api RtMidiIn :: getCurrentApi( void ) throw() { return rtapi_->getCurrentApi(); } -inline void RtMidiIn :: openPort( unsigned int portNumber, const std::string portName ) { rtapi_->openPort( portNumber, portName ); } -inline void RtMidiIn :: openVirtualPort( const std::string portName ) { rtapi_->openVirtualPort( portName ); } +inline RtMidi::Api RtMidiIn :: getCurrentApi( void ) throw() +{ + return rtapi_->getCurrentApi(); +} +inline void RtMidiIn :: openVirtualPort( const std::string portName ) +{ + rtapi_->openVirtualPort( portName ); +} +inline void RtMidiIn :: openPort( unsigned int portNumber, + const std::string portName ) +{ + rtapi_->openPort( portNumber, portName ); +} +inline void RtMidiIn :: openPort( const CommonMidiApi::PortDescriptor & port, + const std::string portName) +{ + rtapi_->openPort(port,portName); +} +inline CommonMidiApi::PortDescriptor::Pointer RtMidiIn :: getDescriptor() +{ + return rtapi_->getDescriptor(); +} +inline CommonMidiApi::PortList RtMidiIn :: getPortList(int capabilities) +{ + return rtapi_->getPortList(capabilities); +} +inline unsigned int RtMidiIn :: getPortCount( void ) +{ + return rtapi_->getPortCount(); +} +inline std::string RtMidiIn :: getPortName( unsigned int portNumber ) +{ + return rtapi_->getPortName( portNumber ); +} inline void RtMidiIn :: closePort( void ) { rtapi_->closePort(); } inline bool RtMidiIn :: isPortOpen() const { return rtapi_->isPortOpen(); } -inline void RtMidiIn :: setCallback( RtMidiCallback callback, void *userData ) { ((MidiInApi *)rtapi_)->setCallback( callback, userData ); } -inline void RtMidiIn :: cancelCallback( void ) { ((MidiInApi *)rtapi_)->cancelCallback(); } -inline unsigned int RtMidiIn :: getPortCount( void ) { return rtapi_->getPortCount(); } -inline std::string RtMidiIn :: getPortName( unsigned int portNumber ) { return rtapi_->getPortName( portNumber ); } -inline void RtMidiIn :: ignoreTypes( bool midiSysex, bool midiTime, bool midiSense ) { ((MidiInApi *)rtapi_)->ignoreTypes( midiSysex, midiTime, midiSense ); } -inline double RtMidiIn :: getMessage( std::vector *message ) { return ((MidiInApi *)rtapi_)->getMessage( message ); } -inline void RtMidiIn :: setErrorCallback( RtMidiErrorCallback errorCallback ) { rtapi_->setErrorCallback(errorCallback); } - -inline RtMidi::Api RtMidiOut :: getCurrentApi( void ) throw() { return rtapi_->getCurrentApi(); } -inline void RtMidiOut :: openPort( unsigned int portNumber, const std::string portName ) { rtapi_->openPort( portNumber, portName ); } -inline void RtMidiOut :: openVirtualPort( const std::string portName ) { rtapi_->openVirtualPort( portName ); } -inline void RtMidiOut :: closePort( void ) { rtapi_->closePort(); } -inline bool RtMidiOut :: isPortOpen() const { return rtapi_->isPortOpen(); } -inline unsigned int RtMidiOut :: getPortCount( void ) { return rtapi_->getPortCount(); } -inline std::string RtMidiOut :: getPortName( unsigned int portNumber ) { return rtapi_->getPortName( portNumber ); } -inline void RtMidiOut :: sendMessage( std::vector *message ) { ((MidiOutApi *)rtapi_)->sendMessage( message ); } -inline void RtMidiOut :: setErrorCallback( RtMidiErrorCallback errorCallback ) { rtapi_->setErrorCallback(errorCallback); } +inline void RtMidiIn :: setCallback( RtMidiCallback callback, + void *userData ) +{ + ((MidiInApi *)rtapi_)->setCallback( callback, userData ); +} +inline void RtMidiIn :: cancelCallback( void ) +{ + ((MidiInApi *)rtapi_)->cancelCallback(); +} +inline void RtMidiIn :: ignoreTypes( bool midiSysex, + bool midiTime, + bool midiSense ) +{ + ((MidiInApi *)rtapi_)->ignoreTypes( midiSysex, midiTime, midiSense ); +} +inline double RtMidiIn :: getMessage( std::vector *message ) +{ + return ((MidiInApi *)rtapi_)->getMessage( message ); +} +inline void RtMidiIn :: setErrorCallback( RtMidiErrorCallback errorCallback ) +{ + rtapi_->setErrorCallback(errorCallback); +} + +inline RtMidi::Api RtMidiOut :: getCurrentApi( void ) throw() +{ + return rtapi_->getCurrentApi(); +} +inline void RtMidiOut :: openPort( unsigned int portNumber, const std::string portName ) +{ + rtapi_->openPort( portNumber, portName ); +} +inline void RtMidiOut :: openVirtualPort( const std::string portName ) +{ + rtapi_->openVirtualPort( portName ); +} +inline void RtMidiOut :: openPort( const CommonMidiApi::PortDescriptor & port, + const std::string portName) +{ + rtapi_->openPort(port,portName); +} +inline CommonMidiApi::PortDescriptor::Pointer RtMidiOut :: getDescriptor() +{ + return rtapi_->getDescriptor(); +} +inline CommonMidiApi::PortList RtMidiOut :: getPortList(int capabilities) +{ + return rtapi_->getPortList(capabilities); +} +inline void RtMidiOut :: closePort( void ) +{ + rtapi_->closePort(); +} +inline bool RtMidiOut :: isPortOpen() const +{ + return rtapi_->isPortOpen(); +} +inline unsigned int RtMidiOut :: getPortCount( void ) +{ + return rtapi_->getPortCount(); +} +inline std::string RtMidiOut :: getPortName( unsigned int portNumber ) +{ + return rtapi_->getPortName( portNumber ); +} +inline void RtMidiOut :: sendMessage( std::vector *message ) +{ + ((MidiOutApi *)rtapi_)->sendMessage( message ); +} +inline void RtMidiOut :: setErrorCallback( RtMidiErrorCallback errorCallback ) +{ + rtapi_->setErrorCallback(errorCallback); +} // **************************************************************** // // From 0b44c7b60f9ce4dbc827ad5e4193cfac4ffd3e58 Mon Sep 17 00:00:00 2001 From: Tobias Schlemmer Date: Sun, 30 Mar 2014 16:13:04 +0200 Subject: [PATCH 18/45] Namespace based API and get rid of virtual inline functions for RtMidi(In|Out). MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch includes more than it was intended to. The changes include: • provide a namespace rtmidi to simplify class names • Make all functions of Midi(In|Out)? non-virtual. Virtual inline functions have several pitfalls. • provide Dummies for the new ALSA api. • provide workaround for the major API breaks. • use references for passing certain pointer arguments and deprecate the pointer versions of these functions. --- RtMidi.cpp | 7107 ++++++++++++++++++++++++++-------------------------- RtMidi.h | 2053 ++++++++------- 2 files changed, 4608 insertions(+), 4552 deletions(-) diff --git a/RtMidi.cpp b/RtMidi.cpp index 2101c377..6a3098d9 100644 --- a/RtMidi.cpp +++ b/RtMidi.cpp @@ -1,2447 +1,2507 @@ /**********************************************************************/ -/*! \class RtMidi - \brief An abstract base class for realtime MIDI input/output. - - This class implements some common functionality for the realtime - MIDI input/output subclasses RtMidiIn and RtMidiOut. - - RtMidi WWW site: http://music.mcgill.ca/~gary/rtmidi/ - - RtMidi: realtime MIDI i/o C++ classes - Copyright (c) 2003-2014 Gary P. Scavone - - Permission is hereby granted, free of charge, to any person - obtaining a copy of this software and associated documentation files - (the "Software"), to deal in the Software without restriction, - including without limitation the rights to use, copy, modify, merge, - publish, distribute, sublicense, and/or sell copies of the Software, - and to permit persons to whom the Software is furnished to do so, - subject to the following conditions: - - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. - - Any person wishing to distribute modifications to the Software is - asked to send the modifications to the original developer so that - they can be incorporated into the canonical version. This is, - however, not a binding provision of this license. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR - ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +/*! \class Midi + \brief An abstract base class for realtime MIDI input/output. + + This class implements some common functionality for the realtime + MIDI input/output subclasses MidiIn and MidiOut. + + Midi WWW site: http://music.mcgill.ca/~gary/rtmidi/ + + Midi: realtime MIDI i/o C++ classes + Copyright (c) 2003-2014 Gary P. Scavone + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation files + (the "Software"), to deal in the Software without restriction, + including without limitation the rights to use, copy, modify, merge, + publish, distribute, sublicense, and/or sell copies of the Software, + and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + Any person wishing to distribute modifications to the Software is + asked to send the modifications to the original developer so that + they can be incorporated into the canonical version. This is, + however, not a binding provision of this license. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR + ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**********************************************************************/ #include "RtMidi.h" #include -//*********************************************************************// -// RtMidi Definitions -//*********************************************************************// - -RtMidi :: RtMidi() - : rtapi_(0) -{ -} - -RtMidi :: ~RtMidi() -{ - if ( rtapi_ ) - delete rtapi_; - rtapi_ = 0; -} - -std::string RtMidi :: getVersion( void ) throw() -{ - return std::string( RTMIDI_VERSION ); -} +namespace rtmidi { + //*********************************************************************// + // Midi Definitions + //*********************************************************************// + std::string Midi :: getVersion( void ) throw() + { + return std::string( RTMIDI_VERSION ); + } -void RtMidi :: getCompiledApi( std::vector &apis ) throw() -{ - apis.clear(); + void Midi :: getCompiledApi( std::vector &apis ) throw() + { + apis.clear(); - // The order here will control the order of RtMidi's API search in - // the constructor. + // The order here will control the order of RtMidi's API search in + // the constructor. #if defined(__MACOSX_CORE__) - apis.push_back( MACOSX_CORE ); + apis.push_back( rtmidi::MACOSX_CORE ); #endif #if defined(__LINUX_ALSA__) - apis.push_back( LINUX_ALSA ); + apis.push_back( rtmidi::LINUX_ALSA ); #endif #if defined(__UNIX_JACK__) - apis.push_back( UNIX_JACK ); + apis.push_back( rtmidi::UNIX_JACK ); #endif #if defined(__WINDOWS_MM__) - apis.push_back( WINDOWS_MM ); + apis.push_back( rtmidi::WINDOWS_MM ); #endif #if defined(__WINDOWS_KS__) - apis.push_back( WINDOWS_KS ); + apis.push_back( rtmidi::WINDOWS_KS ); #endif #if defined(__RTMIDI_DUMMY__) - apis.push_back( RTMIDI_DUMMY ); + apis.push_back( rtmidi::RTMIDI_DUMMY ); #endif -} + } + + void Midi :: error( Error::Type type, std::string errorString ) + { +#if 0 + if ( errorCallback_ ) { + static bool firstErrorOccured = false; + + if ( firstErrorOccured ) + return; + + firstErrorOccured = true; + const std::string errorMessage = errorString; + + errorCallback_( type, errorMessage ); + firstErrorOccured = false; + return; + } +#endif + + if ( type == Error::WARNING ) { + std::cerr << '\n' << errorString << "\n\n"; + } + else if ( type == Error::DEBUG_WARNING ) { +#if defined(__RTMIDI_DEBUG__) + std::cerr << '\n' << errorString << "\n\n"; +#endif + } + else { + std::cerr << '\n' << errorString << "\n\n"; + throw Error( errorString, type ); + } + } + -//*********************************************************************// -// RtMidiIn Definitions -//*********************************************************************// -void RtMidiIn :: openMidiApi( RtMidi::Api api, const std::string clientName, unsigned int queueSizeLimit ) -{ - if ( rtapi_ ) - delete rtapi_; - rtapi_ = 0; + + //*********************************************************************// + // MidiIn Definitions + //*********************************************************************// + + void MidiIn :: openMidiApi( ApiType api, const std::string clientName, unsigned int queueSizeLimit ) + { + if ( rtapi_ ) + delete rtapi_; + rtapi_ = 0; #if defined(__UNIX_JACK__) - if ( api == UNIX_JACK ) - rtapi_ = new MidiInJack( clientName, queueSizeLimit ); + if ( api == rtmidi::UNIX_JACK ) + rtapi_ = new MidiInJack( clientName, queueSizeLimit ); #endif #if defined(__LINUX_ALSA__) - if ( api == LINUX_ALSA ) - rtapi_ = new MidiInAlsa( clientName, queueSizeLimit ); + if ( api == rtmidi::LINUX_ALSA ) + rtapi_ = new MidiInAlsa( clientName, queueSizeLimit ); #endif #if defined(__WINDOWS_MM__) - if ( api == WINDOWS_MM ) - rtapi_ = new MidiInWinMM( clientName, queueSizeLimit ); + if ( api == rtmidi::WINDOWS_MM ) + rtapi_ = new MidiInWinMM( clientName, queueSizeLimit ); #endif #if defined(__WINDOWS_KS__) - if ( api == WINDOWS_KS ) - rtapi_ = new MidiInWinKS( clientName, queueSizeLimit ); + if ( api == rtmidi::WINDOWS_KS ) + rtapi_ = new MidiInWinKS( clientName, queueSizeLimit ); #endif #if defined(__MACOSX_CORE__) - if ( api == MACOSX_CORE ) - rtapi_ = new MidiInCore( clientName, queueSizeLimit ); + if ( api == rtmidi::MACOSX_CORE ) + rtapi_ = new MidiInCore( clientName, queueSizeLimit ); #endif #if defined(__RTMIDI_DUMMY__) - if ( api == RTMIDI_DUMMY ) - rtapi_ = new MidiInDummy( clientName, queueSizeLimit ); + if ( api == rtmidi::RTMIDI_DUMMY ) + rtapi_ = new MidiInDummy( clientName, queueSizeLimit ); #endif -} + } -RtMidiIn :: RtMidiIn( RtMidi::Api api, const std::string clientName, unsigned int queueSizeLimit ) - : RtMidi() -{ - if ( api != UNSPECIFIED ) { - // Attempt to open the specified API. - openMidiApi( api, clientName, queueSizeLimit ); - if ( rtapi_ ) return; - - // No compiled support for specified API value. Issue a warning - // and continue as if no API was specified. - std::cerr << "\nRtMidiIn: no compiled support for specified API argument!\n\n" << std::endl; - } - - // Iterate through the compiled APIs and return as soon as we find - // one with at least one port or we reach the end of the list. - std::vector< RtMidi::Api > apis; - getCompiledApi( apis ); - for ( unsigned int i=0; igetPortCount() ) break; - } - - if ( rtapi_ ) return; - - // It should not be possible to get here because the preprocessor - // definition __RTMIDI_DUMMY__ is automatically defined if no - // API-specific definitions are passed to the compiler. But just in - // case something weird happens, we'll throw an error. - std::string errorText = "RtMidiIn: no compiled API support found ... critical error!!"; - throw( RtMidiError( errorText, RtMidiError::UNSPECIFIED ) ); -} + MidiIn :: MidiIn( ApiType api, const std::string clientName, unsigned int queueSizeLimit ) + : Midi() + { + if ( api != rtmidi::UNSPECIFIED ) { + // Attempt to open the specified API. + openMidiApi( api, clientName, queueSizeLimit ); + if ( rtapi_ ) return; + + // No compiled support for specified API value. Issue a warning + // and continue as if no API was specified. + std::cerr << "\nMidiIn: no compiled support for specified API argument!\n\n" << std::endl; + } + + // Iterate through the compiled APIs and return as soon as we find + // one with at least one port or we reach the end of the list. + std::vector< ApiType > apis; + getCompiledApi( apis ); + for ( unsigned int i=0; igetPortCount() ) break; + } + + if ( rtapi_ ) return; + + // It should not be possible to get here because the preprocessor + // definition __RTMIDI_DUMMY__ is automatically defined if no + // API-specific definitions are passed to the compiler. But just in + // case something weird happens, we'll throw an error. + std::string errorText = "MidiIn: no compiled API support found ... critical error!!"; + throw( Error( errorText, Error::UNSPECIFIED ) ); + } -RtMidiIn :: ~RtMidiIn() throw() -{ -} + MidiIn :: ~MidiIn() throw() + { + } -//*********************************************************************// -// RtMidiOut Definitions -//*********************************************************************// + //*********************************************************************// + // MidiOut Definitions + //*********************************************************************// -void RtMidiOut :: openMidiApi( RtMidi::Api api, const std::string clientName ) -{ - if ( rtapi_ ) - delete rtapi_; - rtapi_ = 0; + void MidiOut :: openMidiApi( ApiType api, const std::string clientName ) + { + if ( rtapi_ ) + delete rtapi_; + rtapi_ = 0; #if defined(__UNIX_JACK__) - if ( api == UNIX_JACK ) - rtapi_ = new MidiOutJack( clientName ); + if ( api == rtmidi::UNIX_JACK ) + rtapi_ = new MidiOutJack( clientName ); #endif #if defined(__LINUX_ALSA__) - if ( api == LINUX_ALSA ) - rtapi_ = new MidiOutAlsa( clientName ); + if ( api == rtmidi::LINUX_ALSA ) + rtapi_ = new MidiOutAlsa( clientName ); #endif #if defined(__WINDOWS_MM__) - if ( api == WINDOWS_MM ) - rtapi_ = new MidiOutWinMM( clientName ); + if ( api == rtmidi::WINDOWS_MM ) + rtapi_ = new MidiOutWinMM( clientName ); #endif #if defined(__WINDOWS_KS__) - if ( api == WINDOWS_KS ) - rtapi_ = new MidiOutWinKS( clientName ); + if ( api == rtmidi::WINDOWS_KS ) + rtapi_ = new MidiOutWinKS( clientName ); #endif #if defined(__MACOSX_CORE__) - if ( api == MACOSX_CORE ) - rtapi_ = new MidiOutCore( clientName ); + if ( api == rtmidi::MACOSX_CORE ) + rtapi_ = new MidiOutCore( clientName ); #endif #if defined(__RTMIDI_DUMMY__) - if ( api == RTMIDI_DUMMY ) - rtapi_ = new MidiOutDummy( clientName ); + if ( api == rtmidi::RTMIDI_DUMMY ) + rtapi_ = new MidiOutDummy( clientName ); #endif -} + } -RtMidiOut :: RtMidiOut( RtMidi::Api api, const std::string clientName ) -{ - if ( api != UNSPECIFIED ) { - // Attempt to open the specified API. - openMidiApi( api, clientName ); - if ( rtapi_ ) return; - - // No compiled support for specified API value. Issue a warning - // and continue as if no API was specified. - std::cerr << "\nRtMidiOut: no compiled support for specified API argument!\n\n" << std::endl; - } - - // Iterate through the compiled APIs and return as soon as we find - // one with at least one port or we reach the end of the list. - std::vector< RtMidi::Api > apis; - getCompiledApi( apis ); - for ( unsigned int i=0; igetPortCount() ) break; - } - - if ( rtapi_ ) return; - - // It should not be possible to get here because the preprocessor - // definition __RTMIDI_DUMMY__ is automatically defined if no - // API-specific definitions are passed to the compiler. But just in - // case something weird happens, we'll thrown an error. - std::string errorText = "RtMidiOut: no compiled API support found ... critical error!!"; - throw( RtMidiError( errorText, RtMidiError::UNSPECIFIED ) ); -} + MidiOut :: MidiOut( ApiType api, const std::string clientName ) + { + if ( api != rtmidi::UNSPECIFIED ) { + // Attempt to open the specified API. + openMidiApi( api, clientName ); + if ( rtapi_ ) return; + + // No compiled support for specified API value. Issue a warning + // and continue as if no API was specified. + std::cerr << "\nMidiOut: no compiled support for specified API argument!\n\n" << std::endl; + } + + // Iterate through the compiled APIs and return as soon as we find + // one with at least one port or we reach the end of the list. + std::vector< ApiType > apis; + getCompiledApi( apis ); + for ( unsigned int i=0; igetPortCount() ) break; + } + + if ( rtapi_ ) return; + + // It should not be possible to get here because the preprocessor + // definition __RTMIDI_DUMMY__ is automatically defined if no + // API-specific definitions are passed to the compiler. But just in + // case something weird happens, we'll thrown an error. + std::string errorText = "MidiOut: no compiled API support found ... critical error!!"; + throw( Error( errorText, Error::UNSPECIFIED ) ); + } -RtMidiOut :: ~RtMidiOut() throw() -{ -} + MidiOut :: ~MidiOut() throw() + { + } -//*********************************************************************// -// Common MidiApi Definitions -//*********************************************************************// + //*********************************************************************// + // Common MidiApi Definitions + //*********************************************************************// -MidiApi :: MidiApi( void ) - : apiData_( 0 ), connected_( false ), errorCallback_(0) -{ -} + MidiApi :: MidiApi( void ) + : apiData_( 0 ), connected_( false ), errorCallback_(0) + { + } -MidiApi :: ~MidiApi( void ) -{ -} + MidiApi :: ~MidiApi( void ) + { + } -void MidiApi :: setErrorCallback( RtMidiErrorCallback errorCallback ) -{ - errorCallback_ = errorCallback; -} + void MidiApi :: setErrorCallback( ErrorCallback errorCallback ) + { + errorCallback_ = errorCallback; + } -void MidiApi :: error( RtMidiError::Type type, std::string errorString ) -{ - if ( errorCallback_ ) { - static bool firstErrorOccured = false; + void MidiApi :: error( Error::Type type, std::string errorString ) + { + if ( errorCallback_ ) { + static bool firstErrorOccured = false; - if ( firstErrorOccured ) - return; + if ( firstErrorOccured ) + return; - firstErrorOccured = true; - const std::string errorMessage = errorString; + firstErrorOccured = true; + const std::string errorMessage = errorString; - errorCallback_( type, errorMessage ); - firstErrorOccured = false; - return; - } + errorCallback_( type, errorMessage ); + firstErrorOccured = false; + return; + } - if ( type == RtMidiError::WARNING ) { - std::cerr << '\n' << errorString << "\n\n"; - } - else if ( type == RtMidiError::DEBUG_WARNING ) { + if ( type == Error::WARNING ) { + std::cerr << '\n' << errorString << "\n\n"; + } + else if ( type == Error::DEBUG_WARNING ) { #if defined(__RTMIDI_DEBUG__) - std::cerr << '\n' << errorString << "\n\n"; + std::cerr << '\n' << errorString << "\n\n"; #endif - } - else { - std::cerr << '\n' << errorString << "\n\n"; - throw RtMidiError( errorString, type ); - } -} + } + else { + std::cerr << '\n' << errorString << "\n\n"; + throw Error( errorString, type ); + } + } -//*********************************************************************// -// Common MidiInApi Definitions -//*********************************************************************// - -MidiInApi :: MidiInApi( unsigned int queueSizeLimit ) - : MidiApi() -{ - // Allocate the MIDI queue. - inputData_.queue.ringSize = queueSizeLimit; - if ( inputData_.queue.ringSize > 0 ) - inputData_.queue.ring = new MidiMessage[ inputData_.queue.ringSize ]; -} + //*********************************************************************// + // Common MidiInApi Definitions + //*********************************************************************// + + MidiInApi :: MidiInApi( unsigned int queueSizeLimit ) + : MidiApi() + { + // Allocate the MIDI queue. + inputData_.queue.ringSize = queueSizeLimit; + if ( inputData_.queue.ringSize > 0 ) + inputData_.queue.ring = new MidiMessage[ inputData_.queue.ringSize ]; + } -MidiInApi :: ~MidiInApi( void ) -{ - // Delete the MIDI queue. - if ( inputData_.queue.ringSize > 0 ) delete [] inputData_.queue.ring; -} + MidiInApi :: ~MidiInApi( void ) + { + // Delete the MIDI queue. + if ( inputData_.queue.ringSize > 0 ) delete [] inputData_.queue.ring; + } -void MidiInApi :: setCallback( RtMidiIn::RtMidiCallback callback, void *userData ) -{ - if ( inputData_.usingCallback ) { - errorString_ = "MidiInApi::setCallback: a callback function is already set!"; - error( RtMidiError::WARNING, errorString_ ); - return; - } - - if ( !callback ) { - errorString_ = "RtMidiIn::setCallback: callback function value is invalid!"; - error( RtMidiError::WARNING, errorString_ ); - return; - } - - inputData_.userCallback = callback; - inputData_.userData = userData; - inputData_.usingCallback = true; -} + void MidiInApi :: setCallback( MidiCallback callback, void *userData ) + { + if ( inputData_.usingCallback ) { + errorString_ = "MidiInApi::setCallback: a callback function is already set!"; + error( Error::WARNING, errorString_ ); + return; + } + + if ( !callback ) { + errorString_ = "MidiIn::setCallback: callback function value is invalid!"; + error( Error::WARNING, errorString_ ); + return; + } + + inputData_.userCallback = callback; + inputData_.userData = userData; + inputData_.usingCallback = true; + } -void MidiInApi :: cancelCallback() -{ - if ( !inputData_.usingCallback ) { - errorString_ = "RtMidiIn::cancelCallback: no callback function was set!"; - error( RtMidiError::WARNING, errorString_ ); - return; - } - - inputData_.userCallback = 0; - inputData_.userData = 0; - inputData_.usingCallback = false; -} + void MidiInApi :: cancelCallback() + { + if ( !inputData_.usingCallback ) { + errorString_ = "MidiIn::cancelCallback: no callback function was set!"; + error( Error::WARNING, errorString_ ); + return; + } + + inputData_.userCallback = 0; + inputData_.userData = 0; + inputData_.usingCallback = false; + } -void MidiInApi :: ignoreTypes( bool midiSysex, bool midiTime, bool midiSense ) -{ - inputData_.ignoreFlags = 0; - if ( midiSysex ) inputData_.ignoreFlags = 0x01; - if ( midiTime ) inputData_.ignoreFlags |= 0x02; - if ( midiSense ) inputData_.ignoreFlags |= 0x04; -} + void MidiInApi :: ignoreTypes( bool midiSysex, bool midiTime, bool midiSense ) + { + inputData_.ignoreFlags = 0; + if ( midiSysex ) inputData_.ignoreFlags = 0x01; + if ( midiTime ) inputData_.ignoreFlags |= 0x02; + if ( midiSense ) inputData_.ignoreFlags |= 0x04; + } -double MidiInApi :: getMessage( std::vector *message ) -{ - message->clear(); + double MidiInApi :: getMessage( std::vector &message ) + { + message.clear(); - if ( inputData_.usingCallback ) { - errorString_ = "RtMidiIn::getNextMessage: a user callback is currently set for this port."; - error( RtMidiError::WARNING, errorString_ ); - return 0.0; - } + if ( inputData_.usingCallback ) { + errorString_ = "MidiIn::getMessage: a user callback is currently set for this port."; + error( Error::WARNING, errorString_ ); + return 0.0; + } - if ( inputData_.queue.size == 0 ) return 0.0; + if ( inputData_.queue.size == 0 ) return 0.0; - // Copy queued message to the vector pointer argument and then "pop" it. - std::vector *bytes = &(inputData_.queue.ring[inputData_.queue.front].bytes); - message->assign( bytes->begin(), bytes->end() ); - double deltaTime = inputData_.queue.ring[inputData_.queue.front].timeStamp; - inputData_.queue.size--; - inputData_.queue.front++; - if ( inputData_.queue.front == inputData_.queue.ringSize ) - inputData_.queue.front = 0; + // Copy queued message to the vector pointer argument and then "pop" it. + std::vector *bytes = &(inputData_.queue.ring[inputData_.queue.front].bytes); + message.assign( bytes->begin(), bytes->end() ); + double deltaTime = inputData_.queue.ring[inputData_.queue.front].timeStamp; + inputData_.queue.size--; + inputData_.queue.front++; + if ( inputData_.queue.front == inputData_.queue.ringSize ) + inputData_.queue.front = 0; - return deltaTime; -} + return deltaTime; + } -//*********************************************************************// -// Common MidiOutApi Definitions -//*********************************************************************// + //*********************************************************************// + // Common MidiOutApi Definitions + //*********************************************************************// -MidiOutApi :: MidiOutApi( void ) - : MidiApi() -{ -} + MidiOutApi :: MidiOutApi( void ) + : MidiApi() + { + } -MidiOutApi :: ~MidiOutApi( void ) -{ -} + MidiOutApi :: ~MidiOutApi( void ) + { + } -// *************************************************** // -// -// OS/API-specific methods. -// -// *************************************************** // + // *************************************************** // + // + // OS/API-specific methods. + // + // *************************************************** // +} #if defined(__MACOSX_CORE__) -// The CoreMIDI API is based on the use of a callback function for -// MIDI input. We convert the system specific time stamps to delta -// time values. + // The CoreMIDI API is based on the use of a callback function for + // MIDI input. We convert the system specific time stamps to delta + // time values. -// OS-X CoreMIDI header files. + // OS-X CoreMIDI header files. #include #include #include -// A structure to hold variables related to the CoreMIDI API -// implementation. -struct CoreMidiData { - MIDIClientRef client; - MIDIPortRef port; - MIDIEndpointRef endpoint; - MIDIEndpointRef destinationId; - unsigned long long lastTime; - MIDISysexSendRequest sysexreq; -}; - -//*********************************************************************// -// API: OS-X -// Class Definitions: MidiInCore -//*********************************************************************// - -static void midiInputCallback( const MIDIPacketList *list, void *procRef, void */*srcRef*/ ) -{ - MidiInApi::RtMidiInData *data = static_cast (procRef); - CoreMidiData *apiData = static_cast (data->apiData); - - unsigned char status; - unsigned short nBytes, iByte, size; - unsigned long long time; - - bool& continueSysex = data->continueSysex; - MidiInApi::MidiMessage& message = data->message; - - const MIDIPacket *packet = &list->packet[0]; - for ( unsigned int i=0; inumPackets; ++i ) { - - // My interpretation of the CoreMIDI documentation: all message - // types, except sysex, are complete within a packet and there may - // be several of them in a single packet. Sysex messages can be - // broken across multiple packets and PacketLists but are bundled - // alone within each packet (these packets do not contain other - // message types). If sysex messages are split across multiple - // MIDIPacketLists, they must be handled by multiple calls to this - // function. - - nBytes = packet->length; - if ( nBytes == 0 ) continue; - - // Calculate time stamp. - - if ( data->firstMessage ) { - message.timeStamp = 0.0; - data->firstMessage = false; - } - else { - time = packet->timeStamp; - if ( time == 0 ) { // this happens when receiving asynchronous sysex messages - time = AudioGetCurrentHostTime(); - } - time -= apiData->lastTime; - time = AudioConvertHostTimeToNanos( time ); - if ( !continueSysex ) - message.timeStamp = time * 0.000000001; - } - apiData->lastTime = packet->timeStamp; - if ( apiData->lastTime == 0 ) { // this happens when receiving asynchronous sysex messages - apiData->lastTime = AudioGetCurrentHostTime(); - } - //std::cout << "TimeStamp = " << packet->timeStamp << std::endl; - - iByte = 0; - if ( continueSysex ) { - // We have a continuing, segmented sysex message. - if ( !( data->ignoreFlags & 0x01 ) ) { - // If we're not ignoring sysex messages, copy the entire packet. - for ( unsigned int j=0; jdata[j] ); - } - continueSysex = packet->data[nBytes-1] != 0xF7; - - if ( !( data->ignoreFlags & 0x01 ) && !continueSysex ) { - // If not a continuing sysex message, invoke the user callback function or queue the message. - if ( data->usingCallback ) { - RtMidiIn::RtMidiCallback callback = (RtMidiIn::RtMidiCallback) data->userCallback; - callback( message.timeStamp, &message.bytes, data->userData ); - } - else { - // As long as we haven't reached our queue size limit, push the message. - if ( data->queue.size < data->queue.ringSize ) { - data->queue.ring[data->queue.back++] = message; - if ( data->queue.back == data->queue.ringSize ) - data->queue.back = 0; - data->queue.size++; - } - else - std::cerr << "\nMidiInCore: message queue limit reached!!\n\n"; - } - message.bytes.clear(); - } - } - else { - while ( iByte < nBytes ) { - size = 0; - // We are expecting that the next byte in the packet is a status byte. - status = packet->data[iByte]; - if ( !(status & 0x80) ) break; - // Determine the number of bytes in the MIDI message. - if ( status < 0xC0 ) size = 3; - else if ( status < 0xE0 ) size = 2; - else if ( status < 0xF0 ) size = 3; - else if ( status == 0xF0 ) { - // A MIDI sysex - if ( data->ignoreFlags & 0x01 ) { - size = 0; - iByte = nBytes; - } - else size = nBytes - iByte; - continueSysex = packet->data[nBytes-1] != 0xF7; - } - else if ( status == 0xF1 ) { - // A MIDI time code message - if ( data->ignoreFlags & 0x02 ) { - size = 0; - iByte += 2; - } - else size = 2; - } - else if ( status == 0xF2 ) size = 3; - else if ( status == 0xF3 ) size = 2; - else if ( status == 0xF8 && ( data->ignoreFlags & 0x02 ) ) { - // A MIDI timing tick message and we're ignoring it. - size = 0; - iByte += 1; - } - else if ( status == 0xFE && ( data->ignoreFlags & 0x04 ) ) { - // A MIDI active sensing message and we're ignoring it. - size = 0; - iByte += 1; - } - else size = 1; - - // Copy the MIDI data to our vector. - if ( size ) { - message.bytes.assign( &packet->data[iByte], &packet->data[iByte+size] ); - if ( !continueSysex ) { - // If not a continuing sysex message, invoke the user callback function or queue the message. - if ( data->usingCallback ) { - RtMidiIn::RtMidiCallback callback = (RtMidiIn::RtMidiCallback) data->userCallback; - callback( message.timeStamp, &message.bytes, data->userData ); - } - else { - // As long as we haven't reached our queue size limit, push the message. - if ( data->queue.size < data->queue.ringSize ) { - data->queue.ring[data->queue.back++] = message; - if ( data->queue.back == data->queue.ringSize ) - data->queue.back = 0; - data->queue.size++; - } - else - std::cerr << "\nMidiInCore: message queue limit reached!!\n\n"; - } - message.bytes.clear(); - } - iByte += size; - } - } - } - packet = MIDIPacketNext(packet); - } -} -MidiInCore :: MidiInCore( const std::string clientName, unsigned int queueSizeLimit ) : MidiInApi( queueSizeLimit ) -{ - initialize( clientName ); -} +namespace rtmidi { + // A structure to hold variables related to the CoreMIDI API + // implementation. + struct CoreMidiData { + MIDIClientRef client; + MIDIPortRef port; + MIDIEndpointRef endpoint; + MIDIEndpointRef destinationId; + unsigned long long lastTime; + MIDISysexSendRequest sysexreq; + }; + + //*********************************************************************// + // API: OS-X + // Class Definitions: MidiInCore + //*********************************************************************// + + static void midiInputCallback( const MIDIPacketList *list, void *procRef, void */*srcRef*/ ) + { + MidiInApi::MidiInData *data = static_cast (procRef); + CoreMidiData *apiData = static_cast (data->apiData); + + unsigned char status; + unsigned short nBytes, iByte, size; + unsigned long long time; + + bool& continueSysex = data->continueSysex; + MidiInApi::MidiMessage& message = data->message; + + const MIDIPacket *packet = &list->packet[0]; + for ( unsigned int i=0; inumPackets; ++i ) { + + // My interpretation of the CoreMIDI documentation: all message + // types, except sysex, are complete within a packet and there may + // be several of them in a single packet. Sysex messages can be + // broken across multiple packets and PacketLists but are bundled + // alone within each packet (these packets do not contain other + // message types). If sysex messages are split across multiple + // MIDIPacketLists, they must be handled by multiple calls to this + // function. + + nBytes = packet->length; + if ( nBytes == 0 ) continue; + + // Calculate time stamp. + + if ( data->firstMessage ) { + message.timeStamp = 0.0; + data->firstMessage = false; + } + else { + time = packet->timeStamp; + if ( time == 0 ) { // this happens when receiving asynchronous sysex messages + time = AudioGetCurrentHostTime(); + } + time -= apiData->lastTime; + time = AudioConvertHostTimeToNanos( time ); + if ( !continueSysex ) + message.timeStamp = time * 0.000000001; + } + apiData->lastTime = packet->timeStamp; + if ( apiData->lastTime == 0 ) { // this happens when receiving asynchronous sysex messages + apiData->lastTime = AudioGetCurrentHostTime(); + } + //std::cout << "TimeStamp = " << packet->timeStamp << std::endl; + + iByte = 0; + if ( continueSysex ) { + // We have a continuing, segmented sysex message. + if ( !( data->ignoreFlags & 0x01 ) ) { + // If we're not ignoring sysex messages, copy the entire packet. + for ( unsigned int j=0; jdata[j] ); + } + continueSysex = packet->data[nBytes-1] != 0xF7; + + if ( !( data->ignoreFlags & 0x01 ) ) { + if ( !continueSysex ) { + // If not a continuing sysex message, invoke the user callback function or queue the message. + if ( data->usingCallback ) { + MidiCallback callback = (MidiCallback) data->userCallback; + callback( message.timeStamp, &message.bytes, data->userData ); + } + else { + // As long as we haven't reached our queue size limit, push the message. + if ( data->queue.size < data->queue.ringSize ) { + data->queue.ring[data->queue.back++] = message; + if ( data->queue.back == data->queue.ringSize ) + data->queue.back = 0; + data->queue.size++; + } + else + std::cerr << "\nMidiInCore: message queue limit reached!!\n\n"; + } + message.bytes.clear(); + } + } + } + else { + while ( iByte < nBytes ) { + size = 0; + // We are expecting that the next byte in the packet is a status byte. + status = packet->data[iByte]; + if ( !(status & 0x80) ) break; + // Determine the number of bytes in the MIDI message. + if ( status < 0xC0 ) size = 3; + else if ( status < 0xE0 ) size = 2; + else if ( status < 0xF0 ) size = 3; + else if ( status == 0xF0 ) { + // A MIDI sysex + if ( data->ignoreFlags & 0x01 ) { + size = 0; + iByte = nBytes; + } + else size = nBytes - iByte; + continueSysex = packet->data[nBytes-1] != 0xF7; + } + else if ( status == 0xF1 ) { + // A MIDI time code message + if ( data->ignoreFlags & 0x02 ) { + size = 0; + iByte += 2; + } + else size = 2; + } + else if ( status == 0xF2 ) size = 3; + else if ( status == 0xF3 ) size = 2; + else if ( status == 0xF8 && ( data->ignoreFlags & 0x02 ) ) { + // A MIDI timing tick message and we're ignoring it. + size = 0; + iByte += 1; + } + else if ( status == 0xFE && ( data->ignoreFlags & 0x04 ) ) { + // A MIDI active sensing message and we're ignoring it. + size = 0; + iByte += 1; + } + else size = 1; + + // Copy the MIDI data to our vector. + if ( size ) { + message.bytes.assign( &packet->data[iByte], &packet->data[iByte+size] ); + if ( !continueSysex ) { + // If not a continuing sysex message, invoke the user callback function or queue the message. + if ( data->usingCallback ) { + MidiCallback callback = (MidiCallback) data->userCallback; + callback( message.timeStamp, &message.bytes, data->userData ); + } + else { + // As long as we haven't reached our queue size limit, push the message. + if ( data->queue.size < data->queue.ringSize ) { + data->queue.ring[data->queue.back++] = message; + if ( data->queue.back == data->queue.ringSize ) + data->queue.back = 0; + data->queue.size++; + } + else + std::cerr << "\nMidiInCore: message queue limit reached!!\n\n"; + } + message.bytes.clear(); + } + iByte += size; + } + } + } + packet = MIDIPacketNext(packet); + } + } -MidiInCore :: ~MidiInCore( void ) -{ - // Close a connection if it exists. - closePort(); + MidiInCore :: MidiInCore( const std::string clientName, unsigned int queueSizeLimit ) : MidiInApi( queueSizeLimit ) + { + initialize( clientName ); + } - // Cleanup. - CoreMidiData *data = static_cast (apiData_); - MIDIClientDispose( data->client ); - if ( data->endpoint ) MIDIEndpointDispose( data->endpoint ); - delete data; -} + MidiInCore :: ~MidiInCore( void ) + { + // Close a connection if it exists. + closePort(); -void MidiInCore :: initialize( const std::string& clientName ) -{ - // Set up our client. - MIDIClientRef client; - OSStatus result = MIDIClientCreate( CFStringCreateWithCString( NULL, clientName.c_str(), kCFStringEncodingASCII ), NULL, NULL, &client ); - if ( result != noErr ) { - errorString_ = "MidiInCore::initialize: error creating OS-X MIDI client object."; - error( RtMidiError::DRIVER_ERROR, errorString_ ); - return; - } - - // Save our api-specific connection information. - CoreMidiData *data = (CoreMidiData *) new CoreMidiData; - data->client = client; - data->endpoint = 0; - apiData_ = (void *) data; - inputData_.apiData = (void *) data; -} + // Cleanup. + CoreMidiData *data = static_cast (apiData_); + MIDIClientDispose( data->client ); + if ( data->endpoint ) MIDIEndpointDispose( data->endpoint ); + delete data; + } -void MidiInCore :: openPort( unsigned int portNumber, const std::string portName ) -{ - if ( connected_ ) { - errorString_ = "MidiInCore::openPort: a valid connection already exists!"; - error( RtMidiError::WARNING, errorString_ ); - return; - } - - CFRunLoopRunInMode( kCFRunLoopDefaultMode, 0, false ); - unsigned int nSrc = MIDIGetNumberOfSources(); - if (nSrc < 1) { - errorString_ = "MidiInCore::openPort: no MIDI input sources found!"; - error( RtMidiError::NO_DEVICES_FOUND, errorString_ ); - return; - } - - if ( portNumber >= nSrc ) { - std::ostringstream ost; - ost << "MidiInCore::openPort: the 'portNumber' argument (" << portNumber << ") is invalid."; - errorString_ = ost.str(); - error( RtMidiError::INVALID_PARAMETER, errorString_ ); - return; - } - - MIDIPortRef port; - CoreMidiData *data = static_cast (apiData_); - OSStatus result = MIDIInputPortCreate( data->client, - CFStringCreateWithCString( NULL, portName.c_str(), kCFStringEncodingASCII ), - midiInputCallback, (void *)&inputData_, &port ); - if ( result != noErr ) { - MIDIClientDispose( data->client ); - errorString_ = "MidiInCore::openPort: error creating OS-X MIDI input port."; - error( RtMidiError::DRIVER_ERROR, errorString_ ); - return; - } - - // Get the desired input source identifier. - MIDIEndpointRef endpoint = MIDIGetSource( portNumber ); - if ( endpoint == 0 ) { - MIDIPortDispose( port ); - MIDIClientDispose( data->client ); - errorString_ = "MidiInCore::openPort: error getting MIDI input source reference."; - error( RtMidiError::DRIVER_ERROR, errorString_ ); - return; - } - - // Make the connection. - result = MIDIPortConnectSource( port, endpoint, NULL ); - if ( result != noErr ) { - MIDIPortDispose( port ); - MIDIClientDispose( data->client ); - errorString_ = "MidiInCore::openPort: error connecting OS-X MIDI input port."; - error( RtMidiError::DRIVER_ERROR, errorString_ ); - return; - } - - // Save our api-specific port information. - data->port = port; - - connected_ = true; -} + void MidiInCore :: initialize( const std::string& clientName ) + { + // Set up our client. + MIDIClientRef client; + OSStatus result = MIDIClientCreate( CFStringCreateWithCString( NULL, clientName.c_str(), kCFStringEncodingASCII ), NULL, NULL, &client ); + if ( result != noErr ) { + errorString_ = "MidiInCore::initialize: error creating OS-X MIDI client object."; + error( Error::DRIVER_ERROR, errorString_ ); + return; + } + + // Save our api-specific connection information. + CoreMidiData *data = (CoreMidiData *) new CoreMidiData; + data->client = client; + data->endpoint = 0; + apiData_ = (void *) data; + inputData_.apiData = (void *) data; + } -void MidiInCore :: openVirtualPort( const std::string portName ) -{ - CoreMidiData *data = static_cast (apiData_); - - // Create a virtual MIDI input destination. - MIDIEndpointRef endpoint; - OSStatus result = MIDIDestinationCreate( data->client, - CFStringCreateWithCString( NULL, portName.c_str(), kCFStringEncodingASCII ), - midiInputCallback, (void *)&inputData_, &endpoint ); - if ( result != noErr ) { - errorString_ = "MidiInCore::openVirtualPort: error creating virtual OS-X MIDI destination."; - error( RtMidiError::DRIVER_ERROR, errorString_ ); - return; - } - - // Save our api-specific connection information. - data->endpoint = endpoint; -} + void MidiInCore :: openPort( unsigned int portNumber, const std::string portName ) + { + if ( connected_ ) { + errorString_ = "MidiInCore::openPort: a valid connection already exists!"; + error( Error::WARNING, errorString_ ); + return; + } + + CFRunLoopRunInMode( kCFRunLoopDefaultMode, 0, false ); + unsigned int nSrc = MIDIGetNumberOfSources(); + if (nSrc < 1) { + errorString_ = "MidiInCore::openPort: no MIDI input sources found!"; + error( Error::NO_DEVICES_FOUND, errorString_ ); + return; + } + + if ( portNumber >= nSrc ) { + std::ostringstream ost; + ost << "MidiInCore::openPort: the 'portNumber' argument (" << portNumber << ") is invalid."; + errorString_ = ost.str(); + error( Error::INVALID_PARAMETER, errorString_ ); + return; + } + + MIDIPortRef port; + CoreMidiData *data = static_cast (apiData_); + OSStatus result = MIDIInputPortCreate( data->client, + CFStringCreateWithCString( NULL, portName.c_str(), kCFStringEncodingASCII ), + midiInputCallback, (void *)&inputData_, &port ); + if ( result != noErr ) { + MIDIClientDispose( data->client ); + errorString_ = "MidiInCore::openPort: error creating OS-X MIDI input port."; + error( Error::DRIVER_ERROR, errorString_ ); + return; + } + + // Get the desired input source identifier. + MIDIEndpointRef endpoint = MIDIGetSource( portNumber ); + if ( endpoint == 0 ) { + MIDIPortDispose( port ); + MIDIClientDispose( data->client ); + errorString_ = "MidiInCore::openPort: error getting MIDI input source reference."; + error( Error::DRIVER_ERROR, errorString_ ); + return; + } + + // Make the connection. + result = MIDIPortConnectSource( port, endpoint, NULL ); + if ( result != noErr ) { + MIDIPortDispose( port ); + MIDIClientDispose( data->client ); + errorString_ = "MidiInCore::openPort: error connecting OS-X MIDI input port."; + error( Error::DRIVER_ERROR, errorString_ ); + return; + } + + // Save our api-specific port information. + data->port = port; + + connected_ = true; + } -void MidiInCore :: closePort( void ) -{ - if ( connected_ ) { - CoreMidiData *data = static_cast (apiData_); - MIDIPortDispose( data->port ); - connected_ = false; - } -} + void MidiInCore :: openVirtualPort( const std::string portName ) + { + CoreMidiData *data = static_cast (apiData_); + + // Create a virtual MIDI input destination. + MIDIEndpointRef endpoint; + OSStatus result = MIDIDestinationCreate( data->client, + CFStringCreateWithCString( NULL, portName.c_str(), kCFStringEncodingASCII ), + midiInputCallback, (void *)&inputData_, &endpoint ); + if ( result != noErr ) { + errorString_ = "MidiInCore::openVirtualPort: error creating virtual OS-X MIDI destination."; + error( Error::DRIVER_ERROR, errorString_ ); + return; + } + + // Save our api-specific connection information. + data->endpoint = endpoint; + } -unsigned int MidiInCore :: getPortCount() -{ - CFRunLoopRunInMode( kCFRunLoopDefaultMode, 0, false ); - return MIDIGetNumberOfSources(); -} + void MidiInCore :: closePort( void ) + { + if ( connected_ ) { + CoreMidiData *data = static_cast (apiData_); + MIDIPortDispose( data->port ); + connected_ = false; + } + } -// This function was submitted by Douglas Casey Tucker and apparently -// derived largely from PortMidi. -CFStringRef EndpointName( MIDIEndpointRef endpoint, bool isExternal ) -{ - CFMutableStringRef result = CFStringCreateMutable( NULL, 0 ); - CFStringRef str; - - // Begin with the endpoint's name. - str = NULL; - MIDIObjectGetStringProperty( endpoint, kMIDIPropertyName, &str ); - if ( str != NULL ) { - CFStringAppend( result, str ); - CFRelease( str ); - } - - MIDIEntityRef entity = 0; - MIDIEndpointGetEntity( endpoint, &entity ); - if ( entity == 0 ) - // probably virtual - return result; - - if ( CFStringGetLength( result ) == 0 ) { - // endpoint name has zero length -- try the entity - str = NULL; - MIDIObjectGetStringProperty( entity, kMIDIPropertyName, &str ); - if ( str != NULL ) { - CFStringAppend( result, str ); - CFRelease( str ); - } - } - // now consider the device's name - MIDIDeviceRef device = 0; - MIDIEntityGetDevice( entity, &device ); - if ( device == 0 ) - return result; - - str = NULL; - MIDIObjectGetStringProperty( device, kMIDIPropertyName, &str ); - if ( CFStringGetLength( result ) == 0 ) { - CFRelease( result ); - return str; - } - if ( str != NULL ) { - // if an external device has only one entity, throw away - // the endpoint name and just use the device name - if ( isExternal && MIDIDeviceGetNumberOfEntities( device ) < 2 ) { - CFRelease( result ); - return str; - } else { - if ( CFStringGetLength( str ) == 0 ) { - CFRelease( str ); - return result; - } - // does the entity name already start with the device name? - // (some drivers do this though they shouldn't) - // if so, do not prepend - if ( CFStringCompareWithOptions( result, /* endpoint name */ - str /* device name */, - CFRangeMake(0, CFStringGetLength( str ) ), 0 ) != kCFCompareEqualTo ) { - // prepend the device name to the entity name - if ( CFStringGetLength( result ) > 0 ) - CFStringInsert( result, 0, CFSTR(" ") ); - CFStringInsert( result, 0, str ); - } - CFRelease( str ); - } - } - return result; -} + unsigned int MidiInCore :: getPortCount() + { + CFRunLoopRunInMode( kCFRunLoopDefaultMode, 0, false ); + return MIDIGetNumberOfSources(); + } -// This function was submitted by Douglas Casey Tucker and apparently -// derived largely from PortMidi. -static CFStringRef ConnectedEndpointName( MIDIEndpointRef endpoint ) -{ - CFMutableStringRef result = CFStringCreateMutable( NULL, 0 ); - CFStringRef str; - OSStatus err; - int i; - - // Does the endpoint have connections? - CFDataRef connections = NULL; - int nConnected = 0; - bool anyStrings = false; - err = MIDIObjectGetDataProperty( endpoint, kMIDIPropertyConnectionUniqueID, &connections ); - if ( connections != NULL ) { - // It has connections, follow them - // Concatenate the names of all connected devices - nConnected = CFDataGetLength( connections ) / sizeof(MIDIUniqueID); - if ( nConnected ) { - const SInt32 *pid = (const SInt32 *)(CFDataGetBytePtr(connections)); - for ( i=0; i 0 ) + CFStringInsert( result, 0, CFSTR(" ") ); + CFStringInsert( result, 0, str ); + } + CFRelease( str ); + } + } + return result; + } -std::string MidiInCore :: getPortName( unsigned int portNumber ) -{ - CFStringRef nameRef; - MIDIEndpointRef portRef; - char name[128]; - - std::string stringName; - CFRunLoopRunInMode( kCFRunLoopDefaultMode, 0, false ); - if ( portNumber >= MIDIGetNumberOfSources() ) { - std::ostringstream ost; - ost << "MidiInCore::getPortName: the 'portNumber' argument (" << portNumber << ") is invalid."; - errorString_ = ost.str(); - error( RtMidiError::WARNING, errorString_ ); - return stringName; - } - - portRef = MIDIGetSource( portNumber ); - nameRef = ConnectedEndpointName(portRef); - CFStringGetCString( nameRef, name, sizeof(name), CFStringGetSystemEncoding()); - CFRelease( nameRef ); - - return stringName = name; -} + // This function was submitted by Douglas Casey Tucker and apparently + // derived largely from PortMidi. + static CFStringRef ConnectedEndpointName( MIDIEndpointRef endpoint ) + { + CFMutableStringRef result = CFStringCreateMutable( NULL, 0 ); + CFStringRef str; + OSStatus err; + int i; + + // Does the endpoint have connections? + CFDataRef connections = NULL; + int nConnected = 0; + bool anyStrings = false; + err = MIDIObjectGetDataProperty( endpoint, kMIDIPropertyConnectionUniqueID, &connections ); + if ( connections != NULL ) { + // It has connections, follow them + // Concatenate the names of all connected devices + nConnected = CFDataGetLength( connections ) / sizeof(MIDIUniqueID); + if ( nConnected ) { + const SInt32 *pid = (const SInt32 *)(CFDataGetBytePtr(connections)); + for ( i=0; i= MIDIGetNumberOfSources() ) { + std::ostringstream ost; + ost << "MidiInCore::getPortName: the 'portNumber' argument (" << portNumber << ") is invalid."; + errorString_ = ost.str(); + error( Error::WARNING, errorString_ ); + return stringName; + } + + portRef = MIDIGetSource( portNumber ); + nameRef = ConnectedEndpointName(portRef); + CFStringGetCString( nameRef, name, sizeof(name), CFStringGetSystemEncoding()); + CFRelease( nameRef ); + + return stringName = name; + } -MidiOutCore :: MidiOutCore( const std::string clientName ) : MidiOutApi() -{ - initialize( clientName ); -} + //*********************************************************************// + // API: OS-X + // Class Definitions: MidiOutCore + //*********************************************************************// -MidiOutCore :: ~MidiOutCore( void ) -{ - // Close a connection if it exists. - closePort(); + MidiOutCore :: MidiOutCore( const std::string clientName ) : MidiOutApi() + { + initialize( clientName ); + } - // Cleanup. - CoreMidiData *data = static_cast (apiData_); - MIDIClientDispose( data->client ); - if ( data->endpoint ) MIDIEndpointDispose( data->endpoint ); - delete data; -} + MidiOutCore :: ~MidiOutCore( void ) + { + // Close a connection if it exists. + closePort(); -void MidiOutCore :: initialize( const std::string& clientName ) -{ - // Set up our client. - MIDIClientRef client; - OSStatus result = MIDIClientCreate( CFStringCreateWithCString( NULL, clientName.c_str(), kCFStringEncodingASCII ), NULL, NULL, &client ); - if ( result != noErr ) { - errorString_ = "MidiOutCore::initialize: error creating OS-X MIDI client object."; - error( RtMidiError::DRIVER_ERROR, errorString_ ); - return; - } - - // Save our api-specific connection information. - CoreMidiData *data = (CoreMidiData *) new CoreMidiData; - data->client = client; - data->endpoint = 0; - apiData_ = (void *) data; -} + // Cleanup. + CoreMidiData *data = static_cast (apiData_); + MIDIClientDispose( data->client ); + if ( data->endpoint ) MIDIEndpointDispose( data->endpoint ); + delete data; + } -unsigned int MidiOutCore :: getPortCount() -{ - CFRunLoopRunInMode( kCFRunLoopDefaultMode, 0, false ); - return MIDIGetNumberOfDestinations(); -} + void MidiOutCore :: initialize( const std::string& clientName ) + { + // Set up our client. + MIDIClientRef client; + OSStatus result = MIDIClientCreate( CFStringCreateWithCString( NULL, clientName.c_str(), kCFStringEncodingASCII ), NULL, NULL, &client ); + if ( result != noErr ) { + errorString_ = "MidiOutCore::initialize: error creating OS-X MIDI client object."; + error( Error::DRIVER_ERROR, errorString_ ); + return; + } + + // Save our api-specific connection information. + CoreMidiData *data = (CoreMidiData *) new CoreMidiData; + data->client = client; + data->endpoint = 0; + apiData_ = (void *) data; + } + + unsigned int MidiOutCore :: getPortCount() + { + CFRunLoopRunInMode( kCFRunLoopDefaultMode, 0, false ); + return MIDIGetNumberOfDestinations(); + } -std::string MidiOutCore :: getPortName( unsigned int portNumber ) -{ - CFStringRef nameRef; - MIDIEndpointRef portRef; - char name[128]; - - std::string stringName; - CFRunLoopRunInMode( kCFRunLoopDefaultMode, 0, false ); - if ( portNumber >= MIDIGetNumberOfDestinations() ) { - std::ostringstream ost; - ost << "MidiOutCore::getPortName: the 'portNumber' argument (" << portNumber << ") is invalid."; - errorString_ = ost.str(); - error( RtMidiError::WARNING, errorString_ ); - return stringName; - } - - portRef = MIDIGetDestination( portNumber ); - nameRef = ConnectedEndpointName(portRef); - CFStringGetCString( nameRef, name, sizeof(name), CFStringGetSystemEncoding()); - CFRelease( nameRef ); + std::string MidiOutCore :: getPortName( unsigned int portNumber ) + { + CFStringRef nameRef; + MIDIEndpointRef portRef; + char name[128]; + + std::string stringName; + CFRunLoopRunInMode( kCFRunLoopDefaultMode, 0, false ); + if ( portNumber >= MIDIGetNumberOfDestinations() ) { + std::ostringstream ost; + ost << "MidiOutCore::getPortName: the 'portNumber' argument (" << portNumber << ") is invalid."; + errorString_ = ost.str(); + error( Error::WARNING, errorString_ ); + return stringName; + } + + portRef = MIDIGetDestination( portNumber ); + nameRef = ConnectedEndpointName(portRef); + CFStringGetCString( nameRef, name, sizeof(name), CFStringGetSystemEncoding()); + CFRelease( nameRef ); - return stringName = name; -} + return stringName = name; + } -void MidiOutCore :: openPort( unsigned int portNumber, const std::string portName ) -{ - if ( connected_ ) { - errorString_ = "MidiOutCore::openPort: a valid connection already exists!"; - error( RtMidiError::WARNING, errorString_ ); - return; - } - - CFRunLoopRunInMode( kCFRunLoopDefaultMode, 0, false ); - unsigned int nDest = MIDIGetNumberOfDestinations(); - if (nDest < 1) { - errorString_ = "MidiOutCore::openPort: no MIDI output destinations found!"; - error( RtMidiError::NO_DEVICES_FOUND, errorString_ ); - return; - } - - if ( portNumber >= nDest ) { - std::ostringstream ost; - ost << "MidiOutCore::openPort: the 'portNumber' argument (" << portNumber << ") is invalid."; - errorString_ = ost.str(); - error( RtMidiError::INVALID_PARAMETER, errorString_ ); - return; - } - - MIDIPortRef port; - CoreMidiData *data = static_cast (apiData_); - OSStatus result = MIDIOutputPortCreate( data->client, - CFStringCreateWithCString( NULL, portName.c_str(), kCFStringEncodingASCII ), - &port ); - if ( result != noErr ) { - MIDIClientDispose( data->client ); - errorString_ = "MidiOutCore::openPort: error creating OS-X MIDI output port."; - error( RtMidiError::DRIVER_ERROR, errorString_ ); - return; - } - - // Get the desired output port identifier. - MIDIEndpointRef destination = MIDIGetDestination( portNumber ); - if ( destination == 0 ) { - MIDIPortDispose( port ); - MIDIClientDispose( data->client ); - errorString_ = "MidiOutCore::openPort: error getting MIDI output destination reference."; - error( RtMidiError::DRIVER_ERROR, errorString_ ); - return; - } - - // Save our api-specific connection information. - data->port = port; - data->destinationId = destination; - connected_ = true; -} + void MidiOutCore :: openPort( unsigned int portNumber, const std::string portName ) + { + if ( connected_ ) { + errorString_ = "MidiOutCore::openPort: a valid connection already exists!"; + error( Error::WARNING, errorString_ ); + return; + } + + CFRunLoopRunInMode( kCFRunLoopDefaultMode, 0, false ); + unsigned int nDest = MIDIGetNumberOfDestinations(); + if (nDest < 1) { + errorString_ = "MidiOutCore::openPort: no MIDI output destinations found!"; + error( Error::NO_DEVICES_FOUND, errorString_ ); + return; + } + + if ( portNumber >= nDest ) { + std::ostringstream ost; + ost << "MidiOutCore::openPort: the 'portNumber' argument (" << portNumber << ") is invalid."; + errorString_ = ost.str(); + error( Error::INVALID_PARAMETER, errorString_ ); + return; + } + + MIDIPortRef port; + CoreMidiData *data = static_cast (apiData_); + OSStatus result = MIDIOutputPortCreate( data->client, + CFStringCreateWithCString( NULL, portName.c_str(), kCFStringEncodingASCII ), + &port ); + if ( result != noErr ) { + MIDIClientDispose( data->client ); + errorString_ = "MidiOutCore::openPort: error creating OS-X MIDI output port."; + error( Error::DRIVER_ERROR, errorString_ ); + return; + } + + // Get the desired output port identifier. + MIDIEndpointRef destination = MIDIGetDestination( portNumber ); + if ( destination == 0 ) { + MIDIPortDispose( port ); + MIDIClientDispose( data->client ); + errorString_ = "MidiOutCore::openPort: error getting MIDI output destination reference."; + error( Error::DRIVER_ERROR, errorString_ ); + return; + } + + // Save our api-specific connection information. + data->port = port; + data->destinationId = destination; + connected_ = true; + } -void MidiOutCore :: closePort( void ) -{ - if ( connected_ ) { - CoreMidiData *data = static_cast (apiData_); - MIDIPortDispose( data->port ); - connected_ = false; - } -} + void MidiOutCore :: closePort( void ) + { + if ( connected_ ) { + CoreMidiData *data = static_cast (apiData_); + MIDIPortDispose( data->port ); + connected_ = false; + } + } -void MidiOutCore :: openVirtualPort( std::string portName ) -{ - CoreMidiData *data = static_cast (apiData_); - - if ( data->endpoint ) { - errorString_ = "MidiOutCore::openVirtualPort: a virtual output port already exists!"; - error( RtMidiError::WARNING, errorString_ ); - return; - } - - // Create a virtual MIDI output source. - MIDIEndpointRef endpoint; - OSStatus result = MIDISourceCreate( data->client, - CFStringCreateWithCString( NULL, portName.c_str(), kCFStringEncodingASCII ), - &endpoint ); - if ( result != noErr ) { - errorString_ = "MidiOutCore::initialize: error creating OS-X virtual MIDI source."; - error( RtMidiError::DRIVER_ERROR, errorString_ ); - return; - } - - // Save our api-specific connection information. - data->endpoint = endpoint; -} + void MidiOutCore :: openVirtualPort( std::string portName ) + { + CoreMidiData *data = static_cast (apiData_); + + if ( data->endpoint ) { + errorString_ = "MidiOutCore::openVirtualPort: a virtual output port already exists!"; + error( Error::WARNING, errorString_ ); + return; + } + + // Create a virtual MIDI output source. + MIDIEndpointRef endpoint; + OSStatus result = MIDISourceCreate( data->client, + CFStringCreateWithCString( NULL, portName.c_str(), kCFStringEncodingASCII ), + &endpoint ); + if ( result != noErr ) { + errorString_ = "MidiOutCore::initialize: error creating OS-X virtual MIDI source."; + error( Error::DRIVER_ERROR, errorString_ ); + return; + } + + // Save our api-specific connection information. + data->endpoint = endpoint; + } -// Not necessary if we don't treat sysex messages any differently than -// normal messages ... see below. -//static void sysexCompletionProc( MIDISysexSendRequest *sreq ) -//{ -// free( sreq ); -//} - -void MidiOutCore :: sendMessage( std::vector *message ) -{ - // We use the MIDISendSysex() function to asynchronously send sysex - // messages. Otherwise, we use a single CoreMidi MIDIPacket. - unsigned int nBytes = message->size(); - if ( nBytes == 0 ) { - errorString_ = "MidiOutCore::sendMessage: no data in message argument!"; - error( RtMidiError::WARNING, errorString_ ); - return; - } - - // unsigned int packetBytes, bytesLeft = nBytes; - // unsigned int messageIndex = 0; - MIDITimeStamp timeStamp = AudioGetCurrentHostTime(); - CoreMidiData *data = static_cast (apiData_); - OSStatus result; - - /* - // I don't think this code is necessary. We can send sysex - // messages through the normal mechanism. In addition, this avoids - // the problem of virtual ports not receiving sysex messages. - - if ( message->at(0) == 0xF0 ) { - - // Apple's fantastic API requires us to free the allocated data in - // the completion callback but trashes the pointer and size before - // we get a chance to free it!! This is a somewhat ugly hack - // submitted by ptarabbia that puts the sysex buffer data right at - // the end of the MIDISysexSendRequest structure. This solution - // does not require that we wait for a previous sysex buffer to be - // sent before sending a new one, which was the old way we did it. - MIDISysexSendRequest *newRequest = (MIDISysexSendRequest *) malloc(sizeof(struct MIDISysexSendRequest) + nBytes); - char * sysexBuffer = ((char *) newRequest) + sizeof(struct MIDISysexSendRequest); - - // Copy data to buffer. - for ( unsigned int i=0; iat(i); - - newRequest->destination = data->destinationId; - newRequest->data = (Byte *)sysexBuffer; - newRequest->bytesToSend = nBytes; - newRequest->complete = 0; - newRequest->completionProc = sysexCompletionProc; - newRequest->completionRefCon = newRequest; - - result = MIDISendSysex(newRequest); - if ( result != noErr ) { - free( newRequest ); - errorString_ = "MidiOutCore::sendMessage: error sending MIDI to virtual destinations."; - error( RtMidiError::WARNING, errorString_ ); - return; - } - return; - } - else if ( nBytes > 3 ) { - errorString_ = "MidiOutCore::sendMessage: message format problem ... not sysex but > 3 bytes?"; - error( RtMidiError::WARNING, errorString_ ); - return; - } - */ - - MIDIPacketList packetList; - MIDIPacket *packet = MIDIPacketListInit( &packetList ); - packet = MIDIPacketListAdd( &packetList, sizeof(packetList), packet, timeStamp, nBytes, (const Byte *) &message->at( 0 ) ); - if ( !packet ) { - errorString_ = "MidiOutCore::sendMessage: could not allocate packet list"; - error( RtMidiError::DRIVER_ERROR, errorString_ ); - return; - } - - // Send to any destinations that may have connected to us. - if ( data->endpoint ) { - result = MIDIReceived( data->endpoint, &packetList ); - if ( result != noErr ) { - errorString_ = "MidiOutCore::sendMessage: error sending MIDI to virtual destinations."; - error( RtMidiError::WARNING, errorString_ ); - } - } - - // And send to an explicit destination port if we're connected. - if ( connected_ ) { - result = MIDISend( data->port, data->destinationId, &packetList ); - if ( result != noErr ) { - errorString_ = "MidiOutCore::sendMessage: error sending MIDI message to port."; - error( RtMidiError::WARNING, errorString_ ); - } - } + // Not necessary if we don't treat sysex messages any differently than + // normal messages ... see below. + //static void sysexCompletionProc( MIDISysexSendRequest *sreq ) + //{ + // free( sreq ); + //} + + void MidiOutCore :: sendMessage( std::vector *message ) + { + // We use the MIDISendSysex() function to asynchronously send sysex + // messages. Otherwise, we use a single CoreMidi MIDIPacket. + unsigned int nBytes = message->size(); + if ( nBytes == 0 ) { + errorString_ = "MidiOutCore::sendMessage: no data in message argument!"; + error( Error::WARNING, errorString_ ); + return; + } + + // unsigned int packetBytes, bytesLeft = nBytes; + // unsigned int messageIndex = 0; + MIDITimeStamp timeStamp = AudioGetCurrentHostTime(); + CoreMidiData *data = static_cast (apiData_); + OSStatus result; + + /* + // I don't think this code is necessary. We can send sysex + // messages through the normal mechanism. In addition, this avoids + // the problem of virtual ports not receiving sysex messages. + + if ( message->at(0) == 0xF0 ) { + + // Apple's fantastic API requires us to free the allocated data in + // the completion callback but trashes the pointer and size before + // we get a chance to free it!! This is a somewhat ugly hack + // submitted by ptarabbia that puts the sysex buffer data right at + // the end of the MIDISysexSendRequest structure. This solution + // does not require that we wait for a previous sysex buffer to be + // sent before sending a new one, which was the old way we did it. + MIDISysexSendRequest *newRequest = (MIDISysexSendRequest *) malloc(sizeof(struct MIDISysexSendRequest) + nBytes); + char * sysexBuffer = ((char *) newRequest) + sizeof(struct MIDISysexSendRequest); + + // Copy data to buffer. + for ( unsigned int i=0; iat(i); + + newRequest->destination = data->destinationId; + newRequest->data = (Byte *)sysexBuffer; + newRequest->bytesToSend = nBytes; + newRequest->complete = 0; + newRequest->completionProc = sysexCompletionProc; + newRequest->completionRefCon = newRequest; + + result = MIDISendSysex(newRequest); + if ( result != noErr ) { + free( newRequest ); + errorString_ = "MidiOutCore::sendMessage: error sending MIDI to virtual destinations."; + error( Error::WARNING, errorString_ ); + return; + } + return; + } + else if ( nBytes > 3 ) { + errorString_ = "MidiOutCore::sendMessage: message format problem ... not sysex but > 3 bytes?"; + error( Error::WARNING, errorString_ ); + return; + } + */ + + MIDIPacketList packetList; + MIDIPacket *packet = MIDIPacketListInit( &packetList ); + packet = MIDIPacketListAdd( &packetList, sizeof(packetList), packet, timeStamp, nBytes, (const Byte *) &message->at( 0 ) ); + if ( !packet ) { + errorString_ = "MidiOutCore::sendMessage: could not allocate packet list"; + error( Error::DRIVER_ERROR, errorString_ ); + return; + } + + // Send to any destinations that may have connected to us. + if ( data->endpoint ) { + result = MIDIReceived( data->endpoint, &packetList ); + if ( result != noErr ) { + errorString_ = "MidiOutCore::sendMessage: error sending MIDI to virtual destinations."; + error( Error::WARNING, errorString_ ); + } + } + + // And send to an explicit destination port if we're connected. + if ( connected_ ) { + result = MIDISend( data->port, data->destinationId, &packetList ); + if ( result != noErr ) { + errorString_ = "MidiOutCore::sendMessage: error sending MIDI message to port."; + error( Error::WARNING, errorString_ ); + } + } + } } - #endif // __MACOSX_CORE__ -//*********************************************************************// -// API: LINUX ALSA SEQUENCER -//*********************************************************************// + //*********************************************************************// + // API: LINUX ALSA SEQUENCER + //*********************************************************************// -// API information found at: -// - http://www.alsa-project.org/documentation.php#Library + // API information found at: + // - http://www.alsa-project.org/documentation.php#Library #if defined(__LINUX_ALSA__) -// The ALSA Sequencer API is based on the use of a callback function for -// MIDI input. -// -// Thanks to Pedro Lopez-Cabanillas for help with the ALSA sequencer -// time stamps and other assorted fixes!!! + // The ALSA Sequencer API is based on the use of a callback function for + // MIDI input. + // + // Thanks to Pedro Lopez-Cabanillas for help with the ALSA sequencer + // time stamps and other assorted fixes!!! -// If you don't need timestamping for incoming MIDI events, define the -// preprocessor definition AVOID_TIMESTAMPING to save resources -// associated with the ALSA sequencer queues. + // If you don't need timestamping for incoming MIDI events, define the + // preprocessor definition AVOID_TIMESTAMPING to save resources + // associated with the ALSA sequencer queues. #include #include -// ALSA header file. + // ALSA header file. #include -// A structure to hold variables related to the ALSA API -// implementation. -struct AlsaMidiData { - snd_seq_t *seq; - unsigned int portNum; - int vport; - snd_seq_port_subscribe_t *subscription; - snd_midi_event_t *coder; - unsigned int bufferSize; - unsigned char *buffer; - pthread_t thread; - pthread_t dummy_thread_id; - unsigned long long lastTime; - int queue_id; // an input queue is needed to get timestamped events - int trigger_fds[2]; -}; +namespace rtmidi { + // A structure to hold variables related to the ALSA API + // implementation. + struct AlsaMidiData { + snd_seq_t *seq; + unsigned int portNum; + int vport; + snd_seq_port_subscribe_t *subscription; + snd_midi_event_t *coder; + unsigned int bufferSize; + unsigned char *buffer; + pthread_t thread; + pthread_t dummy_thread_id; + unsigned long long lastTime; + int queue_id; // an input queue is needed to get timestamped events + int trigger_fds[2]; + }; #define PORT_TYPE( pinfo, bits ) ((snd_seq_port_info_get_capability(pinfo) & (bits)) == (bits)) -//*********************************************************************// -// API: LINUX ALSA -// Class Definitions: MidiInAlsa -//*********************************************************************// - -static void *alsaMidiHandler( void *ptr ) -{ - MidiInApi::RtMidiInData *data = static_cast (ptr); - AlsaMidiData *apiData = static_cast (data->apiData); - - long nBytes; - unsigned long long time, lastTime; - bool continueSysex = false; - bool doDecode = false; - MidiInApi::MidiMessage message; - int poll_fd_count; - struct pollfd *poll_fds; - - snd_seq_event_t *ev; - int result; - apiData->bufferSize = 32; - result = snd_midi_event_new( 0, &apiData->coder ); - if ( result < 0 ) { - data->doInput = false; - std::cerr << "\nMidiInAlsa::alsaMidiHandler: error initializing MIDI event parser!\n\n"; - return 0; - } - unsigned char *buffer = (unsigned char *) malloc( apiData->bufferSize ); - if ( buffer == NULL ) { - data->doInput = false; - snd_midi_event_free( apiData->coder ); - apiData->coder = 0; - std::cerr << "\nMidiInAlsa::alsaMidiHandler: error initializing buffer memory!\n\n"; - return 0; - } - snd_midi_event_init( apiData->coder ); - snd_midi_event_no_status( apiData->coder, 1 ); // suppress running status messages - - poll_fd_count = snd_seq_poll_descriptors_count( apiData->seq, POLLIN ) + 1; - poll_fds = (struct pollfd*)alloca( poll_fd_count * sizeof( struct pollfd )); - snd_seq_poll_descriptors( apiData->seq, poll_fds + 1, poll_fd_count - 1, POLLIN ); - poll_fds[0].fd = apiData->trigger_fds[0]; - poll_fds[0].events = POLLIN; - - while ( data->doInput ) { - - if ( snd_seq_event_input_pending( apiData->seq, 1 ) == 0 ) { - // No data pending - if ( poll( poll_fds, poll_fd_count, -1) >= 0 ) { - if ( poll_fds[0].revents & POLLIN ) { - bool dummy; - int res = read( poll_fds[0].fd, &dummy, sizeof(dummy) ); - (void) res; - } - } - continue; - } - - // If here, there should be data. - result = snd_seq_event_input( apiData->seq, &ev ); - if ( result == -ENOSPC ) { - std::cerr << "\nMidiInAlsa::alsaMidiHandler: MIDI input buffer overrun!\n\n"; - continue; - } - else if ( result <= 0 ) { - std::cerr << "\nMidiInAlsa::alsaMidiHandler: unknown MIDI input error!\n"; - perror("System reports"); - continue; - } - - // This is a bit weird, but we now have to decode an ALSA MIDI - // event (back) into MIDI bytes. We'll ignore non-MIDI types. - if ( !continueSysex ) message.bytes.clear(); - - doDecode = false; - switch ( ev->type ) { - - case SND_SEQ_EVENT_PORT_SUBSCRIBED: + //*********************************************************************// + // API: LINUX ALSA + // Class Definitions: MidiInAlsa + //*********************************************************************// + + static void *alsaMidiHandler( void *ptr ) + { + MidiInApi::MidiInData *data = static_cast (ptr); + AlsaMidiData *apiData = static_cast (data->apiData); + + long nBytes; + unsigned long long time, lastTime; + bool continueSysex = false; + bool doDecode = false; + MidiInApi::MidiMessage message; + int poll_fd_count; + struct pollfd *poll_fds; + + snd_seq_event_t *ev; + int result; + apiData->bufferSize = 32; + result = snd_midi_event_new( 0, &apiData->coder ); + if ( result < 0 ) { + data->doInput = false; + std::cerr << "\nMidiInAlsa::alsaMidiHandler: error initializing MIDI event parser!\n\n"; + return 0; + } + unsigned char *buffer = (unsigned char *) malloc( apiData->bufferSize ); + if ( buffer == NULL ) { + data->doInput = false; + snd_midi_event_free( apiData->coder ); + apiData->coder = 0; + std::cerr << "\nMidiInAlsa::alsaMidiHandler: error initializing buffer memory!\n\n"; + return 0; + } + snd_midi_event_init( apiData->coder ); + snd_midi_event_no_status( apiData->coder, 1 ); // suppress running status messages + + poll_fd_count = snd_seq_poll_descriptors_count( apiData->seq, POLLIN ) + 1; + poll_fds = (struct pollfd*)alloca( poll_fd_count * sizeof( struct pollfd )); + snd_seq_poll_descriptors( apiData->seq, poll_fds + 1, poll_fd_count - 1, POLLIN ); + poll_fds[0].fd = apiData->trigger_fds[0]; + poll_fds[0].events = POLLIN; + + while ( data->doInput ) { + + if ( snd_seq_event_input_pending( apiData->seq, 1 ) == 0 ) { + // No data pending + if ( poll( poll_fds, poll_fd_count, -1) >= 0 ) { + if ( poll_fds[0].revents & POLLIN ) { + bool dummy; + int res = read( poll_fds[0].fd, &dummy, sizeof(dummy) ); + (void) res; + } + } + continue; + } + + // If here, there should be data. + result = snd_seq_event_input( apiData->seq, &ev ); + if ( result == -ENOSPC ) { + std::cerr << "\nMidiInAlsa::alsaMidiHandler: MIDI input buffer overrun!\n\n"; + continue; + } + else if ( result <= 0 ) { + std::cerr << "\nMidiInAlsa::alsaMidiHandler: unknown MIDI input error!\n"; + perror("System reports"); + continue; + } + + // This is a bit weird, but we now have to decode an ALSA MIDI + // event (back) into MIDI bytes. We'll ignore non-MIDI types. + if ( !continueSysex ) message.bytes.clear(); + + doDecode = false; + switch ( ev->type ) { + + case SND_SEQ_EVENT_PORT_SUBSCRIBED: #if defined(__RTMIDI_DEBUG__) - std::cout << "MidiInAlsa::alsaMidiHandler: port connection made!\n"; + std::cout << "MidiInAlsa::alsaMidiHandler: port connection made!\n"; #endif - break; + break; - case SND_SEQ_EVENT_PORT_UNSUBSCRIBED: + case SND_SEQ_EVENT_PORT_UNSUBSCRIBED: #if defined(__RTMIDI_DEBUG__) - std::cerr << "MidiInAlsa::alsaMidiHandler: port connection has closed!\n"; - std::cout << "sender = " << (int) ev->data.connect.sender.client << ":" - << (int) ev->data.connect.sender.port - << ", dest = " << (int) ev->data.connect.dest.client << ":" - << (int) ev->data.connect.dest.port - << std::endl; + std::cerr << "MidiInAlsa::alsaMidiHandler: port connection has closed!\n"; + std::cout << "sender = " << (int) ev->data.connect.sender.client << ":" + << (int) ev->data.connect.sender.port + << ", dest = " << (int) ev->data.connect.dest.client << ":" + << (int) ev->data.connect.dest.port + << std::endl; #endif - break; - - case SND_SEQ_EVENT_QFRAME: // MIDI time code - if ( !( data->ignoreFlags & 0x02 ) ) doDecode = true; - break; - - case SND_SEQ_EVENT_TICK: // 0xF9 ... MIDI timing tick - if ( !( data->ignoreFlags & 0x02 ) ) doDecode = true; - break; - - case SND_SEQ_EVENT_CLOCK: // 0xF8 ... MIDI timing (clock) tick - if ( !( data->ignoreFlags & 0x02 ) ) doDecode = true; - break; - - case SND_SEQ_EVENT_SENSING: // Active sensing - if ( !( data->ignoreFlags & 0x04 ) ) doDecode = true; - break; - - case SND_SEQ_EVENT_SYSEX: - if ( (data->ignoreFlags & 0x01) ) break; - if ( ev->data.ext.len > apiData->bufferSize ) { - apiData->bufferSize = ev->data.ext.len; - free( buffer ); - buffer = (unsigned char *) malloc( apiData->bufferSize ); - if ( buffer == NULL ) { - data->doInput = false; - std::cerr << "\nMidiInAlsa::alsaMidiHandler: error resizing buffer memory!\n\n"; - break; - } - } - - default: - doDecode = true; - } - - if ( doDecode ) { - - nBytes = snd_midi_event_decode( apiData->coder, buffer, apiData->bufferSize, ev ); - if ( nBytes > 0 ) { - // The ALSA sequencer has a maximum buffer size for MIDI sysex - // events of 256 bytes. If a device sends sysex messages larger - // than this, they are segmented into 256 byte chunks. So, - // we'll watch for this and concatenate sysex chunks into a - // single sysex message if necessary. - if ( !continueSysex ) - message.bytes.assign( buffer, &buffer[nBytes] ); - else - message.bytes.insert( message.bytes.end(), buffer, &buffer[nBytes] ); - - continueSysex = ( ( ev->type == SND_SEQ_EVENT_SYSEX ) && ( message.bytes.back() != 0xF7 ) ); - if ( !continueSysex ) { - - // Calculate the time stamp: - message.timeStamp = 0.0; - - // Method 1: Use the system time. - //(void)gettimeofday(&tv, (struct timezone *)NULL); - //time = (tv.tv_sec * 1000000) + tv.tv_usec; - - // Method 2: Use the ALSA sequencer event time data. - // (thanks to Pedro Lopez-Cabanillas!). - time = ( ev->time.time.tv_sec * 1000000 ) + ( ev->time.time.tv_nsec/1000 ); - lastTime = time; - time -= apiData->lastTime; - apiData->lastTime = lastTime; - if ( data->firstMessage == true ) - data->firstMessage = false; - else - message.timeStamp = time * 0.000001; - } - else { + break; + + case SND_SEQ_EVENT_QFRAME: // MIDI time code + if ( !( data->ignoreFlags & 0x02 ) ) doDecode = true; + break; + + case SND_SEQ_EVENT_TICK: // 0xF9 ... MIDI timing tick + if ( !( data->ignoreFlags & 0x02 ) ) doDecode = true; + break; + + case SND_SEQ_EVENT_CLOCK: // 0xF8 ... MIDI timing (clock) tick + if ( !( data->ignoreFlags & 0x02 ) ) doDecode = true; + break; + + case SND_SEQ_EVENT_SENSING: // Active sensing + if ( !( data->ignoreFlags & 0x04 ) ) doDecode = true; + break; + + case SND_SEQ_EVENT_SYSEX: + if ( (data->ignoreFlags & 0x01) ) break; + if ( ev->data.ext.len > apiData->bufferSize ) { + apiData->bufferSize = ev->data.ext.len; + free( buffer ); + buffer = (unsigned char *) malloc( apiData->bufferSize ); + if ( buffer == NULL ) { + data->doInput = false; + std::cerr << "\nMidiInAlsa::alsaMidiHandler: error resizing buffer memory!\n\n"; + break; + } + } + + default: + doDecode = true; + } + + if ( doDecode ) { + + nBytes = snd_midi_event_decode( apiData->coder, buffer, apiData->bufferSize, ev ); + if ( nBytes > 0 ) { + // The ALSA sequencer has a maximum buffer size for MIDI sysex + // events of 256 bytes. If a device sends sysex messages larger + // than this, they are segmented into 256 byte chunks. So, + // we'll watch for this and concatenate sysex chunks into a + // single sysex message if necessary. + if ( !continueSysex ) + message.bytes.assign( buffer, &buffer[nBytes] ); + else + message.bytes.insert( message.bytes.end(), buffer, &buffer[nBytes] ); + + continueSysex = ( ( ev->type == SND_SEQ_EVENT_SYSEX ) && ( message.bytes.back() != 0xF7 ) ); + if ( !continueSysex ) { + + // Calculate the time stamp: + message.timeStamp = 0.0; + + // Method 1: Use the system time. + //(void)gettimeofday(&tv, (struct timezone *)NULL); + //time = (tv.tv_sec * 1000000) + tv.tv_usec; + + // Method 2: Use the ALSA sequencer event time data. + // (thanks to Pedro Lopez-Cabanillas!). + time = ( ev->time.time.tv_sec * 1000000 ) + ( ev->time.time.tv_nsec/1000 ); + lastTime = time; + time -= apiData->lastTime; + apiData->lastTime = lastTime; + if ( data->firstMessage == true ) + data->firstMessage = false; + else + message.timeStamp = time * 0.000001; + } + else { #if defined(__RTMIDI_DEBUG__) - std::cerr << "\nMidiInAlsa::alsaMidiHandler: event parsing error or not a MIDI event!\n\n"; + std::cerr << "\nMidiInAlsa::alsaMidiHandler: event parsing error or not a MIDI event!\n\n"; #endif - } - } - } - - snd_seq_free_event( ev ); - if ( message.bytes.size() == 0 || continueSysex ) continue; - - if ( data->usingCallback ) { - RtMidiIn::RtMidiCallback callback = (RtMidiIn::RtMidiCallback) data->userCallback; - callback( message.timeStamp, &message.bytes, data->userData ); - } - else { - // As long as we haven't reached our queue size limit, push the message. - if ( data->queue.size < data->queue.ringSize ) { - data->queue.ring[data->queue.back++] = message; - if ( data->queue.back == data->queue.ringSize ) - data->queue.back = 0; - data->queue.size++; - } - else - std::cerr << "\nMidiInAlsa: message queue limit reached!!\n\n"; - } - } - - if ( buffer ) free( buffer ); - snd_midi_event_free( apiData->coder ); - apiData->coder = 0; - apiData->thread = apiData->dummy_thread_id; - return 0; -} + } + } + } + + snd_seq_free_event( ev ); + if ( message.bytes.size() == 0 || continueSysex ) continue; + + if ( data->usingCallback ) { + MidiCallback callback = (MidiCallback) data->userCallback; + callback( message.timeStamp, &message.bytes, data->userData ); + } + else { + // As long as we haven't reached our queue size limit, push the message. + if ( data->queue.size < data->queue.ringSize ) { + data->queue.ring[data->queue.back++] = message; + if ( data->queue.back == data->queue.ringSize ) + data->queue.back = 0; + data->queue.size++; + } + else + std::cerr << "\nMidiInAlsa: message queue limit reached!!\n\n"; + } + } + + if ( buffer ) free( buffer ); + snd_midi_event_free( apiData->coder ); + apiData->coder = 0; + apiData->thread = apiData->dummy_thread_id; + return 0; + } -MidiInAlsa :: MidiInAlsa( const std::string clientName, unsigned int queueSizeLimit ) : MidiInApi( queueSizeLimit ) -{ - initialize( clientName ); -} + MidiInAlsa :: MidiInAlsa( const std::string clientName, unsigned int queueSizeLimit ) : MidiInApi( queueSizeLimit ) + { + initialize( clientName ); + } -MidiInAlsa :: ~MidiInAlsa() -{ - // Close a connection if it exists. - closePort(); - - // Shutdown the input thread. - AlsaMidiData *data = static_cast (apiData_); - if ( inputData_.doInput ) { - inputData_.doInput = false; - int res = write( data->trigger_fds[1], &inputData_.doInput, sizeof(inputData_.doInput) ); - (void) res; - if ( !pthread_equal(data->thread, data->dummy_thread_id) ) - pthread_join( data->thread, NULL ); - } - - // Cleanup. - close ( data->trigger_fds[0] ); - close ( data->trigger_fds[1] ); - if ( data->vport >= 0 ) snd_seq_delete_port( data->seq, data->vport ); + MidiInAlsa :: ~MidiInAlsa() + { + // Close a connection if it exists. + closePort(); + + // Shutdown the input thread. + AlsaMidiData *data = static_cast (apiData_); + if ( inputData_.doInput ) { + inputData_.doInput = false; + int res = write( data->trigger_fds[1], &inputData_.doInput, sizeof(inputData_.doInput) ); + (void) res; + if ( !pthread_equal(data->thread, data->dummy_thread_id) ) + pthread_join( data->thread, NULL ); + } + + // Cleanup. + close ( data->trigger_fds[0] ); + close ( data->trigger_fds[1] ); + if ( data->vport >= 0 ) snd_seq_delete_port( data->seq, data->vport ); #ifndef AVOID_TIMESTAMPING - snd_seq_free_queue( data->seq, data->queue_id ); + snd_seq_free_queue( data->seq, data->queue_id ); #endif - snd_seq_close( data->seq ); - delete data; -} + snd_seq_close( data->seq ); + delete data; + } -void MidiInAlsa :: initialize( const std::string& clientName ) -{ - // Set up the ALSA sequencer client. - snd_seq_t *seq; - int result = snd_seq_open(&seq, "default", SND_SEQ_OPEN_DUPLEX, SND_SEQ_NONBLOCK); - if ( result < 0 ) { - errorString_ = "MidiInAlsa::initialize: error creating ALSA sequencer client object."; - error( RtMidiError::DRIVER_ERROR, errorString_ ); - return; - } - - // Set client name. - snd_seq_set_client_name( seq, clientName.c_str() ); - - // Save our api-specific connection information. - AlsaMidiData *data = (AlsaMidiData *) new AlsaMidiData; - data->seq = seq; - data->portNum = -1; - data->vport = -1; - data->subscription = 0; - data->dummy_thread_id = pthread_self(); - data->thread = data->dummy_thread_id; - data->trigger_fds[0] = -1; - data->trigger_fds[1] = -1; - apiData_ = (void *) data; - inputData_.apiData = (void *) data; - - if ( pipe(data->trigger_fds) == -1 ) { - errorString_ = "MidiInAlsa::initialize: error creating pipe objects."; - error( RtMidiError::DRIVER_ERROR, errorString_ ); - return; - } - - // Create the input queue + void MidiInAlsa :: initialize( const std::string& clientName ) + { + // Set up the ALSA sequencer client. + snd_seq_t *seq; + int result = snd_seq_open(&seq, "default", SND_SEQ_OPEN_DUPLEX, SND_SEQ_NONBLOCK); + if ( result < 0 ) { + errorString_ = "MidiInAlsa::initialize: error creating ALSA sequencer client object."; + error( Error::DRIVER_ERROR, errorString_ ); + return; + } + + // Set client name. + snd_seq_set_client_name( seq, clientName.c_str() ); + + // Save our api-specific connection information. + AlsaMidiData *data = (AlsaMidiData *) new AlsaMidiData; + data->seq = seq; + data->portNum = -1; + data->vport = -1; + data->subscription = 0; + data->dummy_thread_id = pthread_self(); + data->thread = data->dummy_thread_id; + data->trigger_fds[0] = -1; + data->trigger_fds[1] = -1; + apiData_ = (void *) data; + inputData_.apiData = (void *) data; + + if ( pipe(data->trigger_fds) == -1 ) { + errorString_ = "MidiInAlsa::initialize: error creating pipe objects."; + error( Error::DRIVER_ERROR, errorString_ ); + return; + } + + // Create the input queue #ifndef AVOID_TIMESTAMPING - data->queue_id = snd_seq_alloc_named_queue(seq, "RtMidi Queue"); - // Set arbitrary tempo (mm=100) and resolution (240) - snd_seq_queue_tempo_t *qtempo; - snd_seq_queue_tempo_alloca(&qtempo); - snd_seq_queue_tempo_set_tempo(qtempo, 600000); - snd_seq_queue_tempo_set_ppq(qtempo, 240); - snd_seq_set_queue_tempo(data->seq, data->queue_id, qtempo); - snd_seq_drain_output(data->seq); + data->queue_id = snd_seq_alloc_named_queue(seq, "Midi Queue"); + // Set arbitrary tempo (mm=100) and resolution (240) + snd_seq_queue_tempo_t *qtempo; + snd_seq_queue_tempo_alloca(&qtempo); + snd_seq_queue_tempo_set_tempo(qtempo, 600000); + snd_seq_queue_tempo_set_ppq(qtempo, 240); + snd_seq_set_queue_tempo(data->seq, data->queue_id, qtempo); + snd_seq_drain_output(data->seq); #endif -} + } -// This function is used to count or get the pinfo structure for a given port number. -unsigned int portInfo( snd_seq_t *seq, snd_seq_port_info_t *pinfo, unsigned int type, int portNumber ) -{ - snd_seq_client_info_t *cinfo; - int client; - int count = 0; - snd_seq_client_info_alloca( &cinfo ); - - snd_seq_client_info_set_client( cinfo, -1 ); - while ( snd_seq_query_next_client( seq, cinfo ) >= 0 ) { - client = snd_seq_client_info_get_client( cinfo ); - if ( client == 0 ) continue; - // Reset query info - snd_seq_port_info_set_client( pinfo, client ); - snd_seq_port_info_set_port( pinfo, -1 ); - while ( snd_seq_query_next_port( seq, pinfo ) >= 0 ) { - unsigned int atyp = snd_seq_port_info_get_type( pinfo ); - if ( ( atyp & SND_SEQ_PORT_TYPE_MIDI_GENERIC ) == 0 ) continue; - unsigned int caps = snd_seq_port_info_get_capability( pinfo ); - if ( ( caps & type ) != type ) continue; - if ( count == portNumber ) return 1; - ++count; - } - } - - // If a negative portNumber was used, return the port count. - if ( portNumber < 0 ) return count; - return 0; -} + // This function is used to count or get the pinfo structure for a given port number. + unsigned int portInfo( snd_seq_t *seq, snd_seq_port_info_t *pinfo, unsigned int type, int portNumber ) + { + snd_seq_client_info_t *cinfo; + int client; + int count = 0; + snd_seq_client_info_alloca( &cinfo ); + + snd_seq_client_info_set_client( cinfo, -1 ); + while ( snd_seq_query_next_client( seq, cinfo ) >= 0 ) { + client = snd_seq_client_info_get_client( cinfo ); + if ( client == 0 ) continue; + // Reset query info + snd_seq_port_info_set_client( pinfo, client ); + snd_seq_port_info_set_port( pinfo, -1 ); + while ( snd_seq_query_next_port( seq, pinfo ) >= 0 ) { + unsigned int atyp = snd_seq_port_info_get_type( pinfo ); + if ( ( atyp & SND_SEQ_PORT_TYPE_MIDI_GENERIC ) == 0 ) continue; + unsigned int caps = snd_seq_port_info_get_capability( pinfo ); + if ( ( caps & type ) != type ) continue; + if ( count == portNumber ) return 1; + ++count; + } + } + + // If a negative portNumber was used, return the port count. + if ( portNumber < 0 ) return count; + return 0; + } -unsigned int MidiInAlsa :: getPortCount() -{ - snd_seq_port_info_t *pinfo; - snd_seq_port_info_alloca( &pinfo ); + unsigned int MidiInAlsa :: getPortCount() + { + snd_seq_port_info_t *pinfo; + snd_seq_port_info_alloca( &pinfo ); - AlsaMidiData *data = static_cast (apiData_); - return portInfo( data->seq, pinfo, SND_SEQ_PORT_CAP_READ|SND_SEQ_PORT_CAP_SUBS_READ, -1 ); -} + AlsaMidiData *data = static_cast (apiData_); + return portInfo( data->seq, pinfo, SND_SEQ_PORT_CAP_READ|SND_SEQ_PORT_CAP_SUBS_READ, -1 ); + } -std::string MidiInAlsa :: getPortName( unsigned int portNumber ) -{ - snd_seq_client_info_t *cinfo; - snd_seq_port_info_t *pinfo; - snd_seq_client_info_alloca( &cinfo ); - snd_seq_port_info_alloca( &pinfo ); - - std::string stringName; - AlsaMidiData *data = static_cast (apiData_); - if ( portInfo( data->seq, pinfo, SND_SEQ_PORT_CAP_READ|SND_SEQ_PORT_CAP_SUBS_READ, (int) portNumber ) ) { - int cnum = snd_seq_port_info_get_client( pinfo ); - snd_seq_get_any_client_info( data->seq, cnum, cinfo ); - std::ostringstream os; - os << snd_seq_client_info_get_name( cinfo ); - os << " "; // These lines added to make sure devices are listed - os << snd_seq_port_info_get_client( pinfo ); // with full portnames added to ensure individual device names - os << ":"; - os << snd_seq_port_info_get_port( pinfo ); - stringName = os.str(); - return stringName; - } - - // If we get here, we didn't find a match. - errorString_ = "MidiInAlsa::getPortName: error looking for port name!"; - error( RtMidiError::WARNING, errorString_ ); - return stringName; -} + std::string MidiInAlsa :: getPortName( unsigned int portNumber ) + { + snd_seq_client_info_t *cinfo; + snd_seq_port_info_t *pinfo; + snd_seq_client_info_alloca( &cinfo ); + snd_seq_port_info_alloca( &pinfo ); + + std::string stringName; + AlsaMidiData *data = static_cast (apiData_); + if ( portInfo( data->seq, pinfo, SND_SEQ_PORT_CAP_READ|SND_SEQ_PORT_CAP_SUBS_READ, (int) portNumber ) ) { + int cnum = snd_seq_port_info_get_client( pinfo ); + snd_seq_get_any_client_info( data->seq, cnum, cinfo ); + std::ostringstream os; + os << snd_seq_client_info_get_name( cinfo ); + os << " "; // These lines added to make sure devices are listed + os << snd_seq_port_info_get_client( pinfo ); // with full portnames added to ensure individual device names + os << ":"; + os << snd_seq_port_info_get_port( pinfo ); + stringName = os.str(); + return stringName; + } + + // If we get here, we didn't find a match. + errorString_ = "MidiInAlsa::getPortName: error looking for port name!"; + error( Error::WARNING, errorString_ ); + return stringName; + } -void MidiInAlsa :: openPort( unsigned int portNumber, const std::string portName ) -{ - if ( connected_ ) { - errorString_ = "MidiInAlsa::openPort: a valid connection already exists!"; - error( RtMidiError::WARNING, errorString_ ); - return; - } - - unsigned int nSrc = this->getPortCount(); - if ( nSrc < 1 ) { - errorString_ = "MidiInAlsa::openPort: no MIDI input sources found!"; - error( RtMidiError::NO_DEVICES_FOUND, errorString_ ); - return; - } - - snd_seq_port_info_t *src_pinfo; - snd_seq_port_info_alloca( &src_pinfo ); - AlsaMidiData *data = static_cast (apiData_); - if ( portInfo( data->seq, src_pinfo, SND_SEQ_PORT_CAP_READ|SND_SEQ_PORT_CAP_SUBS_READ, (int) portNumber ) == 0 ) { - std::ostringstream ost; - ost << "MidiInAlsa::openPort: the 'portNumber' argument (" << portNumber << ") is invalid."; - errorString_ = ost.str(); - error( RtMidiError::INVALID_PARAMETER, errorString_ ); - return; - } - - snd_seq_addr_t sender, receiver; - sender.client = snd_seq_port_info_get_client( src_pinfo ); - sender.port = snd_seq_port_info_get_port( src_pinfo ); - - snd_seq_port_info_t *pinfo; - snd_seq_port_info_alloca( &pinfo ); - if ( data->vport < 0 ) { - snd_seq_port_info_set_client( pinfo, 0 ); - snd_seq_port_info_set_port( pinfo, 0 ); - snd_seq_port_info_set_capability( pinfo, - SND_SEQ_PORT_CAP_WRITE | - SND_SEQ_PORT_CAP_SUBS_WRITE ); - snd_seq_port_info_set_type( pinfo, - SND_SEQ_PORT_TYPE_MIDI_GENERIC | - SND_SEQ_PORT_TYPE_APPLICATION ); - snd_seq_port_info_set_midi_channels(pinfo, 16); + void MidiInAlsa :: openPort( unsigned int portNumber, const std::string portName ) + { + if ( connected_ ) { + errorString_ = "MidiInAlsa::openPort: a valid connection already exists!"; + error( Error::WARNING, errorString_ ); + return; + } + + unsigned int nSrc = this->getPortCount(); + if ( nSrc < 1 ) { + errorString_ = "MidiInAlsa::openPort: no MIDI input sources found!"; + error( Error::NO_DEVICES_FOUND, errorString_ ); + return; + } + + snd_seq_port_info_t *src_pinfo; + snd_seq_port_info_alloca( &src_pinfo ); + AlsaMidiData *data = static_cast (apiData_); + if ( portInfo( data->seq, src_pinfo, SND_SEQ_PORT_CAP_READ|SND_SEQ_PORT_CAP_SUBS_READ, (int) portNumber ) == 0 ) { + std::ostringstream ost; + ost << "MidiInAlsa::openPort: the 'portNumber' argument (" << portNumber << ") is invalid."; + errorString_ = ost.str(); + error( Error::INVALID_PARAMETER, errorString_ ); + return; + } + + snd_seq_addr_t sender, receiver; + sender.client = snd_seq_port_info_get_client( src_pinfo ); + sender.port = snd_seq_port_info_get_port( src_pinfo ); + + snd_seq_port_info_t *pinfo; + snd_seq_port_info_alloca( &pinfo ); + if ( data->vport < 0 ) { + snd_seq_port_info_set_client( pinfo, 0 ); + snd_seq_port_info_set_port( pinfo, 0 ); + snd_seq_port_info_set_capability( pinfo, + SND_SEQ_PORT_CAP_WRITE | + SND_SEQ_PORT_CAP_SUBS_WRITE ); + snd_seq_port_info_set_type( pinfo, + SND_SEQ_PORT_TYPE_MIDI_GENERIC | + SND_SEQ_PORT_TYPE_APPLICATION ); + snd_seq_port_info_set_midi_channels(pinfo, 16); #ifndef AVOID_TIMESTAMPING - snd_seq_port_info_set_timestamping(pinfo, 1); - snd_seq_port_info_set_timestamp_real(pinfo, 1); - snd_seq_port_info_set_timestamp_queue(pinfo, data->queue_id); + snd_seq_port_info_set_timestamping(pinfo, 1); + snd_seq_port_info_set_timestamp_real(pinfo, 1); + snd_seq_port_info_set_timestamp_queue(pinfo, data->queue_id); #endif - snd_seq_port_info_set_name(pinfo, portName.c_str() ); - data->vport = snd_seq_create_port(data->seq, pinfo); + snd_seq_port_info_set_name(pinfo, portName.c_str() ); + int createok = snd_seq_create_port(data->seq, pinfo); - if ( data->vport < 0 ) { - errorString_ = "MidiInAlsa::openPort: ALSA error creating input port."; - error( RtMidiError::DRIVER_ERROR, errorString_ ); - return; - } - data->vport = snd_seq_port_info_get_port(pinfo); - } - - receiver.client = snd_seq_port_info_get_client( pinfo ); - receiver.port = data->vport; - - if ( !data->subscription ) { - // Make subscription - if (snd_seq_port_subscribe_malloc( &data->subscription ) < 0) { - errorString_ = "MidiInAlsa::openPort: ALSA error allocation port subscription."; - error( RtMidiError::DRIVER_ERROR, errorString_ ); - return; - } - snd_seq_port_subscribe_set_sender(data->subscription, &sender); - snd_seq_port_subscribe_set_dest(data->subscription, &receiver); - if ( snd_seq_subscribe_port(data->seq, data->subscription) ) { - snd_seq_port_subscribe_free( data->subscription ); - data->subscription = 0; - errorString_ = "MidiInAlsa::openPort: ALSA error making port connection."; - error( RtMidiError::DRIVER_ERROR, errorString_ ); - return; - } - } - - if ( inputData_.doInput == false ) { - // Start the input queue + if ( createok < 0 ) { + errorString_ = "MidiInAlsa::openPort: ALSA error creating input port."; + error( Error::DRIVER_ERROR, errorString_ ); + return; + } + data->vport = snd_seq_port_info_get_port(pinfo); + } + + receiver.client = snd_seq_port_info_get_client( pinfo ); + receiver.port = data->vport; + + if ( !data->subscription ) { + // Make subscription + if (snd_seq_port_subscribe_malloc( &data->subscription ) < 0) { + errorString_ = "MidiInAlsa::openPort: ALSA error allocation port subscription."; + error( Error::DRIVER_ERROR, errorString_ ); + return; + } + snd_seq_port_subscribe_set_sender(data->subscription, &sender); + snd_seq_port_subscribe_set_dest(data->subscription, &receiver); + if ( snd_seq_subscribe_port(data->seq, data->subscription) ) { + snd_seq_port_subscribe_free( data->subscription ); + data->subscription = 0; + errorString_ = "MidiInAlsa::openPort: ALSA error making port connection."; + error( Error::DRIVER_ERROR, errorString_ ); + return; + } + } + + if ( inputData_.doInput == false ) { + // Start the input queue #ifndef AVOID_TIMESTAMPING - snd_seq_start_queue( data->seq, data->queue_id, NULL ); - snd_seq_drain_output( data->seq ); + snd_seq_start_queue( data->seq, data->queue_id, NULL ); + snd_seq_drain_output( data->seq ); #endif - // Start our MIDI input thread. - pthread_attr_t attr; - pthread_attr_init(&attr); - pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); - pthread_attr_setschedpolicy(&attr, SCHED_OTHER); - - inputData_.doInput = true; - int err = pthread_create(&data->thread, &attr, alsaMidiHandler, &inputData_); - pthread_attr_destroy(&attr); - if ( err ) { - snd_seq_unsubscribe_port( data->seq, data->subscription ); - snd_seq_port_subscribe_free( data->subscription ); - data->subscription = 0; - inputData_.doInput = false; - errorString_ = "MidiInAlsa::openPort: error starting MIDI input thread!"; - error( RtMidiError::THREAD_ERROR, errorString_ ); - return; - } - } - - connected_ = true; -} + // Start our MIDI input thread. + pthread_attr_t attr; + pthread_attr_init(&attr); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); + pthread_attr_setschedpolicy(&attr, SCHED_OTHER); + + inputData_.doInput = true; + int err = pthread_create(&data->thread, &attr, alsaMidiHandler, &inputData_); + pthread_attr_destroy(&attr); + if ( err ) { + snd_seq_unsubscribe_port( data->seq, data->subscription ); + snd_seq_port_subscribe_free( data->subscription ); + data->subscription = 0; + inputData_.doInput = false; + errorString_ = "MidiInAlsa::openPort: error starting MIDI input thread!"; + error( Error::THREAD_ERROR, errorString_ ); + return; + } + } + + connected_ = true; + } + + void MidiInAlsa :: openPort( const PortDescriptor & port, + const std::string portName = std::string( "RtMidi" ) ) + { + abort(); + } + + Pointer MidiInAlsa :: getDescriptor() + { + abort(); + } + PortList MidiInAlsa :: getPortList(int capabilities) + { + abort(); + } + + -void MidiInAlsa :: openVirtualPort( std::string portName ) -{ - AlsaMidiData *data = static_cast (apiData_); - if ( data->vport < 0 ) { - snd_seq_port_info_t *pinfo; - snd_seq_port_info_alloca( &pinfo ); - snd_seq_port_info_set_capability( pinfo, - SND_SEQ_PORT_CAP_WRITE | - SND_SEQ_PORT_CAP_SUBS_WRITE ); - snd_seq_port_info_set_type( pinfo, - SND_SEQ_PORT_TYPE_MIDI_GENERIC | - SND_SEQ_PORT_TYPE_APPLICATION ); - snd_seq_port_info_set_midi_channels(pinfo, 16); + void MidiInAlsa :: openVirtualPort( std::string portName ) + { + AlsaMidiData *data = static_cast (apiData_); + if ( data->vport < 0 ) { + snd_seq_port_info_t *pinfo; + snd_seq_port_info_alloca( &pinfo ); + snd_seq_port_info_set_capability( pinfo, + SND_SEQ_PORT_CAP_WRITE | + SND_SEQ_PORT_CAP_SUBS_WRITE ); + snd_seq_port_info_set_type( pinfo, + SND_SEQ_PORT_TYPE_MIDI_GENERIC | + SND_SEQ_PORT_TYPE_APPLICATION ); + snd_seq_port_info_set_midi_channels(pinfo, 16); #ifndef AVOID_TIMESTAMPING - snd_seq_port_info_set_timestamping(pinfo, 1); - snd_seq_port_info_set_timestamp_real(pinfo, 1); - snd_seq_port_info_set_timestamp_queue(pinfo, data->queue_id); + snd_seq_port_info_set_timestamping(pinfo, 1); + snd_seq_port_info_set_timestamp_real(pinfo, 1); + snd_seq_port_info_set_timestamp_queue(pinfo, data->queue_id); #endif - snd_seq_port_info_set_name(pinfo, portName.c_str()); - data->vport = snd_seq_create_port(data->seq, pinfo); - - if ( data->vport < 0 ) { - errorString_ = "MidiInAlsa::openVirtualPort: ALSA error creating virtual port."; - error( RtMidiError::DRIVER_ERROR, errorString_ ); - return; - } - data->vport = snd_seq_port_info_get_port(pinfo); - } - - if ( inputData_.doInput == false ) { - // Wait for old thread to stop, if still running - if ( !pthread_equal(data->thread, data->dummy_thread_id) ) - pthread_join( data->thread, NULL ); - - // Start the input queue + snd_seq_port_info_set_name(pinfo, portName.c_str()); + int createok = snd_seq_create_port(data->seq, pinfo); + + if ( createok < 0 ) { + errorString_ = "MidiInAlsa::openVirtualPort: ALSA error creating virtual port."; + error( Error::DRIVER_ERROR, errorString_ ); + return; + } + data->vport = snd_seq_port_info_get_port(pinfo); + } + + if ( inputData_.doInput == false ) { + // Wait for old thread to stop, if still running + if ( !pthread_equal(data->thread, data->dummy_thread_id) ) + pthread_join( data->thread, NULL ); + + // Start the input queue #ifndef AVOID_TIMESTAMPING - snd_seq_start_queue( data->seq, data->queue_id, NULL ); - snd_seq_drain_output( data->seq ); + snd_seq_start_queue( data->seq, data->queue_id, NULL ); + snd_seq_drain_output( data->seq ); #endif - // Start our MIDI input thread. - pthread_attr_t attr; - pthread_attr_init(&attr); - pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); - pthread_attr_setschedpolicy(&attr, SCHED_OTHER); - - inputData_.doInput = true; - int err = pthread_create(&data->thread, &attr, alsaMidiHandler, &inputData_); - pthread_attr_destroy(&attr); - if ( err ) { - if ( data->subscription ) { - snd_seq_unsubscribe_port( data->seq, data->subscription ); - snd_seq_port_subscribe_free( data->subscription ); - data->subscription = 0; - } - inputData_.doInput = false; - errorString_ = "MidiInAlsa::openPort: error starting MIDI input thread!"; - error( RtMidiError::THREAD_ERROR, errorString_ ); - return; - } - } -} + // Start our MIDI input thread. + pthread_attr_t attr; + pthread_attr_init(&attr); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); + pthread_attr_setschedpolicy(&attr, SCHED_OTHER); + + inputData_.doInput = true; + int err = pthread_create(&data->thread, &attr, alsaMidiHandler, &inputData_); + pthread_attr_destroy(&attr); + if ( err ) { + if ( data->subscription ) { + snd_seq_unsubscribe_port( data->seq, data->subscription ); + snd_seq_port_subscribe_free( data->subscription ); + data->subscription = 0; + } + inputData_.doInput = false; + errorString_ = "MidiInAlsa::openPort: error starting MIDI input thread!"; + error( Error::THREAD_ERROR, errorString_ ); + return; + } + } + } -void MidiInAlsa :: closePort( void ) -{ - AlsaMidiData *data = static_cast (apiData_); - - if ( connected_ ) { - if ( data->subscription ) { - snd_seq_unsubscribe_port( data->seq, data->subscription ); - snd_seq_port_subscribe_free( data->subscription ); - data->subscription = 0; - } - // Stop the input queue + void MidiInAlsa :: closePort( void ) + { + AlsaMidiData *data = static_cast (apiData_); + + if ( connected_ ) { + if ( data->subscription ) { + snd_seq_unsubscribe_port( data->seq, data->subscription ); + snd_seq_port_subscribe_free( data->subscription ); + data->subscription = 0; + } + // Stop the input queue #ifndef AVOID_TIMESTAMPING - snd_seq_stop_queue( data->seq, data->queue_id, NULL ); - snd_seq_drain_output( data->seq ); + snd_seq_stop_queue( data->seq, data->queue_id, NULL ); + snd_seq_drain_output( data->seq ); #endif - connected_ = false; - } - - // Stop thread to avoid triggering the callback, while the port is intended to be closed - if ( inputData_.doInput ) { - inputData_.doInput = false; - int res = write( data->trigger_fds[1], &inputData_.doInput, sizeof(inputData_.doInput) ); - (void) res; - if ( !pthread_equal(data->thread, data->dummy_thread_id) ) - pthread_join( data->thread, NULL ); - } -} + connected_ = false; + } + + // Stop thread to avoid triggering the callback, while the port is intended to be closed + if ( inputData_.doInput ) { + inputData_.doInput = false; + int res = write( data->trigger_fds[1], &inputData_.doInput, sizeof(inputData_.doInput) ); + (void) res; + if ( !pthread_equal(data->thread, data->dummy_thread_id) ) + pthread_join( data->thread, NULL ); + } + } -//*********************************************************************// -// API: LINUX ALSA -// Class Definitions: MidiOutAlsa -//*********************************************************************// + //*********************************************************************// + // API: LINUX ALSA + // Class Definitions: MidiOutAlsa + //*********************************************************************// -MidiOutAlsa :: MidiOutAlsa( const std::string clientName ) : MidiOutApi() -{ - initialize( clientName ); -} + MidiOutAlsa :: MidiOutAlsa( const std::string clientName ) : MidiOutApi() + { + initialize( clientName ); + } -MidiOutAlsa :: ~MidiOutAlsa() -{ - // Close a connection if it exists. - closePort(); - - // Cleanup. - AlsaMidiData *data = static_cast (apiData_); - if ( data->vport >= 0 ) snd_seq_delete_port( data->seq, data->vport ); - if ( data->coder ) snd_midi_event_free( data->coder ); - if ( data->buffer ) free( data->buffer ); - snd_seq_close( data->seq ); - delete data; -} + MidiOutAlsa :: ~MidiOutAlsa() + { + // Close a connection if it exists. + closePort(); + + // Cleanup. + AlsaMidiData *data = static_cast (apiData_); + if ( data->vport >= 0 ) snd_seq_delete_port( data->seq, data->vport ); + if ( data->coder ) snd_midi_event_free( data->coder ); + if ( data->buffer ) free( data->buffer ); + snd_seq_close( data->seq ); + delete data; + } -void MidiOutAlsa :: initialize( const std::string& clientName ) -{ - // Set up the ALSA sequencer client. - snd_seq_t *seq; - int result1 = snd_seq_open( &seq, "default", SND_SEQ_OPEN_OUTPUT, SND_SEQ_NONBLOCK ); - if ( result1 < 0 ) { - errorString_ = "MidiOutAlsa::initialize: error creating ALSA sequencer client object."; - error( RtMidiError::DRIVER_ERROR, errorString_ ); - return; - } - - // Set client name. - snd_seq_set_client_name( seq, clientName.c_str() ); - - // Save our api-specific connection information. - AlsaMidiData *data = (AlsaMidiData *) new AlsaMidiData; - data->seq = seq; - data->portNum = -1; - data->vport = -1; - data->bufferSize = 32; - data->coder = 0; - data->buffer = 0; - int result = snd_midi_event_new( data->bufferSize, &data->coder ); - if ( result < 0 ) { - delete data; - errorString_ = "MidiOutAlsa::initialize: error initializing MIDI event parser!\n\n"; - error( RtMidiError::DRIVER_ERROR, errorString_ ); - return; - } - data->buffer = (unsigned char *) malloc( data->bufferSize ); - if ( data->buffer == NULL ) { - delete data; - errorString_ = "MidiOutAlsa::initialize: error allocating buffer memory!\n\n"; - error( RtMidiError::MEMORY_ERROR, errorString_ ); - return; - } - snd_midi_event_init( data->coder ); - apiData_ = (void *) data; -} + void MidiOutAlsa :: initialize( const std::string& clientName ) + { + // Set up the ALSA sequencer client. + snd_seq_t *seq; + int result1 = snd_seq_open( &seq, "default", SND_SEQ_OPEN_OUTPUT, SND_SEQ_NONBLOCK ); + if ( result1 < 0 ) { + errorString_ = "MidiOutAlsa::initialize: error creating ALSA sequencer client object."; + error( Error::DRIVER_ERROR, errorString_ ); + return; + } + + // Set client name. + snd_seq_set_client_name( seq, clientName.c_str() ); + + // Save our api-specific connection information. + AlsaMidiData *data = (AlsaMidiData *) new AlsaMidiData; + data->seq = seq; + data->portNum = -1; + data->vport = -1; + data->bufferSize = 32; + data->coder = 0; + data->buffer = 0; + int result = snd_midi_event_new( data->bufferSize, &data->coder ); + if ( result < 0 ) { + delete data; + errorString_ = "MidiOutAlsa::initialize: error initializing MIDI event parser!\n\n"; + error( Error::DRIVER_ERROR, errorString_ ); + return; + } + data->buffer = (unsigned char *) malloc( data->bufferSize ); + if ( data->buffer == NULL ) { + delete data; + errorString_ = "MidiOutAlsa::initialize: error allocating buffer memory!\n\n"; + error( Error::MEMORY_ERROR, errorString_ ); + return; + } + snd_midi_event_init( data->coder ); + apiData_ = (void *) data; + } -unsigned int MidiOutAlsa :: getPortCount() -{ - snd_seq_port_info_t *pinfo; - snd_seq_port_info_alloca( &pinfo ); + unsigned int MidiOutAlsa :: getPortCount() + { + snd_seq_port_info_t *pinfo; + snd_seq_port_info_alloca( &pinfo ); - AlsaMidiData *data = static_cast (apiData_); - return portInfo( data->seq, pinfo, SND_SEQ_PORT_CAP_WRITE|SND_SEQ_PORT_CAP_SUBS_WRITE, -1 ); -} + AlsaMidiData *data = static_cast (apiData_); + return portInfo( data->seq, pinfo, SND_SEQ_PORT_CAP_WRITE|SND_SEQ_PORT_CAP_SUBS_WRITE, -1 ); + } -std::string MidiOutAlsa :: getPortName( unsigned int portNumber ) -{ - snd_seq_client_info_t *cinfo; - snd_seq_port_info_t *pinfo; - snd_seq_client_info_alloca( &cinfo ); - snd_seq_port_info_alloca( &pinfo ); - - std::string stringName; - AlsaMidiData *data = static_cast (apiData_); - if ( portInfo( data->seq, pinfo, SND_SEQ_PORT_CAP_WRITE|SND_SEQ_PORT_CAP_SUBS_WRITE, (int) portNumber ) ) { - int cnum = snd_seq_port_info_get_client(pinfo); - snd_seq_get_any_client_info( data->seq, cnum, cinfo ); - std::ostringstream os; - os << snd_seq_client_info_get_name(cinfo); - os << " "; // These lines added to make sure devices are listed - os << snd_seq_port_info_get_client( pinfo ); // with full portnames added to ensure individual device names - os << ":"; - os << snd_seq_port_info_get_port(pinfo); - stringName = os.str(); - return stringName; - } - - // If we get here, we didn't find a match. - errorString_ = "MidiOutAlsa::getPortName: error looking for port name!"; - error( RtMidiError::WARNING, errorString_ ); - return stringName; -} + std::string MidiOutAlsa :: getPortName( unsigned int portNumber ) + { + snd_seq_client_info_t *cinfo; + snd_seq_port_info_t *pinfo; + snd_seq_client_info_alloca( &cinfo ); + snd_seq_port_info_alloca( &pinfo ); + + std::string stringName; + AlsaMidiData *data = static_cast (apiData_); + if ( portInfo( data->seq, pinfo, SND_SEQ_PORT_CAP_WRITE|SND_SEQ_PORT_CAP_SUBS_WRITE, (int) portNumber ) ) { + int cnum = snd_seq_port_info_get_client(pinfo); + snd_seq_get_any_client_info( data->seq, cnum, cinfo ); + std::ostringstream os; + os << snd_seq_client_info_get_name(cinfo); + os << " "; // These lines added to make sure devices are listed + os << snd_seq_port_info_get_client( pinfo ); // with full portnames added to ensure individual device names + os << ":"; + os << snd_seq_port_info_get_port(pinfo); + stringName = os.str(); + return stringName; + } + + // If we get here, we didn't find a match. + errorString_ = "MidiOutAlsa::getPortName: error looking for port name!"; + error( Error::WARNING, errorString_ ); + return stringName; + } -void MidiOutAlsa :: openPort( unsigned int portNumber, const std::string portName ) -{ - if ( connected_ ) { - errorString_ = "MidiOutAlsa::openPort: a valid connection already exists!"; - error( RtMidiError::WARNING, errorString_ ); - return; - } - - unsigned int nSrc = this->getPortCount(); - if (nSrc < 1) { - errorString_ = "MidiOutAlsa::openPort: no MIDI output sources found!"; - error( RtMidiError::NO_DEVICES_FOUND, errorString_ ); - return; - } - - snd_seq_port_info_t *pinfo; - snd_seq_port_info_alloca( &pinfo ); - AlsaMidiData *data = static_cast (apiData_); - if ( portInfo( data->seq, pinfo, SND_SEQ_PORT_CAP_WRITE|SND_SEQ_PORT_CAP_SUBS_WRITE, (int) portNumber ) == 0 ) { - std::ostringstream ost; - ost << "MidiOutAlsa::openPort: the 'portNumber' argument (" << portNumber << ") is invalid."; - errorString_ = ost.str(); - error( RtMidiError::INVALID_PARAMETER, errorString_ ); - return; - } - - snd_seq_addr_t sender, receiver; - receiver.client = snd_seq_port_info_get_client( pinfo ); - receiver.port = snd_seq_port_info_get_port( pinfo ); - sender.client = snd_seq_client_id( data->seq ); - - if ( data->vport < 0 ) { - data->vport = snd_seq_create_simple_port( data->seq, portName.c_str(), - SND_SEQ_PORT_CAP_READ|SND_SEQ_PORT_CAP_SUBS_READ, - SND_SEQ_PORT_TYPE_MIDI_GENERIC|SND_SEQ_PORT_TYPE_APPLICATION ); - if ( data->vport < 0 ) { - errorString_ = "MidiOutAlsa::openPort: ALSA error creating output port."; - error( RtMidiError::DRIVER_ERROR, errorString_ ); - return; - } - } - - sender.port = data->vport; - - // Make subscription - if (snd_seq_port_subscribe_malloc( &data->subscription ) < 0) { - snd_seq_port_subscribe_free( data->subscription ); - errorString_ = "MidiOutAlsa::openPort: error allocating port subscription."; - error( RtMidiError::DRIVER_ERROR, errorString_ ); - return; - } - snd_seq_port_subscribe_set_sender(data->subscription, &sender); - snd_seq_port_subscribe_set_dest(data->subscription, &receiver); - snd_seq_port_subscribe_set_time_update(data->subscription, 1); - snd_seq_port_subscribe_set_time_real(data->subscription, 1); - if ( snd_seq_subscribe_port(data->seq, data->subscription) ) { - snd_seq_port_subscribe_free( data->subscription ); - errorString_ = "MidiOutAlsa::openPort: ALSA error making port connection."; - error( RtMidiError::DRIVER_ERROR, errorString_ ); - return; - } - - connected_ = true; -} + void MidiOutAlsa :: openPort( unsigned int portNumber, const std::string portName ) + { + if ( connected_ ) { + errorString_ = "MidiOutAlsa::openPort: a valid connection already exists!"; + error( Error::WARNING, errorString_ ); + return; + } + + unsigned int nSrc = this->getPortCount(); + if (nSrc < 1) { + errorString_ = "MidiOutAlsa::openPort: no MIDI output sources found!"; + error( Error::NO_DEVICES_FOUND, errorString_ ); + return; + } + + snd_seq_port_info_t *pinfo; + snd_seq_port_info_alloca( &pinfo ); + AlsaMidiData *data = static_cast (apiData_); + if ( portInfo( data->seq, pinfo, SND_SEQ_PORT_CAP_WRITE|SND_SEQ_PORT_CAP_SUBS_WRITE, (int) portNumber ) == 0 ) { + std::ostringstream ost; + ost << "MidiOutAlsa::openPort: the 'portNumber' argument (" << portNumber << ") is invalid."; + errorString_ = ost.str(); + error( Error::INVALID_PARAMETER, errorString_ ); + return; + } + + snd_seq_addr_t sender, receiver; + receiver.client = snd_seq_port_info_get_client( pinfo ); + receiver.port = snd_seq_port_info_get_port( pinfo ); + sender.client = snd_seq_client_id( data->seq ); + + if ( data->vport < 0 ) { + data->vport = snd_seq_create_simple_port( data->seq, portName.c_str(), + SND_SEQ_PORT_CAP_READ|SND_SEQ_PORT_CAP_SUBS_READ, + SND_SEQ_PORT_TYPE_MIDI_GENERIC|SND_SEQ_PORT_TYPE_APPLICATION ); + if ( data->vport < 0 ) { + errorString_ = "MidiOutAlsa::openPort: ALSA error creating output port."; + error( Error::DRIVER_ERROR, errorString_ ); + return; + } + } + + sender.port = data->vport; + + // Make subscription + if (snd_seq_port_subscribe_malloc( &data->subscription ) < 0) { + snd_seq_port_subscribe_free( data->subscription ); + errorString_ = "MidiOutAlsa::openPort: error allocating port subscription."; + error( Error::DRIVER_ERROR, errorString_ ); + return; + } + snd_seq_port_subscribe_set_sender(data->subscription, &sender); + snd_seq_port_subscribe_set_dest(data->subscription, &receiver); + snd_seq_port_subscribe_set_time_update(data->subscription, 1); + snd_seq_port_subscribe_set_time_real(data->subscription, 1); + if ( snd_seq_subscribe_port(data->seq, data->subscription) ) { + snd_seq_port_subscribe_free( data->subscription ); + errorString_ = "MidiOutAlsa::openPort: ALSA error making port connection."; + error( Error::DRIVER_ERROR, errorString_ ); + return; + } + + connected_ = true; + } -void MidiOutAlsa :: closePort( void ) -{ - if ( connected_ ) { - AlsaMidiData *data = static_cast (apiData_); - snd_seq_unsubscribe_port( data->seq, data->subscription ); - snd_seq_port_subscribe_free( data->subscription ); - connected_ = false; - } -} + void MidiOutAlsa :: closePort( void ) + { + if ( connected_ ) { + AlsaMidiData *data = static_cast (apiData_); + snd_seq_unsubscribe_port( data->seq, data->subscription ); + snd_seq_port_subscribe_free( data->subscription ); + connected_ = false; + } + } -void MidiOutAlsa :: openVirtualPort( std::string portName ) -{ - AlsaMidiData *data = static_cast (apiData_); - if ( data->vport < 0 ) { - data->vport = snd_seq_create_simple_port( data->seq, portName.c_str(), - SND_SEQ_PORT_CAP_READ|SND_SEQ_PORT_CAP_SUBS_READ, - SND_SEQ_PORT_TYPE_MIDI_GENERIC|SND_SEQ_PORT_TYPE_APPLICATION ); - - if ( data->vport < 0 ) { - errorString_ = "MidiOutAlsa::openVirtualPort: ALSA error creating virtual port."; - error( RtMidiError::DRIVER_ERROR, errorString_ ); - } - } -} + void MidiOutAlsa :: openVirtualPort( std::string portName ) + { + AlsaMidiData *data = static_cast (apiData_); + if ( data->vport < 0 ) { + data->vport = snd_seq_create_simple_port( data->seq, portName.c_str(), + SND_SEQ_PORT_CAP_READ|SND_SEQ_PORT_CAP_SUBS_READ, + SND_SEQ_PORT_TYPE_MIDI_GENERIC|SND_SEQ_PORT_TYPE_APPLICATION ); + + if ( data->vport < 0 ) { + errorString_ = "MidiOutAlsa::openVirtualPort: ALSA error creating virtual port."; + error( Error::DRIVER_ERROR, errorString_ ); + } + } + } -void MidiOutAlsa :: sendMessage( std::vector *message ) -{ - int result; - AlsaMidiData *data = static_cast (apiData_); - unsigned int nBytes = message->size(); - if ( nBytes > data->bufferSize ) { - data->bufferSize = nBytes; - result = snd_midi_event_resize_buffer ( data->coder, nBytes); - if ( result != 0 ) { - errorString_ = "MidiOutAlsa::sendMessage: ALSA error resizing MIDI event buffer."; - error( RtMidiError::DRIVER_ERROR, errorString_ ); - return; - } - free (data->buffer); - data->buffer = (unsigned char *) malloc( data->bufferSize ); - if ( data->buffer == NULL ) { - errorString_ = "MidiOutAlsa::initialize: error allocating buffer memory!\n\n"; - error( RtMidiError::MEMORY_ERROR, errorString_ ); - return; - } - } - - snd_seq_event_t ev; - snd_seq_ev_clear(&ev); - snd_seq_ev_set_source(&ev, data->vport); - snd_seq_ev_set_subs(&ev); - snd_seq_ev_set_direct(&ev); - for ( unsigned int i=0; ibuffer[i] = message->at(i); - result = snd_midi_event_encode( data->coder, data->buffer, (long)nBytes, &ev ); - if ( result < (int)nBytes ) { - errorString_ = "MidiOutAlsa::sendMessage: event parsing error!"; - error( RtMidiError::WARNING, errorString_ ); - return; - } - - // Send the event. - result = snd_seq_event_output(data->seq, &ev); - if ( result < 0 ) { - errorString_ = "MidiOutAlsa::sendMessage: error sending MIDI message to port."; - error( RtMidiError::WARNING, errorString_ ); - return; - } - snd_seq_drain_output(data->seq); -} + void MidiOutAlsa :: sendMessage( std::vector &message ) + { + int result; + AlsaMidiData *data = static_cast (apiData_); + unsigned int nBytes = message.size(); + if ( nBytes > data->bufferSize ) { + data->bufferSize = nBytes; + result = snd_midi_event_resize_buffer ( data->coder, nBytes); + if ( result != 0 ) { + errorString_ = "MidiOutAlsa::sendMessage: ALSA error resizing MIDI event buffer."; + error( Error::DRIVER_ERROR, errorString_ ); + return; + } + free (data->buffer); + data->buffer = (unsigned char *) malloc( data->bufferSize ); + if ( data->buffer == NULL ) { + errorString_ = "MidiOutAlsa::initialize: error allocating buffer memory!\n\n"; + error( Error::MEMORY_ERROR, errorString_ ); + return; + } + } + + snd_seq_event_t ev; + snd_seq_ev_clear(&ev); + snd_seq_ev_set_source(&ev, data->vport); + snd_seq_ev_set_subs(&ev); + snd_seq_ev_set_direct(&ev); + for ( unsigned int i=0; ibuffer[i] = message.at(i); + result = snd_midi_event_encode( data->coder, data->buffer, (long)nBytes, &ev ); + if ( result < (int)nBytes ) { + errorString_ = "MidiOutAlsa::sendMessage: event parsing error!"; + error( Error::WARNING, errorString_ ); + return; + } + + // Send the event. + result = snd_seq_event_output(data->seq, &ev); + if ( result < 0 ) { + errorString_ = "MidiOutAlsa::sendMessage: error sending MIDI message to port."; + error( Error::WARNING, errorString_ ); + return; + } + snd_seq_drain_output(data->seq); + } + void MidiOutAlsa :: openPort( const PortDescriptor & port, + const std::string portName) + { + abort(); + } + Pointer MidiOutAlsa :: getDescriptor() + { + abort(); + } + PortList MidiOutAlsa :: getPortList(int capabilities) + { + abort(); + } +} #endif // __LINUX_ALSA__ -//*********************************************************************// -// API: Windows Multimedia Library (MM) -//*********************************************************************// + //*********************************************************************// + // API: Windows Multimedia Library (MM) + //*********************************************************************// -// API information deciphered from: -// - http://msdn.microsoft.com/library/default.asp?url=/library/en-us/multimed/htm/_win32_midi_reference.asp + // API information deciphered from: + // - http://msdn.microsoft.com/library/default.asp?url=/library/en-us/multimed/htm/_win32_midi_reference.asp -// Thanks to Jean-Baptiste Berruchon for the sysex code. + // Thanks to Jean-Baptiste Berruchon for the sysex code. #if defined(__WINDOWS_MM__) -// The Windows MM API is based on the use of a callback function for -// MIDI input. We convert the system specific time stamps to delta -// time values. + // The Windows MM API is based on the use of a callback function for + // MIDI input. We convert the system specific time stamps to delta + // time values. -// Windows MM MIDI header files. + // Windows MM MIDI header files. #include #include #define RT_SYSEX_BUFFER_SIZE 1024 #define RT_SYSEX_BUFFER_COUNT 4 +namespace rtmidi{ + // A structure to hold variables related to the CoreMIDI API + // implementation. + struct WinMidiData { + HMIDIIN inHandle; // Handle to Midi Input Device + HMIDIOUT outHandle; // Handle to Midi Output Device + DWORD lastTime; + MidiInApi::MidiMessage message; + LPMIDIHDR sysexBuffer[RT_SYSEX_BUFFER_COUNT]; + CRITICAL_SECTION _mutex; // [Patrice] see https://groups.google.com/forum/#!topic/mididev/6OUjHutMpEo + }; + + //*********************************************************************// + // API: Windows MM + // Class Definitions: MidiInWinMM + //*********************************************************************// + + static void CALLBACK midiInputCallback( HMIDIIN /*hmin*/, + UINT inputStatus, + DWORD_PTR instancePtr, + DWORD_PTR midiMessage, + DWORD timestamp ) + { + if ( inputStatus != MIM_DATA && inputStatus != MIM_LONGDATA && inputStatus != MIM_LONGERROR ) return; + + //MidiInApi::MidiInData *data = static_cast (instancePtr); + MidiInApi::MidiInData *data = (MidiInApi::MidiInData *)instancePtr; + WinMidiData *apiData = static_cast (data->apiData); + + // Calculate time stamp. + if ( data->firstMessage == true ) { + apiData->message.timeStamp = 0.0; + data->firstMessage = false; + } + else apiData->message.timeStamp = (double) ( timestamp - apiData->lastTime ) * 0.001; + apiData->lastTime = timestamp; + + if ( inputStatus == MIM_DATA ) { // Channel or system message + + // Make sure the first byte is a status byte. + unsigned char status = (unsigned char) (midiMessage & 0x000000FF); + if ( !(status & 0x80) ) return; + + // Determine the number of bytes in the MIDI message. + unsigned short nBytes = 1; + if ( status < 0xC0 ) nBytes = 3; + else if ( status < 0xE0 ) nBytes = 2; + else if ( status < 0xF0 ) nBytes = 3; + else if ( status == 0xF1 ) { + if ( data->ignoreFlags & 0x02 ) return; + else nBytes = 2; + } + else if ( status == 0xF2 ) nBytes = 3; + else if ( status == 0xF3 ) nBytes = 2; + else if ( status == 0xF8 && (data->ignoreFlags & 0x02) ) { + // A MIDI timing tick message and we're ignoring it. + return; + } + else if ( status == 0xFE && (data->ignoreFlags & 0x04) ) { + // A MIDI active sensing message and we're ignoring it. + return; + } + + // Copy bytes to our MIDI message. + unsigned char *ptr = (unsigned char *) &midiMessage; + for ( int i=0; imessage.bytes.push_back( *ptr++ ); + } + else { // Sysex message ( MIM_LONGDATA or MIM_LONGERROR ) + MIDIHDR *sysex = ( MIDIHDR *) midiMessage; + if ( !( data->ignoreFlags & 0x01 ) && inputStatus != MIM_LONGERROR ) { + // Sysex message and we're not ignoring it + for ( int i=0; i<(int)sysex->dwBytesRecorded; ++i ) + apiData->message.bytes.push_back( sysex->lpData[i] ); + } + + // The WinMM API requires that the sysex buffer be requeued after + // input of each sysex message. Even if we are ignoring sysex + // messages, we still need to requeue the buffer in case the user + // decides to not ignore sysex messages in the future. However, + // it seems that WinMM calls this function with an empty sysex + // buffer when an application closes and in this case, we should + // avoid requeueing it, else the computer suddenly reboots after + // one or two minutes. + if ( apiData->sysexBuffer[sysex->dwUser]->dwBytesRecorded > 0 ) { + //if ( sysex->dwBytesRecorded > 0 ) { + EnterCriticalSection( &(apiData->_mutex) ); + MMRESULT result = midiInAddBuffer( apiData->inHandle, apiData->sysexBuffer[sysex->dwUser], sizeof(MIDIHDR) ); + LeaveCriticalSection( &(apiData->_mutex) ); + if ( result != MMSYSERR_NOERROR ) + std::cerr << "\nMidiIn::midiInputCallback: error sending sysex to Midi device!!\n\n"; + + if ( data->ignoreFlags & 0x01 ) return; + } + else return; + } + + if ( data->usingCallback ) { + MidiCallback callback = (MidiCallback) data->userCallback; + callback( apiData->message.timeStamp, &apiData->message.bytes, data->userData ); + } + else { + // As long as we haven't reached our queue size limit, push the message. + if ( data->queue.size < data->queue.ringSize ) { + data->queue.ring[data->queue.back++] = apiData->message; + if ( data->queue.back == data->queue.ringSize ) + data->queue.back = 0; + data->queue.size++; + } + else + std::cerr << "\nMidiIn: message queue limit reached!!\n\n"; + } + + // Clear the vector for the next input message. + apiData->message.bytes.clear(); + } -// A structure to hold variables related to the CoreMIDI API -// implementation. -struct WinMidiData { - HMIDIIN inHandle; // Handle to Midi Input Device - HMIDIOUT outHandle; // Handle to Midi Output Device - DWORD lastTime; - MidiInApi::MidiMessage message; - LPMIDIHDR sysexBuffer[RT_SYSEX_BUFFER_COUNT]; - CRITICAL_SECTION _mutex; // [Patrice] see https://groups.google.com/forum/#!topic/mididev/6OUjHutMpEo -}; - -//*********************************************************************// -// API: Windows MM -// Class Definitions: MidiInWinMM -//*********************************************************************// - -static void CALLBACK midiInputCallback( HMIDIIN /*hmin*/, - UINT inputStatus, - DWORD_PTR instancePtr, - DWORD_PTR midiMessage, - DWORD timestamp ) -{ - if ( inputStatus != MIM_DATA && inputStatus != MIM_LONGDATA && inputStatus != MIM_LONGERROR ) return; - - //MidiInApi::RtMidiInData *data = static_cast (instancePtr); - MidiInApi::RtMidiInData *data = (MidiInApi::RtMidiInData *)instancePtr; - WinMidiData *apiData = static_cast (data->apiData); - - // Calculate time stamp. - if ( data->firstMessage == true ) { - apiData->message.timeStamp = 0.0; - data->firstMessage = false; - } - else apiData->message.timeStamp = (double) ( timestamp - apiData->lastTime ) * 0.001; - apiData->lastTime = timestamp; - - if ( inputStatus == MIM_DATA ) { // Channel or system message - - // Make sure the first byte is a status byte. - unsigned char status = (unsigned char) (midiMessage & 0x000000FF); - if ( !(status & 0x80) ) return; - - // Determine the number of bytes in the MIDI message. - unsigned short nBytes = 1; - if ( status < 0xC0 ) nBytes = 3; - else if ( status < 0xE0 ) nBytes = 2; - else if ( status < 0xF0 ) nBytes = 3; - else if ( status == 0xF1 ) { - if ( data->ignoreFlags & 0x02 ) return; - else nBytes = 2; - } - else if ( status == 0xF2 ) nBytes = 3; - else if ( status == 0xF3 ) nBytes = 2; - else if ( status == 0xF8 && (data->ignoreFlags & 0x02) ) { - // A MIDI timing tick message and we're ignoring it. - return; - } - else if ( status == 0xFE && (data->ignoreFlags & 0x04) ) { - // A MIDI active sensing message and we're ignoring it. - return; - } - - // Copy bytes to our MIDI message. - unsigned char *ptr = (unsigned char *) &midiMessage; - for ( int i=0; imessage.bytes.push_back( *ptr++ ); - } - else { // Sysex message ( MIM_LONGDATA or MIM_LONGERROR ) - MIDIHDR *sysex = ( MIDIHDR *) midiMessage; - if ( !( data->ignoreFlags & 0x01 ) && inputStatus != MIM_LONGERROR ) { - // Sysex message and we're not ignoring it - for ( int i=0; i<(int)sysex->dwBytesRecorded; ++i ) - apiData->message.bytes.push_back( sysex->lpData[i] ); - } - - // The WinMM API requires that the sysex buffer be requeued after - // input of each sysex message. Even if we are ignoring sysex - // messages, we still need to requeue the buffer in case the user - // decides to not ignore sysex messages in the future. However, - // it seems that WinMM calls this function with an empty sysex - // buffer when an application closes and in this case, we should - // avoid requeueing it, else the computer suddenly reboots after - // one or two minutes. - if ( apiData->sysexBuffer[sysex->dwUser]->dwBytesRecorded > 0 ) { - //if ( sysex->dwBytesRecorded > 0 ) { - EnterCriticalSection( &(apiData->_mutex) ); - MMRESULT result = midiInAddBuffer( apiData->inHandle, apiData->sysexBuffer[sysex->dwUser], sizeof(MIDIHDR) ); - LeaveCriticalSection( &(apiData->_mutex) ); - if ( result != MMSYSERR_NOERROR ) - std::cerr << "\nRtMidiIn::midiInputCallback: error sending sysex to Midi device!!\n\n"; - - if ( data->ignoreFlags & 0x01 ) return; - } - else return; - } - - if ( data->usingCallback ) { - RtMidiIn::RtMidiCallback callback = (RtMidiIn::RtMidiCallback) data->userCallback; - callback( apiData->message.timeStamp, &apiData->message.bytes, data->userData ); - } - else { - // As long as we haven't reached our queue size limit, push the message. - if ( data->queue.size < data->queue.ringSize ) { - data->queue.ring[data->queue.back++] = apiData->message; - if ( data->queue.back == data->queue.ringSize ) - data->queue.back = 0; - data->queue.size++; - } - else - std::cerr << "\nRtMidiIn: message queue limit reached!!\n\n"; - } - - // Clear the vector for the next input message. - apiData->message.bytes.clear(); -} - -MidiInWinMM :: MidiInWinMM( const std::string clientName, unsigned int queueSizeLimit ) : MidiInApi( queueSizeLimit ) -{ - initialize( clientName ); -} + MidiInWinMM :: MidiInWinMM( const std::string clientName, unsigned int queueSizeLimit ) : MidiInApi( queueSizeLimit ) + { + initialize( clientName ); + } -MidiInWinMM :: ~MidiInWinMM() -{ - // Close a connection if it exists. - closePort(); + MidiInWinMM :: ~MidiInWinMM() + { + // Close a connection if it exists. + closePort(); - WinMidiData *data = static_cast (apiData_); - DeleteCriticalSection( &(data->_mutex) ); + WinMidiData *data = static_cast (apiData_); + DeleteCriticalSection( &(data->_mutex) ); - // Cleanup. - delete data; -} + // Cleanup. + delete data; + } -void MidiInWinMM :: initialize( const std::string& /*clientName*/ ) -{ - // We'll issue a warning here if no devices are available but not - // throw an error since the user can plugin something later. - unsigned int nDevices = midiInGetNumDevs(); - if ( nDevices == 0 ) { - errorString_ = "MidiInWinMM::initialize: no MIDI input devices currently available."; - error( RtMidiError::WARNING, errorString_ ); - } - - // Save our api-specific connection information. - WinMidiData *data = (WinMidiData *) new WinMidiData; - apiData_ = (void *) data; - inputData_.apiData = (void *) data; - data->message.bytes.clear(); // needs to be empty for first input message - - if ( !InitializeCriticalSectionAndSpinCount(&(data->_mutex), 0x00000400) ) { - errorString_ = "MidiInWinMM::initialize: InitializeCriticalSectionAndSpinCount failed."; - error( RtMidiError::WARNING, errorString_ ); - } -} + void MidiInWinMM :: initialize( const std::string& /*clientName*/ ) + { + // We'll issue a warning here if no devices are available but not + // throw an error since the user can plugin something later. + unsigned int nDevices = midiInGetNumDevs(); + if ( nDevices == 0 ) { + errorString_ = "MidiInWinMM::initialize: no MIDI input devices currently available."; + error( Error::WARNING, errorString_ ); + } + + // Save our api-specific connection information. + WinMidiData *data = (WinMidiData *) new WinMidiData; + apiData_ = (void *) data; + inputData_.apiData = (void *) data; + data->message.bytes.clear(); // needs to be empty for first input message + + if ( !InitializeCriticalSectionAndSpinCount(&(data->_mutex), 0x00000400) ) { + errorString_ = "MidiInWinMM::initialize: InitializeCriticalSectionAndSpinCount failed."; + error( Error::WARNING, errorString_ ); + } + } -void MidiInWinMM :: openPort( unsigned int portNumber, const std::string /*portName*/ ) -{ - if ( connected_ ) { - errorString_ = "MidiInWinMM::openPort: a valid connection already exists!"; - error( RtMidiError::WARNING, errorString_ ); - return; - } - - unsigned int nDevices = midiInGetNumDevs(); - if (nDevices == 0) { - errorString_ = "MidiInWinMM::openPort: no MIDI input sources found!"; - error( RtMidiError::NO_DEVICES_FOUND, errorString_ ); - return; - } - - if ( portNumber >= nDevices ) { - std::ostringstream ost; - ost << "MidiInWinMM::openPort: the 'portNumber' argument (" << portNumber << ") is invalid."; - errorString_ = ost.str(); - error( RtMidiError::INVALID_PARAMETER, errorString_ ); - return; - } - - WinMidiData *data = static_cast (apiData_); - MMRESULT result = midiInOpen( &data->inHandle, - portNumber, - (DWORD_PTR)&midiInputCallback, - (DWORD_PTR)&inputData_, - CALLBACK_FUNCTION ); - if ( result != MMSYSERR_NOERROR ) { - errorString_ = "MidiInWinMM::openPort: error creating Windows MM MIDI input port."; - error( RtMidiError::DRIVER_ERROR, errorString_ ); - return; - } - - // Allocate and init the sysex buffers. - for ( int i=0; isysexBuffer[i] = (MIDIHDR*) new char[ sizeof(MIDIHDR) ]; - data->sysexBuffer[i]->lpData = new char[ RT_SYSEX_BUFFER_SIZE ]; - data->sysexBuffer[i]->dwBufferLength = RT_SYSEX_BUFFER_SIZE; - data->sysexBuffer[i]->dwUser = i; // We use the dwUser parameter as buffer indicator - data->sysexBuffer[i]->dwFlags = 0; - - result = midiInPrepareHeader( data->inHandle, data->sysexBuffer[i], sizeof(MIDIHDR) ); - if ( result != MMSYSERR_NOERROR ) { - midiInClose( data->inHandle ); - errorString_ = "MidiInWinMM::openPort: error starting Windows MM MIDI input port (PrepareHeader)."; - error( RtMidiError::DRIVER_ERROR, errorString_ ); - return; - } - - // Register the buffer. - result = midiInAddBuffer( data->inHandle, data->sysexBuffer[i], sizeof(MIDIHDR) ); - if ( result != MMSYSERR_NOERROR ) { - midiInClose( data->inHandle ); - errorString_ = "MidiInWinMM::openPort: error starting Windows MM MIDI input port (AddBuffer)."; - error( RtMidiError::DRIVER_ERROR, errorString_ ); - return; - } - } - - result = midiInStart( data->inHandle ); - if ( result != MMSYSERR_NOERROR ) { - midiInClose( data->inHandle ); - errorString_ = "MidiInWinMM::openPort: error starting Windows MM MIDI input port."; - error( RtMidiError::DRIVER_ERROR, errorString_ ); - return; - } - - connected_ = true; -} + void MidiInWinMM :: openPort( unsigned int portNumber, const std::string /*portName*/ ) + { + if ( connected_ ) { + errorString_ = "MidiInWinMM::openPort: a valid connection already exists!"; + error( Error::WARNING, errorString_ ); + return; + } + + unsigned int nDevices = midiInGetNumDevs(); + if (nDevices == 0) { + errorString_ = "MidiInWinMM::openPort: no MIDI input sources found!"; + error( Error::NO_DEVICES_FOUND, errorString_ ); + return; + } + + if ( portNumber >= nDevices ) { + std::ostringstream ost; + ost << "MidiInWinMM::openPort: the 'portNumber' argument (" << portNumber << ") is invalid."; + errorString_ = ost.str(); + error( Error::INVALID_PARAMETER, errorString_ ); + return; + } + + WinMidiData *data = static_cast (apiData_); + MMRESULT result = midiInOpen( &data->inHandle, + portNumber, + (DWORD_PTR)&midiInputCallback, + (DWORD_PTR)&inputData_, + CALLBACK_FUNCTION ); + if ( result != MMSYSERR_NOERROR ) { + errorString_ = "MidiInWinMM::openPort: error creating Windows MM MIDI input port."; + error( Error::DRIVER_ERROR, errorString_ ); + return; + } + + // Allocate and init the sysex buffers. + for ( int i=0; isysexBuffer[i] = (MIDIHDR*) new char[ sizeof(MIDIHDR) ]; + data->sysexBuffer[i]->lpData = new char[ RT_SYSEX_BUFFER_SIZE ]; + data->sysexBuffer[i]->dwBufferLength = RT_SYSEX_BUFFER_SIZE; + data->sysexBuffer[i]->dwUser = i; // We use the dwUser parameter as buffer indicator + data->sysexBuffer[i]->dwFlags = 0; + + result = midiInPrepareHeader( data->inHandle, data->sysexBuffer[i], sizeof(MIDIHDR) ); + if ( result != MMSYSERR_NOERROR ) { + midiInClose( data->inHandle ); + errorString_ = "MidiInWinMM::openPort: error starting Windows MM MIDI input port (PrepareHeader)."; + error( Error::DRIVER_ERROR, errorString_ ); + return; + } + + // Register the buffer. + result = midiInAddBuffer( data->inHandle, data->sysexBuffer[i], sizeof(MIDIHDR) ); + if ( result != MMSYSERR_NOERROR ) { + midiInClose( data->inHandle ); + errorString_ = "MidiInWinMM::openPort: error starting Windows MM MIDI input port (AddBuffer)."; + error( Error::DRIVER_ERROR, errorString_ ); + return; + } + } + + result = midiInStart( data->inHandle ); + if ( result != MMSYSERR_NOERROR ) { + midiInClose( data->inHandle ); + errorString_ = "MidiInWinMM::openPort: error starting Windows MM MIDI input port."; + error( Error::DRIVER_ERROR, errorString_ ); + return; + } + + connected_ = true; + } -void MidiInWinMM :: openVirtualPort( std::string /*portName*/ ) -{ - // This function cannot be implemented for the Windows MM MIDI API. - errorString_ = "MidiInWinMM::openVirtualPort: cannot be implemented in Windows MM MIDI API!"; - error( RtMidiError::WARNING, errorString_ ); -} + void MidiInWinMM :: openVirtualPort( std::string /*portName*/ ) + { + // This function cannot be implemented for the Windows MM MIDI API. + errorString_ = "MidiInWinMM::openVirtualPort: cannot be implemented in Windows MM MIDI API!"; + error( Error::WARNING, errorString_ ); + } -void MidiInWinMM :: closePort( void ) -{ - if ( connected_ ) { - WinMidiData *data = static_cast (apiData_); - EnterCriticalSection( &(data->_mutex) ); - midiInReset( data->inHandle ); - midiInStop( data->inHandle ); - - for ( int i=0; iinHandle, data->sysexBuffer[i], sizeof(MIDIHDR)); - delete [] data->sysexBuffer[i]->lpData; - delete [] data->sysexBuffer[i]; - if ( result != MMSYSERR_NOERROR ) { - midiInClose( data->inHandle ); - errorString_ = "MidiInWinMM::openPort: error closing Windows MM MIDI input port (midiInUnprepareHeader)."; - error( RtMidiError::DRIVER_ERROR, errorString_ ); - return; - } - } - - midiInClose( data->inHandle ); - connected_ = false; - LeaveCriticalSection( &(data->_mutex) ); - } -} + void MidiInWinMM :: closePort( void ) + { + if ( connected_ ) { + WinMidiData *data = static_cast (apiData_); + EnterCriticalSection( &(data->_mutex) ); + midiInReset( data->inHandle ); + midiInStop( data->inHandle ); + + for ( int i=0; iinHandle, data->sysexBuffer[i], sizeof(MIDIHDR)); + delete [] data->sysexBuffer[i]->lpData; + delete [] data->sysexBuffer[i]; + if ( result != MMSYSERR_NOERROR ) { + midiInClose( data->inHandle ); + errorString_ = "MidiInWinMM::openPort: error closing Windows MM MIDI input port (midiInUnprepareHeader)."; + error( Error::DRIVER_ERROR, errorString_ ); + return; + } + } + + midiInClose( data->inHandle ); + connected_ = false; + LeaveCriticalSection( &(data->_mutex) ); + } + } -unsigned int MidiInWinMM :: getPortCount() -{ - return midiInGetNumDevs(); -} + unsigned int MidiInWinMM :: getPortCount() + { + return midiInGetNumDevs(); + } -std::string MidiInWinMM :: getPortName( unsigned int portNumber ) -{ - std::string stringName; - unsigned int nDevices = midiInGetNumDevs(); - if ( portNumber >= nDevices ) { - std::ostringstream ost; - ost << "MidiInWinMM::getPortName: the 'portNumber' argument (" << portNumber << ") is invalid."; - errorString_ = ost.str(); - error( RtMidiError::WARNING, errorString_ ); - return stringName; - } - - MIDIINCAPS deviceCaps; - midiInGetDevCaps( portNumber, &deviceCaps, sizeof(MIDIINCAPS)); + std::string MidiInWinMM :: getPortName( unsigned int portNumber ) + { + std::string stringName; + unsigned int nDevices = midiInGetNumDevs(); + if ( portNumber >= nDevices ) { + std::ostringstream ost; + ost << "MidiInWinMM::getPortName: the 'portNumber' argument (" << portNumber << ") is invalid."; + errorString_ = ost.str(); + error( Error::WARNING, errorString_ ); + return stringName; + } + + MIDIINCAPS deviceCaps; + midiInGetDevCaps( portNumber, &deviceCaps, sizeof(MIDIINCAPS)); #if defined( UNICODE ) || defined( _UNICODE ) - int length = WideCharToMultiByte(CP_UTF8, 0, deviceCaps.szPname, -1, NULL, 0, NULL, NULL) - 1; - stringName.assign( length, 0 ); - length = WideCharToMultiByte(CP_UTF8, 0, deviceCaps.szPname, static_cast(wcslen(deviceCaps.szPname)), &stringName[0], length, NULL, NULL); + int length = WideCharToMultiByte(CP_UTF8, 0, deviceCaps.szPname, -1, NULL, 0, NULL, NULL) - 1; + stringName.assign( length, 0 ); + length = WideCharToMultiByte(CP_UTF8, 0, deviceCaps.szPname, static_cast(wcslen(deviceCaps.szPname)), &stringName[0], length, NULL, NULL); #else - stringName = std::string( deviceCaps.szPname ); + stringName = std::string( deviceCaps.szPname ); #endif - // Next lines added to add the portNumber to the name so that - // the device's names are sure to be listed with individual names - // even when they have the same brand name - std::ostringstream os; - os << " "; - os << portNumber; - stringName += os.str(); + // Next lines added to add the portNumber to the name so that + // the device's names are sure to be listed with individual names + // even when they have the same brand name + std::ostringstream os; + os << " "; + os << portNumber; + stringName += os.str(); - return stringName; -} + return stringName; + } -//*********************************************************************// -// API: Windows MM -// Class Definitions: MidiOutWinMM -//*********************************************************************// + //*********************************************************************// + // API: Windows MM + // Class Definitions: MidiOutWinMM + //*********************************************************************// -MidiOutWinMM :: MidiOutWinMM( const std::string clientName ) : MidiOutApi() -{ - initialize( clientName ); -} + MidiOutWinMM :: MidiOutWinMM( const std::string clientName ) : MidiOutApi() + { + initialize( clientName ); + } -MidiOutWinMM :: ~MidiOutWinMM() -{ - // Close a connection if it exists. - closePort(); + MidiOutWinMM :: ~MidiOutWinMM() + { + // Close a connection if it exists. + closePort(); - // Cleanup. - WinMidiData *data = static_cast (apiData_); - delete data; -} + // Cleanup. + WinMidiData *data = static_cast (apiData_); + delete data; + } -void MidiOutWinMM :: initialize( const std::string& /*clientName*/ ) -{ - // We'll issue a warning here if no devices are available but not - // throw an error since the user can plug something in later. - unsigned int nDevices = midiOutGetNumDevs(); - if ( nDevices == 0 ) { - errorString_ = "MidiOutWinMM::initialize: no MIDI output devices currently available."; - error( RtMidiError::WARNING, errorString_ ); - } - - // Save our api-specific connection information. - WinMidiData *data = (WinMidiData *) new WinMidiData; - apiData_ = (void *) data; -} + void MidiOutWinMM :: initialize( const std::string& /*clientName*/ ) + { + // We'll issue a warning here if no devices are available but not + // throw an error since the user can plug something in later. + unsigned int nDevices = midiOutGetNumDevs(); + if ( nDevices == 0 ) { + errorString_ = "MidiOutWinMM::initialize: no MIDI output devices currently available."; + error( Error::WARNING, errorString_ ); + } + + // Save our api-specific connection information. + WinMidiData *data = (WinMidiData *) new WinMidiData; + apiData_ = (void *) data; + } -unsigned int MidiOutWinMM :: getPortCount() -{ - return midiOutGetNumDevs(); -} + unsigned int MidiOutWinMM :: getPortCount() + { + return midiOutGetNumDevs(); + } -std::string MidiOutWinMM :: getPortName( unsigned int portNumber ) -{ - std::string stringName; - unsigned int nDevices = midiOutGetNumDevs(); - if ( portNumber >= nDevices ) { - std::ostringstream ost; - ost << "MidiOutWinMM::getPortName: the 'portNumber' argument (" << portNumber << ") is invalid."; - errorString_ = ost.str(); - error( RtMidiError::WARNING, errorString_ ); - return stringName; - } - - MIDIOUTCAPS deviceCaps; - midiOutGetDevCaps( portNumber, &deviceCaps, sizeof(MIDIOUTCAPS)); + std::string MidiOutWinMM :: getPortName( unsigned int portNumber ) + { + std::string stringName; + unsigned int nDevices = midiOutGetNumDevs(); + if ( portNumber >= nDevices ) { + std::ostringstream ost; + ost << "MidiOutWinMM::getPortName: the 'portNumber' argument (" << portNumber << ") is invalid."; + errorString_ = ost.str(); + error( Error::WARNING, errorString_ ); + return stringName; + } + + MIDIOUTCAPS deviceCaps; + midiOutGetDevCaps( portNumber, &deviceCaps, sizeof(MIDIOUTCAPS)); #if defined( UNICODE ) || defined( _UNICODE ) - int length = WideCharToMultiByte(CP_UTF8, 0, deviceCaps.szPname, -1, NULL, 0, NULL, NULL) - 1; - stringName.assign( length, 0 ); - length = WideCharToMultiByte(CP_UTF8, 0, deviceCaps.szPname, static_cast(wcslen(deviceCaps.szPname)), &stringName[0], length, NULL, NULL); + int length = WideCharToMultiByte(CP_UTF8, 0, deviceCaps.szPname, -1, NULL, 0, NULL, NULL) - 1; + stringName.assign( length, 0 ); + length = WideCharToMultiByte(CP_UTF8, 0, deviceCaps.szPname, static_cast(wcslen(deviceCaps.szPname)), &stringName[0], length, NULL, NULL); #else - stringName = std::string( deviceCaps.szPname ); + stringName = std::string( deviceCaps.szPname ); #endif - return stringName; -} + return stringName; + } -void MidiOutWinMM :: openPort( unsigned int portNumber, const std::string /*portName*/ ) -{ - if ( connected_ ) { - errorString_ = "MidiOutWinMM::openPort: a valid connection already exists!"; - error( RtMidiError::WARNING, errorString_ ); - return; - } - - unsigned int nDevices = midiOutGetNumDevs(); - if (nDevices < 1) { - errorString_ = "MidiOutWinMM::openPort: no MIDI output destinations found!"; - error( RtMidiError::NO_DEVICES_FOUND, errorString_ ); - return; - } - - if ( portNumber >= nDevices ) { - std::ostringstream ost; - ost << "MidiOutWinMM::openPort: the 'portNumber' argument (" << portNumber << ") is invalid."; - errorString_ = ost.str(); - error( RtMidiError::INVALID_PARAMETER, errorString_ ); - return; - } - - WinMidiData *data = static_cast (apiData_); - MMRESULT result = midiOutOpen( &data->outHandle, - portNumber, - (DWORD)NULL, - (DWORD)NULL, - CALLBACK_NULL ); - if ( result != MMSYSERR_NOERROR ) { - errorString_ = "MidiOutWinMM::openPort: error creating Windows MM MIDI output port."; - error( RtMidiError::DRIVER_ERROR, errorString_ ); - return; - } - - connected_ = true; -} + void MidiOutWinMM :: openPort( unsigned int portNumber, const std::string /*portName*/ ) + { + if ( connected_ ) { + errorString_ = "MidiOutWinMM::openPort: a valid connection already exists!"; + error( Error::WARNING, errorString_ ); + return; + } + + unsigned int nDevices = midiOutGetNumDevs(); + if (nDevices < 1) { + errorString_ = "MidiOutWinMM::openPort: no MIDI output destinations found!"; + error( Error::NO_DEVICES_FOUND, errorString_ ); + return; + } + + if ( portNumber >= nDevices ) { + std::ostringstream ost; + ost << "MidiOutWinMM::openPort: the 'portNumber' argument (" << portNumber << ") is invalid."; + errorString_ = ost.str(); + error( Error::INVALID_PARAMETER, errorString_ ); + return; + } + + WinMidiData *data = static_cast (apiData_); + MMRESULT result = midiOutOpen( &data->outHandle, + portNumber, + (DWORD)NULL, + (DWORD)NULL, + CALLBACK_NULL ); + if ( result != MMSYSERR_NOERROR ) { + errorString_ = "MidiOutWinMM::openPort: error creating Windows MM MIDI output port."; + error( Error::DRIVER_ERROR, errorString_ ); + return; + } + + connected_ = true; + } -void MidiOutWinMM :: closePort( void ) -{ - if ( connected_ ) { - WinMidiData *data = static_cast (apiData_); - midiOutReset( data->outHandle ); - midiOutClose( data->outHandle ); - connected_ = false; - } -} + void MidiOutWinMM :: closePort( void ) + { + if ( connected_ ) { + WinMidiData *data = static_cast (apiData_); + midiOutReset( data->outHandle ); + midiOutClose( data->outHandle ); + connected_ = false; + } + } -void MidiOutWinMM :: openVirtualPort( std::string /*portName*/ ) -{ - // This function cannot be implemented for the Windows MM MIDI API. - errorString_ = "MidiOutWinMM::openVirtualPort: cannot be implemented in Windows MM MIDI API!"; - error( RtMidiError::WARNING, errorString_ ); -} + void MidiOutWinMM :: openVirtualPort( std::string /*portName*/ ) + { + // This function cannot be implemented for the Windows MM MIDI API. + errorString_ = "MidiOutWinMM::openVirtualPort: cannot be implemented in Windows MM MIDI API!"; + error( Error::WARNING, errorString_ ); + } -void MidiOutWinMM :: sendMessage( std::vector *message ) -{ - if ( !connected_ ) return; - - unsigned int nBytes = static_cast(message->size()); - if ( nBytes == 0 ) { - errorString_ = "MidiOutWinMM::sendMessage: message argument is empty!"; - error( RtMidiError::WARNING, errorString_ ); - return; - } - - MMRESULT result; - WinMidiData *data = static_cast (apiData_); - if ( message->at(0) == 0xF0 ) { // Sysex message - - // Allocate buffer for sysex data. - char *buffer = (char *) malloc( nBytes ); - if ( buffer == NULL ) { - errorString_ = "MidiOutWinMM::sendMessage: error allocating sysex message memory!"; - error( RtMidiError::MEMORY_ERROR, errorString_ ); - return; - } - - // Copy data to buffer. - for ( unsigned int i=0; iat(i); - - // Create and prepare MIDIHDR structure. - MIDIHDR sysex; - sysex.lpData = (LPSTR) buffer; - sysex.dwBufferLength = nBytes; - sysex.dwFlags = 0; - result = midiOutPrepareHeader( data->outHandle, &sysex, sizeof(MIDIHDR) ); - if ( result != MMSYSERR_NOERROR ) { - free( buffer ); - errorString_ = "MidiOutWinMM::sendMessage: error preparing sysex header."; - error( RtMidiError::DRIVER_ERROR, errorString_ ); - return; - } - - // Send the message. - result = midiOutLongMsg( data->outHandle, &sysex, sizeof(MIDIHDR) ); - if ( result != MMSYSERR_NOERROR ) { - free( buffer ); - errorString_ = "MidiOutWinMM::sendMessage: error sending sysex message."; - error( RtMidiError::DRIVER_ERROR, errorString_ ); - return; - } - - // Unprepare the buffer and MIDIHDR. - while ( MIDIERR_STILLPLAYING == midiOutUnprepareHeader( data->outHandle, &sysex, sizeof (MIDIHDR) ) ) Sleep( 1 ); - free( buffer ); - } - else { // Channel or system message. - - // Make sure the message size isn't too big. - if ( nBytes > 3 ) { - errorString_ = "MidiOutWinMM::sendMessage: message size is greater than 3 bytes (and not sysex)!"; - error( RtMidiError::WARNING, errorString_ ); - return; - } - - // Pack MIDI bytes into double word. - DWORD packet; - unsigned char *ptr = (unsigned char *) &packet; - for ( unsigned int i=0; iat(i); - ++ptr; - } - - // Send the message immediately. - result = midiOutShortMsg( data->outHandle, packet ); - if ( result != MMSYSERR_NOERROR ) { - errorString_ = "MidiOutWinMM::sendMessage: error sending MIDI message."; - error( RtMidiError::DRIVER_ERROR, errorString_ ); - } - } + void MidiOutWinMM :: sendMessage( std::vector *message ) + { + if ( !connected_ ) return; + + unsigned int nBytes = static_cast(message->size()); + if ( nBytes == 0 ) { + errorString_ = "MidiOutWinMM::sendMessage: message argument is empty!"; + error( Error::WARNING, errorString_ ); + return; + } + + MMRESULT result; + WinMidiData *data = static_cast (apiData_); + if ( message->at(0) == 0xF0 ) { // Sysex message + + // Allocate buffer for sysex data. + char *buffer = (char *) malloc( nBytes ); + if ( buffer == NULL ) { + errorString_ = "MidiOutWinMM::sendMessage: error allocating sysex message memory!"; + error( Error::MEMORY_ERROR, errorString_ ); + return; + } + + // Copy data to buffer. + for ( unsigned int i=0; iat(i); + + // Create and prepare MIDIHDR structure. + MIDIHDR sysex; + sysex.lpData = (LPSTR) buffer; + sysex.dwBufferLength = nBytes; + sysex.dwFlags = 0; + result = midiOutPrepareHeader( data->outHandle, &sysex, sizeof(MIDIHDR) ); + if ( result != MMSYSERR_NOERROR ) { + free( buffer ); + errorString_ = "MidiOutWinMM::sendMessage: error preparing sysex header."; + error( Error::DRIVER_ERROR, errorString_ ); + return; + } + + // Send the message. + result = midiOutLongMsg( data->outHandle, &sysex, sizeof(MIDIHDR) ); + if ( result != MMSYSERR_NOERROR ) { + free( buffer ); + errorString_ = "MidiOutWinMM::sendMessage: error sending sysex message."; + error( Error::DRIVER_ERROR, errorString_ ); + return; + } + + // Unprepare the buffer and MIDIHDR. + while ( MIDIERR_STILLPLAYING == midiOutUnprepareHeader( data->outHandle, &sysex, sizeof (MIDIHDR) ) ) Sleep( 1 ); + free( buffer ); + } + else { // Channel or system message. + + // Make sure the message size isn't too big. + if ( nBytes > 3 ) { + errorString_ = "MidiOutWinMM::sendMessage: message size is greater than 3 bytes (and not sysex)!"; + error( Error::WARNING, errorString_ ); + return; + } + + // Pack MIDI bytes into double word. + DWORD packet; + unsigned char *ptr = (unsigned char *) &packet; + for ( unsigned int i=0; iat(i); + ++ptr; + } + + // Send the message immediately. + result = midiOutShortMsg( data->outHandle, packet ); + if ( result != MMSYSERR_NOERROR ) { + errorString_ = "MidiOutWinMM::sendMessage: error sending MIDI message."; + error( Error::DRIVER_ERROR, errorString_ ); + } + } + } } - #endif // __WINDOWS_MM__ -// *********************************************************************// -// API: WINDOWS Kernel Streaming -// -// Written by Sebastien Alaiwan, 2012. -// -// NOTE BY GARY: much of the KS-specific code below probably should go in a separate file. -// -// *********************************************************************// + // *********************************************************************// + // API: WINDOWS Kernel Streaming + // + // Written by Sebastien Alaiwan, 2012. + // + // NOTE BY GARY: much of the KS-specific code below probably should go in a separate file. + // + // *********************************************************************// #if defined(__WINDOWS_KS__) @@ -2459,1426 +2519,1429 @@ void MidiOutWinMM :: sendMessage( std::vector *message ) #define INSTANTIATE_GUID(a) GUID const a = { STATIC_ ## a } -INSTANTIATE_GUID(GUID_NULL); -INSTANTIATE_GUID(KSPROPSETID_Pin); -INSTANTIATE_GUID(KSPROPSETID_Connection); -INSTANTIATE_GUID(KSPROPSETID_Topology); -INSTANTIATE_GUID(KSINTERFACESETID_Standard); -INSTANTIATE_GUID(KSMEDIUMSETID_Standard); -INSTANTIATE_GUID(KSDATAFORMAT_TYPE_MUSIC); -INSTANTIATE_GUID(KSDATAFORMAT_SUBTYPE_MIDI); -INSTANTIATE_GUID(KSDATAFORMAT_SPECIFIER_NONE); + INSTANTIATE_GUID(GUID_NULL); + INSTANTIATE_GUID(KSPROPSETID_Pin); + INSTANTIATE_GUID(KSPROPSETID_Connection); + INSTANTIATE_GUID(KSPROPSETID_Topology); + INSTANTIATE_GUID(KSINTERFACESETID_Standard); + INSTANTIATE_GUID(KSMEDIUMSETID_Standard); + INSTANTIATE_GUID(KSDATAFORMAT_TYPE_MUSIC); + INSTANTIATE_GUID(KSDATAFORMAT_SUBTYPE_MIDI); + INSTANTIATE_GUID(KSDATAFORMAT_SPECIFIER_NONE); #undef INSTANTIATE_GUID +namespace rtmidi { + typedef std::basic_string tstring; -typedef std::basic_string tstring; - -inline bool IsValid(HANDLE handle) -{ - return handle != NULL && handle != INVALID_HANDLE_VALUE; -} + inline bool IsValid(HANDLE handle) + { + return handle != NULL && handle != INVALID_HANDLE_VALUE; + } -class ComException : public std::runtime_error -{ -private: - static std::string MakeString(std::string const& s, HRESULT hr) - { - std::stringstream ss; - ss << "(error 0x" << std::hex << hr << ")"; - return s + ss.str(); - } - -public: - ComException(std::string const& s, HRESULT hr) : - std::runtime_error(MakeString(s, hr)) - { - } -}; - -template -class CKsEnumFilters -{ -public: - ~CKsEnumFilters() - { - DestroyLists(); - } - - void EnumFilters(GUID const* categories, size_t numCategories) - { - DestroyLists(); - - if (categories == 0) - throw std::runtime_error("CKsEnumFilters: invalid argument"); - - // Get a handle to the device set specified by the guid - HDEVINFO hDevInfo = ::SetupDiGetClassDevs(&categories[0], NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); - if (!IsValid(hDevInfo)) - throw std::runtime_error("CKsEnumFilters: no devices found"); - - // Loop through members of the set and get details for each - for ( int iClassMember=0; iClassMember++ ) { - try { - SP_DEVICE_INTERFACE_DATA DID; - DID.cbSize = sizeof(DID); - DID.Reserved = 0; - - bool fRes = ::SetupDiEnumDeviceInterfaces(hDevInfo, NULL, &categories[0], iClassMember, &DID); - if (!fRes) - break; - - // Get filter friendly name - HKEY hRegKey = ::SetupDiOpenDeviceInterfaceRegKey(hDevInfo, &DID, 0, KEY_READ); - if (hRegKey == INVALID_HANDLE_VALUE) - throw std::runtime_error("CKsEnumFilters: interface has no registry"); - - char friendlyName[256]; - DWORD dwSize = sizeof friendlyName; - LONG lval = ::RegQueryValueEx(hRegKey, TEXT("FriendlyName"), NULL, NULL, (LPBYTE)friendlyName, &dwSize); - ::RegCloseKey(hRegKey); - if (lval != ERROR_SUCCESS) - throw std::runtime_error("CKsEnumFilters: interface has no friendly name"); - - // Get details for the device registered in this class - DWORD const cbItfDetails = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA) + MAX_PATH * sizeof(WCHAR); - std::vector buffer(cbItfDetails); - - SP_DEVICE_INTERFACE_DETAIL_DATA* pDevInterfaceDetails = reinterpret_cast(&buffer[0]); - pDevInterfaceDetails->cbSize = sizeof(*pDevInterfaceDetails); - - SP_DEVINFO_DATA DevInfoData; - DevInfoData.cbSize = sizeof(DevInfoData); - DevInfoData.Reserved = 0; - - fRes = ::SetupDiGetDeviceInterfaceDetail(hDevInfo, &DID, pDevInterfaceDetails, cbItfDetails, NULL, &DevInfoData); - if (!fRes) - throw std::runtime_error("CKsEnumFilters: could not get interface details"); - - // check additional category guids which may (or may not) have been supplied - for (size_t i=1; i < numCategories; ++i) { - SP_DEVICE_INTERFACE_DATA DIDAlias; - DIDAlias.cbSize = sizeof(DIDAlias); - DIDAlias.Reserved = 0; - - fRes = ::SetupDiGetDeviceInterfaceAlias(hDevInfo, &DID, &categories[i], &DIDAlias); - if (!fRes) - throw std::runtime_error("CKsEnumFilters: could not get interface alias"); - - // Check if the this interface alias is enabled. - if (!DIDAlias.Flags || (DIDAlias.Flags & SPINT_REMOVED)) - throw std::runtime_error("CKsEnumFilters: interface alias is not enabled"); - } - - std::auto_ptr pFilter(new TFilterType(pDevInterfaceDetails->DevicePath, friendlyName)); - - pFilter->Instantiate(); - pFilter->FindMidiPins(); - pFilter->Validate(); - - m_Filters.push_back(pFilter.release()); - } - catch (std::runtime_error const& e) { - } - } - - ::SetupDiDestroyDeviceInfoList(hDevInfo); - } - -private: - void DestroyLists() - { - for (size_t i=0;i < m_Filters.size();++i) - delete m_Filters[i]; - m_Filters.clear(); - } - -public: - // TODO: make this private. - std::vector m_Filters; -}; - -class CKsObject -{ -public: - CKsObject(HANDLE handle) : m_handle(handle) - { - } - -protected: - HANDLE m_handle; - - void SetProperty(REFGUID guidPropertySet, ULONG nProperty, void* pvValue, ULONG cbValue) - { - KSPROPERTY ksProperty; - memset(&ksProperty, 0, sizeof ksProperty); - ksProperty.Set = guidPropertySet; - ksProperty.Id = nProperty; - ksProperty.Flags = KSPROPERTY_TYPE_SET; - - HRESULT hr = DeviceIoControlKsProperty(ksProperty, pvValue, cbValue); - if (FAILED(hr)) - throw ComException("CKsObject::SetProperty: could not set property", hr); - } - -private: - - HRESULT DeviceIoControlKsProperty(KSPROPERTY& ksProperty, void* pvValue, ULONG cbValue) - { - ULONG ulReturned; - return ::DeviceIoControl( - m_handle, - IOCTL_KS_PROPERTY, - &ksProperty, - sizeof(ksProperty), - pvValue, - cbValue, - &ulReturned, - NULL); - } -}; - -class CKsPin; - -class CKsFilter : public CKsObject -{ - friend class CKsPin; - -public: - CKsFilter(tstring const& name, std::string const& sFriendlyName); - virtual ~CKsFilter(); - - virtual void Instantiate(); - - template - T GetPinProperty(ULONG nPinId, ULONG nProperty) - { - ULONG ulReturned = 0; - T value; - - KSP_PIN ksPProp; - ksPProp.Property.Set = KSPROPSETID_Pin; - ksPProp.Property.Id = nProperty; - ksPProp.Property.Flags = KSPROPERTY_TYPE_GET; - ksPProp.PinId = nPinId; - ksPProp.Reserved = 0; - - HRESULT hr = ::DeviceIoControl( - m_handle, - IOCTL_KS_PROPERTY, - &ksPProp, - sizeof(KSP_PIN), - &value, - sizeof(value), - &ulReturned, - NULL); - if (FAILED(hr)) - throw ComException("CKsFilter::GetPinProperty: failed to retrieve property", hr); - - return value; - } - - void GetPinPropertyMulti(ULONG nPinId, REFGUID guidPropertySet, ULONG nProperty, PKSMULTIPLE_ITEM* ppKsMultipleItem) - { - HRESULT hr; - - KSP_PIN ksPProp; - ksPProp.Property.Set = guidPropertySet; - ksPProp.Property.Id = nProperty; - ksPProp.Property.Flags = KSPROPERTY_TYPE_GET; - ksPProp.PinId = nPinId; - ksPProp.Reserved = 0; - - ULONG cbMultipleItem = 0; - hr = ::DeviceIoControl(m_handle, - IOCTL_KS_PROPERTY, - &ksPProp.Property, - sizeof(KSP_PIN), - NULL, - 0, - &cbMultipleItem, - NULL); - if (FAILED(hr)) - throw ComException("CKsFilter::GetPinPropertyMulti: cannot get property", hr); - - *ppKsMultipleItem = (PKSMULTIPLE_ITEM) new BYTE[cbMultipleItem]; - - ULONG ulReturned = 0; - hr = ::DeviceIoControl( - m_handle, - IOCTL_KS_PROPERTY, - &ksPProp, - sizeof(KSP_PIN), - (PVOID)*ppKsMultipleItem, - cbMultipleItem, - &ulReturned, - NULL); - if (FAILED(hr)) - throw ComException("CKsFilter::GetPinPropertyMulti: cannot get property", hr); - } - - std::string const& GetFriendlyName() const - { - return m_sFriendlyName; - } - -protected: - - std::vector m_Pins; // this list owns the pins. - - std::vector m_RenderPins; - std::vector m_CapturePins; - -private: - std::string const m_sFriendlyName; // friendly name eg "Virus TI Synth" - tstring const m_sName; // Filter path, eg "\\?\usb#vid_133e&pid_0815...\vtimidi02" -}; - -class CKsPin : public CKsObject -{ -public: - CKsPin(CKsFilter* pFilter, ULONG nId); - virtual ~CKsPin(); - - virtual void Instantiate(); - - void ClosePin(); - - void SetState(KSSTATE ksState); - - void WriteData(KSSTREAM_HEADER* pKSSTREAM_HEADER, OVERLAPPED* pOVERLAPPED); - void ReadData(KSSTREAM_HEADER* pKSSTREAM_HEADER, OVERLAPPED* pOVERLAPPED); - - KSPIN_DATAFLOW GetDataFlow() const - { - return m_DataFlow; - } - - bool IsSink() const - { - return m_Communication == KSPIN_COMMUNICATION_SINK - || m_Communication == KSPIN_COMMUNICATION_BOTH; - } - - -protected: - PKSPIN_CONNECT m_pKsPinConnect; // creation parameters of pin - CKsFilter* const m_pFilter; - - ULONG m_cInterfaces; - PKSIDENTIFIER m_pInterfaces; - PKSMULTIPLE_ITEM m_pmiInterfaces; - - ULONG m_cMediums; - PKSIDENTIFIER m_pMediums; - PKSMULTIPLE_ITEM m_pmiMediums; - - ULONG m_cDataRanges; - PKSDATARANGE m_pDataRanges; - PKSMULTIPLE_ITEM m_pmiDataRanges; - - KSPIN_DATAFLOW m_DataFlow; - KSPIN_COMMUNICATION m_Communication; -}; - -CKsFilter::CKsFilter(tstring const& sName, std::string const& sFriendlyName) : - CKsObject(INVALID_HANDLE_VALUE), - m_sFriendlyName(sFriendlyName), - m_sName(sName) -{ - if (sName.empty()) - throw std::runtime_error("CKsFilter::CKsFilter: name can't be empty"); -} + class ComException : public std::runtime_error + { + private: + static std::string MakeString(std::string const& s, HRESULT hr) + { + std::stringstream ss; + ss << "(error 0x" << std::hex << hr << ")"; + return s + ss.str(); + } + + public: + ComException(std::string const& s, HRESULT hr) : + std::runtime_error(MakeString(s, hr)) + { + } + }; + + template + class CKsEnumFilters + { + public: + ~CKsEnumFilters() + { + DestroyLists(); + } + + void EnumFilters(GUID const* categories, size_t numCategories) + { + DestroyLists(); + + if (categories == 0) + throw std::runtime_error("CKsEnumFilters: invalid argument"); + + // Get a handle to the device set specified by the guid + HDEVINFO hDevInfo = ::SetupDiGetClassDevs(&categories[0], NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); + if (!IsValid(hDevInfo)) + throw std::runtime_error("CKsEnumFilters: no devices found"); + + // Loop through members of the set and get details for each + for ( int iClassMember=0; iClassMember++ ) { + try { + SP_DEVICE_INTERFACE_DATA DID; + DID.cbSize = sizeof(DID); + DID.Reserved = 0; + + bool fRes = ::SetupDiEnumDeviceInterfaces(hDevInfo, NULL, &categories[0], iClassMember, &DID); + if (!fRes) + break; + + // Get filter friendly name + HKEY hRegKey = ::SetupDiOpenDeviceInterfaceRegKey(hDevInfo, &DID, 0, KEY_READ); + if (hRegKey == INVALID_HANDLE_VALUE) + throw std::runtime_error("CKsEnumFilters: interface has no registry"); + + char friendlyName[256]; + DWORD dwSize = sizeof friendlyName; + LONG lval = ::RegQueryValueEx(hRegKey, TEXT("FriendlyName"), NULL, NULL, (LPBYTE)friendlyName, &dwSize); + ::RegCloseKey(hRegKey); + if (lval != ERROR_SUCCESS) + throw std::runtime_error("CKsEnumFilters: interface has no friendly name"); + + // Get details for the device registered in this class + DWORD const cbItfDetails = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA) + MAX_PATH * sizeof(WCHAR); + std::vector buffer(cbItfDetails); + + SP_DEVICE_INTERFACE_DETAIL_DATA* pDevInterfaceDetails = reinterpret_cast(&buffer[0]); + pDevInterfaceDetails->cbSize = sizeof(*pDevInterfaceDetails); + + SP_DEVINFO_DATA DevInfoData; + DevInfoData.cbSize = sizeof(DevInfoData); + DevInfoData.Reserved = 0; + + fRes = ::SetupDiGetDeviceInterfaceDetail(hDevInfo, &DID, pDevInterfaceDetails, cbItfDetails, NULL, &DevInfoData); + if (!fRes) + throw std::runtime_error("CKsEnumFilters: could not get interface details"); + + // check additional category guids which may (or may not) have been supplied + for (size_t i=1; i < numCategories; ++i) { + SP_DEVICE_INTERFACE_DATA DIDAlias; + DIDAlias.cbSize = sizeof(DIDAlias); + DIDAlias.Reserved = 0; + + fRes = ::SetupDiGetDeviceInterfaceAlias(hDevInfo, &DID, &categories[i], &DIDAlias); + if (!fRes) + throw std::runtime_error("CKsEnumFilters: could not get interface alias"); + + // Check if the this interface alias is enabled. + if (!DIDAlias.Flags || (DIDAlias.Flags & SPINT_REMOVED)) + throw std::runtime_error("CKsEnumFilters: interface alias is not enabled"); + } + + std::auto_ptr pFilter(new TFilterType(pDevInterfaceDetails->DevicePath, friendlyName)); + + pFilter->Instantiate(); + pFilter->FindMidiPins(); + pFilter->Validate(); + + m_Filters.push_back(pFilter.release()); + } + catch (std::runtime_error const& e) { + } + } + + ::SetupDiDestroyDeviceInfoList(hDevInfo); + } + + private: + void DestroyLists() + { + for (size_t i=0;i < m_Filters.size();++i) + delete m_Filters[i]; + m_Filters.clear(); + } + + public: + // TODO: make this private. + std::vector m_Filters; + }; + + class CKsObject + { + public: + CKsObject(HANDLE handle) : m_handle(handle) + { + } + + protected: + HANDLE m_handle; + + void SetProperty(REFGUID guidPropertySet, ULONG nProperty, void* pvValue, ULONG cbValue) + { + KSPROPERTY ksProperty; + memset(&ksProperty, 0, sizeof ksProperty); + ksProperty.Set = guidPropertySet; + ksProperty.Id = nProperty; + ksProperty.Flags = KSPROPERTY_TYPE_SET; + + HRESULT hr = DeviceIoControlKsProperty(ksProperty, pvValue, cbValue); + if (FAILED(hr)) + throw ComException("CKsObject::SetProperty: could not set property", hr); + } + + private: + + HRESULT DeviceIoControlKsProperty(KSPROPERTY& ksProperty, void* pvValue, ULONG cbValue) + { + ULONG ulReturned; + return ::DeviceIoControl( + m_handle, + IOCTL_KS_PROPERTY, + &ksProperty, + sizeof(ksProperty), + pvValue, + cbValue, + &ulReturned, + NULL); + } + }; + + class CKsPin; + + class CKsFilter : public CKsObject + { + friend class CKsPin; + + public: + CKsFilter(tstring const& name, std::string const& sFriendlyName); + virtual ~CKsFilter(); + + virtual void Instantiate(); + + template + T GetPinProperty(ULONG nPinId, ULONG nProperty) + { + ULONG ulReturned = 0; + T value; + + KSP_PIN ksPProp; + ksPProp.Property.Set = KSPROPSETID_Pin; + ksPProp.Property.Id = nProperty; + ksPProp.Property.Flags = KSPROPERTY_TYPE_GET; + ksPProp.PinId = nPinId; + ksPProp.Reserved = 0; + + HRESULT hr = ::DeviceIoControl( + m_handle, + IOCTL_KS_PROPERTY, + &ksPProp, + sizeof(KSP_PIN), + &value, + sizeof(value), + &ulReturned, + NULL); + if (FAILED(hr)) + throw ComException("CKsFilter::GetPinProperty: failed to retrieve property", hr); + + return value; + } + + void GetPinPropertyMulti(ULONG nPinId, REFGUID guidPropertySet, ULONG nProperty, PKSMULTIPLE_ITEM* ppKsMultipleItem) + { + HRESULT hr; + + KSP_PIN ksPProp; + ksPProp.Property.Set = guidPropertySet; + ksPProp.Property.Id = nProperty; + ksPProp.Property.Flags = KSPROPERTY_TYPE_GET; + ksPProp.PinId = nPinId; + ksPProp.Reserved = 0; + + ULONG cbMultipleItem = 0; + hr = ::DeviceIoControl(m_handle, + IOCTL_KS_PROPERTY, + &ksPProp.Property, + sizeof(KSP_PIN), + NULL, + 0, + &cbMultipleItem, + NULL); + if (FAILED(hr)) + throw ComException("CKsFilter::GetPinPropertyMulti: cannot get property", hr); + + *ppKsMultipleItem = (PKSMULTIPLE_ITEM) new BYTE[cbMultipleItem]; + + ULONG ulReturned = 0; + hr = ::DeviceIoControl( + m_handle, + IOCTL_KS_PROPERTY, + &ksPProp, + sizeof(KSP_PIN), + (PVOID)*ppKsMultipleItem, + cbMultipleItem, + &ulReturned, + NULL); + if (FAILED(hr)) + throw ComException("CKsFilter::GetPinPropertyMulti: cannot get property", hr); + } + + std::string const& GetFriendlyName() const + { + return m_sFriendlyName; + } + + protected: + + std::vector m_Pins; // this list owns the pins. + + std::vector m_RenderPins; + std::vector m_CapturePins; + + private: + std::string const m_sFriendlyName; // friendly name eg "Virus TI Synth" + tstring const m_sName; // Filter path, eg "\\?\usb#vid_133e&pid_0815...\vtimidi02" + }; + + class CKsPin : public CKsObject + { + public: + CKsPin(CKsFilter* pFilter, ULONG nId); + virtual ~CKsPin(); + + virtual void Instantiate(); + + void ClosePin(); + + void SetState(KSSTATE ksState); + + void WriteData(KSSTREAM_HEADER* pKSSTREAM_HEADER, OVERLAPPED* pOVERLAPPED); + void ReadData(KSSTREAM_HEADER* pKSSTREAM_HEADER, OVERLAPPED* pOVERLAPPED); + + KSPIN_DATAFLOW GetDataFlow() const + { + return m_DataFlow; + } + + bool IsSink() const + { + return m_Communication == KSPIN_COMMUNICATION_SINK + || m_Communication == KSPIN_COMMUNICATION_BOTH; + } + + + protected: + PKSPIN_CONNECT m_pKsPinConnect; // creation parameters of pin + CKsFilter* const m_pFilter; + + ULONG m_cInterfaces; + PKSIDENTIFIER m_pInterfaces; + PKSMULTIPLE_ITEM m_pmiInterfaces; + + ULONG m_cMediums; + PKSIDENTIFIER m_pMediums; + PKSMULTIPLE_ITEM m_pmiMediums; + + ULONG m_cDataRanges; + PKSDATARANGE m_pDataRanges; + PKSMULTIPLE_ITEM m_pmiDataRanges; + + KSPIN_DATAFLOW m_DataFlow; + KSPIN_COMMUNICATION m_Communication; + }; + + CKsFilter::CKsFilter(tstring const& sName, std::string const& sFriendlyName) : + CKsObject(INVALID_HANDLE_VALUE), + m_sFriendlyName(sFriendlyName), + m_sName(sName) + { + if (sName.empty()) + throw std::runtime_error("CKsFilter::CKsFilter: name can't be empty"); + } -CKsFilter::~CKsFilter() -{ - for (size_t i=0;i < m_Pins.size();++i) - delete m_Pins[i]; + CKsFilter::~CKsFilter() + { + for (size_t i=0;i < m_Pins.size();++i) + delete m_Pins[i]; - if (IsValid(m_handle)) - ::CloseHandle(m_handle); -} + if (IsValid(m_handle)) + ::CloseHandle(m_handle); + } -void CKsFilter::Instantiate() -{ - m_handle = CreateFile( - m_sName.c_str(), - GENERIC_READ | GENERIC_WRITE, - 0, - NULL, - OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, - NULL); - - if (!IsValid(m_handle)) - { - DWORD const dwError = GetLastError(); - throw ComException("CKsFilter::Instantiate: can't open driver", HRESULT_FROM_WIN32(dwError)); - } -} + void CKsFilter::Instantiate() + { + m_handle = CreateFile( + m_sName.c_str(), + GENERIC_READ | GENERIC_WRITE, + 0, + NULL, + OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, + NULL); + + if (!IsValid(m_handle)) + { + DWORD const dwError = GetLastError(); + throw ComException("CKsFilter::Instantiate: can't open driver", HRESULT_FROM_WIN32(dwError)); + } + } -CKsPin::CKsPin(CKsFilter* pFilter, ULONG PinId) : - CKsObject(INVALID_HANDLE_VALUE), - m_pKsPinConnect(NULL), - m_pFilter(pFilter) -{ - m_Communication = m_pFilter->GetPinProperty(PinId, KSPROPERTY_PIN_COMMUNICATION); - m_DataFlow = m_pFilter->GetPinProperty(PinId, KSPROPERTY_PIN_DATAFLOW); - - // Interfaces - m_pFilter->GetPinPropertyMulti( - PinId, - KSPROPSETID_Pin, - KSPROPERTY_PIN_INTERFACES, - &m_pmiInterfaces); - - m_cInterfaces = m_pmiInterfaces->Count; - m_pInterfaces = (PKSPIN_INTERFACE)(m_pmiInterfaces + 1); - - // Mediums - m_pFilter->GetPinPropertyMulti( - PinId, - KSPROPSETID_Pin, - KSPROPERTY_PIN_MEDIUMS, - &m_pmiMediums); - - m_cMediums = m_pmiMediums->Count; - m_pMediums = (PKSPIN_MEDIUM)(m_pmiMediums + 1); - - // Data ranges - m_pFilter->GetPinPropertyMulti( - PinId, - KSPROPSETID_Pin, - KSPROPERTY_PIN_DATARANGES, - &m_pmiDataRanges); - - m_cDataRanges = m_pmiDataRanges->Count; - m_pDataRanges = (PKSDATARANGE)(m_pmiDataRanges + 1); -} + CKsPin::CKsPin(CKsFilter* pFilter, ULONG PinId) : + CKsObject(INVALID_HANDLE_VALUE), + m_pKsPinConnect(NULL), + m_pFilter(pFilter) + { + m_Communication = m_pFilter->GetPinProperty(PinId, KSPROPERTY_PIN_COMMUNICATION); + m_DataFlow = m_pFilter->GetPinProperty(PinId, KSPROPERTY_PIN_DATAFLOW); + + // Interfaces + m_pFilter->GetPinPropertyMulti( + PinId, + KSPROPSETID_Pin, + KSPROPERTY_PIN_INTERFACES, + &m_pmiInterfaces); + + m_cInterfaces = m_pmiInterfaces->Count; + m_pInterfaces = (PKSPIN_INTERFACE)(m_pmiInterfaces + 1); + + // Mediums + m_pFilter->GetPinPropertyMulti( + PinId, + KSPROPSETID_Pin, + KSPROPERTY_PIN_MEDIUMS, + &m_pmiMediums); + + m_cMediums = m_pmiMediums->Count; + m_pMediums = (PKSPIN_MEDIUM)(m_pmiMediums + 1); + + // Data ranges + m_pFilter->GetPinPropertyMulti( + PinId, + KSPROPSETID_Pin, + KSPROPERTY_PIN_DATARANGES, + &m_pmiDataRanges); + + m_cDataRanges = m_pmiDataRanges->Count; + m_pDataRanges = (PKSDATARANGE)(m_pmiDataRanges + 1); + } -CKsPin::~CKsPin() -{ - ClosePin(); + CKsPin::~CKsPin() + { + ClosePin(); - delete[] (BYTE*)m_pKsPinConnect; - delete[] (BYTE*)m_pmiDataRanges; - delete[] (BYTE*)m_pmiInterfaces; - delete[] (BYTE*)m_pmiMediums; -} + delete[] (BYTE*)m_pKsPinConnect; + delete[] (BYTE*)m_pmiDataRanges; + delete[] (BYTE*)m_pmiInterfaces; + delete[] (BYTE*)m_pmiMediums; + } -void CKsPin::ClosePin() -{ - if (IsValid(m_handle)) { - SetState(KSSTATE_STOP); - ::CloseHandle(m_handle); - } - m_handle = INVALID_HANDLE_VALUE; -} + void CKsPin::ClosePin() + { + if (IsValid(m_handle)) { + SetState(KSSTATE_STOP); + ::CloseHandle(m_handle); + } + m_handle = INVALID_HANDLE_VALUE; + } -void CKsPin::SetState(KSSTATE ksState) -{ - SetProperty(KSPROPSETID_Connection, KSPROPERTY_CONNECTION_STATE, &ksState, sizeof(ksState)); -} + void CKsPin::SetState(KSSTATE ksState) + { + SetProperty(KSPROPSETID_Connection, KSPROPERTY_CONNECTION_STATE, &ksState, sizeof(ksState)); + } -void CKsPin::Instantiate() -{ - if (!m_pKsPinConnect) - throw std::runtime_error("CKsPin::Instanciate: abstract pin"); + void CKsPin::Instantiate() + { + if (!m_pKsPinConnect) + throw std::runtime_error("CKsPin::Instanciate: abstract pin"); - DWORD const dwResult = KsCreatePin(m_pFilter->m_handle, m_pKsPinConnect, GENERIC_WRITE | GENERIC_READ, &m_handle); - if (dwResult != ERROR_SUCCESS) - throw ComException("CKsMidiCapFilter::CreateRenderPin: Pin instanciation failed", HRESULT_FROM_WIN32(dwResult)); -} + DWORD const dwResult = KsCreatePin(m_pFilter->m_handle, m_pKsPinConnect, GENERIC_WRITE | GENERIC_READ, &m_handle); + if (dwResult != ERROR_SUCCESS) + throw ComException("CKsMidiCapFilter::CreateRenderPin: Pin instanciation failed", HRESULT_FROM_WIN32(dwResult)); + } -void CKsPin::WriteData(KSSTREAM_HEADER* pKSSTREAM_HEADER, OVERLAPPED* pOVERLAPPED) -{ - DWORD cbWritten; - BOOL fRes = ::DeviceIoControl( - m_handle, - IOCTL_KS_WRITE_STREAM, - NULL, - 0, - pKSSTREAM_HEADER, - pKSSTREAM_HEADER->Size, - &cbWritten, - pOVERLAPPED); - if (!fRes) { - DWORD const dwError = GetLastError(); - if (dwError != ERROR_IO_PENDING) - throw ComException("CKsPin::WriteData: DeviceIoControl failed", HRESULT_FROM_WIN32(dwError)); - } -} + void CKsPin::WriteData(KSSTREAM_HEADER* pKSSTREAM_HEADER, OVERLAPPED* pOVERLAPPED) + { + DWORD cbWritten; + BOOL fRes = ::DeviceIoControl( + m_handle, + IOCTL_KS_WRITE_STREAM, + NULL, + 0, + pKSSTREAM_HEADER, + pKSSTREAM_HEADER->Size, + &cbWritten, + pOVERLAPPED); + if (!fRes) { + DWORD const dwError = GetLastError(); + if (dwError != ERROR_IO_PENDING) + throw ComException("CKsPin::WriteData: DeviceIoControl failed", HRESULT_FROM_WIN32(dwError)); + } + } -void CKsPin::ReadData(KSSTREAM_HEADER* pKSSTREAM_HEADER, OVERLAPPED* pOVERLAPPED) -{ - DWORD cbReturned; - BOOL fRes = ::DeviceIoControl( - m_handle, - IOCTL_KS_READ_STREAM, - NULL, - 0, - pKSSTREAM_HEADER, - pKSSTREAM_HEADER->Size, - &cbReturned, - pOVERLAPPED); - if (!fRes) { - DWORD const dwError = GetLastError(); - if (dwError != ERROR_IO_PENDING) - throw ComException("CKsPin::ReadData: DeviceIoControl failed", HRESULT_FROM_WIN32(dwError)); - } -} + void CKsPin::ReadData(KSSTREAM_HEADER* pKSSTREAM_HEADER, OVERLAPPED* pOVERLAPPED) + { + DWORD cbReturned; + BOOL fRes = ::DeviceIoControl( + m_handle, + IOCTL_KS_READ_STREAM, + NULL, + 0, + pKSSTREAM_HEADER, + pKSSTREAM_HEADER->Size, + &cbReturned, + pOVERLAPPED); + if (!fRes) { + DWORD const dwError = GetLastError(); + if (dwError != ERROR_IO_PENDING) + throw ComException("CKsPin::ReadData: DeviceIoControl failed", HRESULT_FROM_WIN32(dwError)); + } + } -class CKsMidiFilter : public CKsFilter -{ -public: - void FindMidiPins(); - -protected: - CKsMidiFilter(tstring const& sPath, std::string const& sFriendlyName); -}; - -class CKsMidiPin : public CKsPin -{ -public: - CKsMidiPin(CKsFilter* pFilter, ULONG nId); -}; - -class CKsMidiRenFilter : public CKsMidiFilter -{ -public: - CKsMidiRenFilter(tstring const& sPath, std::string const& sFriendlyName); - CKsMidiPin* CreateRenderPin(); - - void Validate() - { - if (m_RenderPins.empty()) - throw std::runtime_error("Could not find a MIDI render pin"); - } -}; - -class CKsMidiCapFilter : public CKsMidiFilter -{ -public: - CKsMidiCapFilter(tstring const& sPath, std::string const& sFriendlyName); - CKsMidiPin* CreateCapturePin(); - - void Validate() - { - if (m_CapturePins.empty()) - throw std::runtime_error("Could not find a MIDI capture pin"); - } -}; - -CKsMidiFilter::CKsMidiFilter(tstring const& sPath, std::string const& sFriendlyName) : - CKsFilter(sPath, sFriendlyName) -{ -} + class CKsMidiFilter : public CKsFilter + { + public: + void FindMidiPins(); + + protected: + CKsMidiFilter(tstring const& sPath, std::string const& sFriendlyName); + }; + + class CKsMidiPin : public CKsPin + { + public: + CKsMidiPin(CKsFilter* pFilter, ULONG nId); + }; + + class CKsMidiRenFilter : public CKsMidiFilter + { + public: + CKsMidiRenFilter(tstring const& sPath, std::string const& sFriendlyName); + CKsMidiPin* CreateRenderPin(); + + void Validate() + { + if (m_RenderPins.empty()) + throw std::runtime_error("Could not find a MIDI render pin"); + } + }; + + class CKsMidiCapFilter : public CKsMidiFilter + { + public: + CKsMidiCapFilter(tstring const& sPath, std::string const& sFriendlyName); + CKsMidiPin* CreateCapturePin(); + + void Validate() + { + if (m_CapturePins.empty()) + throw std::runtime_error("Could not find a MIDI capture pin"); + } + }; + + CKsMidiFilter::CKsMidiFilter(tstring const& sPath, std::string const& sFriendlyName) : + CKsFilter(sPath, sFriendlyName) + { + } -void CKsMidiFilter::FindMidiPins() -{ - ULONG numPins = GetPinProperty(0, KSPROPERTY_PIN_CTYPES); - - for (ULONG iPin = 0; iPin < numPins; ++iPin) { - try { - KSPIN_COMMUNICATION com = GetPinProperty(iPin, KSPROPERTY_PIN_COMMUNICATION); - if (com != KSPIN_COMMUNICATION_SINK && com != KSPIN_COMMUNICATION_BOTH) - throw std::runtime_error("Unknown pin communication value"); - - m_Pins.push_back(new CKsMidiPin(this, iPin)); - } - catch (std::runtime_error const&) { - // pin instanciation has failed, continue to the next pin. - } - } - - m_RenderPins.clear(); - m_CapturePins.clear(); - - for (size_t i = 0; i < m_Pins.size(); ++i) { - CKsPin* const pPin = m_Pins[i]; - - if (pPin->IsSink()) { - if (pPin->GetDataFlow() == KSPIN_DATAFLOW_IN) - m_RenderPins.push_back(pPin); - else - m_CapturePins.push_back(pPin); - } - } - - if (m_RenderPins.empty() && m_CapturePins.empty()) - throw std::runtime_error("No valid pins found on the filter."); -} + void CKsMidiFilter::FindMidiPins() + { + ULONG numPins = GetPinProperty(0, KSPROPERTY_PIN_CTYPES); + + for (ULONG iPin = 0; iPin < numPins; ++iPin) { + try { + KSPIN_COMMUNICATION com = GetPinProperty(iPin, KSPROPERTY_PIN_COMMUNICATION); + if (com != KSPIN_COMMUNICATION_SINK && com != KSPIN_COMMUNICATION_BOTH) + throw std::runtime_error("Unknown pin communication value"); + + m_Pins.push_back(new CKsMidiPin(this, iPin)); + } + catch (std::runtime_error const&) { + // pin instanciation has failed, continue to the next pin. + } + } + + m_RenderPins.clear(); + m_CapturePins.clear(); + + for (size_t i = 0; i < m_Pins.size(); ++i) { + CKsPin* const pPin = m_Pins[i]; + + if (pPin->IsSink()) { + if (pPin->GetDataFlow() == KSPIN_DATAFLOW_IN) + m_RenderPins.push_back(pPin); + else + m_CapturePins.push_back(pPin); + } + } + + if (m_RenderPins.empty() && m_CapturePins.empty()) + throw std::runtime_error("No valid pins found on the filter."); + } -CKsMidiRenFilter::CKsMidiRenFilter(tstring const& sPath, std::string const& sFriendlyName) : - CKsMidiFilter(sPath, sFriendlyName) -{ -} + CKsMidiRenFilter::CKsMidiRenFilter(tstring const& sPath, std::string const& sFriendlyName) : + CKsMidiFilter(sPath, sFriendlyName) + { + } -CKsMidiPin* CKsMidiRenFilter::CreateRenderPin() -{ - if (m_RenderPins.empty()) - throw std::runtime_error("Could not find a MIDI render pin"); + CKsMidiPin* CKsMidiRenFilter::CreateRenderPin() + { + if (m_RenderPins.empty()) + throw std::runtime_error("Could not find a MIDI render pin"); - CKsMidiPin* pPin = (CKsMidiPin*)m_RenderPins[0]; - pPin->Instantiate(); - return pPin; -} + CKsMidiPin* pPin = (CKsMidiPin*)m_RenderPins[0]; + pPin->Instantiate(); + return pPin; + } -CKsMidiCapFilter::CKsMidiCapFilter(tstring const& sPath, std::string const& sFriendlyName) : - CKsMidiFilter(sPath, sFriendlyName) -{ -} + CKsMidiCapFilter::CKsMidiCapFilter(tstring const& sPath, std::string const& sFriendlyName) : + CKsMidiFilter(sPath, sFriendlyName) + { + } -CKsMidiPin* CKsMidiCapFilter::CreateCapturePin() -{ - if (m_CapturePins.empty()) - throw std::runtime_error("Could not find a MIDI capture pin"); + CKsMidiPin* CKsMidiCapFilter::CreateCapturePin() + { + if (m_CapturePins.empty()) + throw std::runtime_error("Could not find a MIDI capture pin"); - CKsMidiPin* pPin = (CKsMidiPin*)m_CapturePins[0]; - pPin->Instantiate(); - return pPin; -} + CKsMidiPin* pPin = (CKsMidiPin*)m_CapturePins[0]; + pPin->Instantiate(); + return pPin; + } -CKsMidiPin::CKsMidiPin(CKsFilter* pFilter, ULONG nId) : - CKsPin(pFilter, nId) -{ - DWORD const cbPinCreateSize = sizeof(KSPIN_CONNECT) + sizeof(KSDATAFORMAT); - m_pKsPinConnect = (PKSPIN_CONNECT) new BYTE[cbPinCreateSize]; - - m_pKsPinConnect->Interface.Set = KSINTERFACESETID_Standard; - m_pKsPinConnect->Interface.Id = KSINTERFACE_STANDARD_STREAMING; - m_pKsPinConnect->Interface.Flags = 0; - m_pKsPinConnect->Medium.Set = KSMEDIUMSETID_Standard; - m_pKsPinConnect->Medium.Id = KSMEDIUM_TYPE_ANYINSTANCE; - m_pKsPinConnect->Medium.Flags = 0; - m_pKsPinConnect->PinId = nId; - m_pKsPinConnect->PinToHandle = NULL; - m_pKsPinConnect->Priority.PriorityClass = KSPRIORITY_NORMAL; - m_pKsPinConnect->Priority.PrioritySubClass = 1; - - // point m_pDataFormat to just after the pConnect struct - KSDATAFORMAT* m_pDataFormat = (KSDATAFORMAT*)(m_pKsPinConnect + 1); - m_pDataFormat->FormatSize = sizeof(KSDATAFORMAT); - m_pDataFormat->Flags = 0; - m_pDataFormat->SampleSize = 0; - m_pDataFormat->Reserved = 0; - m_pDataFormat->MajorFormat = GUID(KSDATAFORMAT_TYPE_MUSIC); - m_pDataFormat->SubFormat = GUID(KSDATAFORMAT_SUBTYPE_MIDI); - m_pDataFormat->Specifier = GUID(KSDATAFORMAT_SPECIFIER_NONE); - - bool hasStdStreamingInterface = false; - bool hasStdStreamingMedium = false; - - for ( ULONG i = 0; i < m_cInterfaces; i++ ) { - if (m_pInterfaces[i].Set == KSINTERFACESETID_Standard - && m_pInterfaces[i].Id == KSINTERFACE_STANDARD_STREAMING) - hasStdStreamingInterface = true; - } - - for (ULONG i = 0; i < m_cMediums; i++) { - if (m_pMediums[i].Set == KSMEDIUMSETID_Standard - && m_pMediums[i].Id == KSMEDIUM_STANDARD_DEVIO) - hasStdStreamingMedium = true; - } - - if (!hasStdStreamingInterface) // No standard streaming interfaces on the pin - throw std::runtime_error("CKsMidiPin::CKsMidiPin: no standard streaming interface"); - - if (!hasStdStreamingMedium) // No standard streaming mediums on the pin - throw std::runtime_error("CKsMidiPin::CKsMidiPin: no standard streaming medium"); - - bool hasMidiDataRange = false; - - BYTE const* pDataRangePtr = reinterpret_cast(m_pDataRanges); - - for (ULONG i = 0; i < m_cDataRanges; ++i) { - KSDATARANGE const* pDataRange = reinterpret_cast(pDataRangePtr); - - if (pDataRange->SubFormat == KSDATAFORMAT_SUBTYPE_MIDI) { - hasMidiDataRange = true; - break; - } - - pDataRangePtr += pDataRange->FormatSize; - } - - if (!hasMidiDataRange) // No MIDI dataranges on the pin - throw std::runtime_error("CKsMidiPin::CKsMidiPin: no MIDI datarange"); -} + CKsMidiPin::CKsMidiPin(CKsFilter* pFilter, ULONG nId) : + CKsPin(pFilter, nId) + { + DWORD const cbPinCreateSize = sizeof(KSPIN_CONNECT) + sizeof(KSDATAFORMAT); + m_pKsPinConnect = (PKSPIN_CONNECT) new BYTE[cbPinCreateSize]; + + m_pKsPinConnect->Interface.Set = KSINTERFACESETID_Standard; + m_pKsPinConnect->Interface.Id = KSINTERFACE_STANDARD_STREAMING; + m_pKsPinConnect->Interface.Flags = 0; + m_pKsPinConnect->Medium.Set = KSMEDIUMSETID_Standard; + m_pKsPinConnect->Medium.Id = KSMEDIUM_TYPE_ANYINSTANCE; + m_pKsPinConnect->Medium.Flags = 0; + m_pKsPinConnect->PinId = nId; + m_pKsPinConnect->PinToHandle = NULL; + m_pKsPinConnect->Priority.PriorityClass = KSPRIORITY_NORMAL; + m_pKsPinConnect->Priority.PrioritySubClass = 1; + + // point m_pDataFormat to just after the pConnect struct + KSDATAFORMAT* m_pDataFormat = (KSDATAFORMAT*)(m_pKsPinConnect + 1); + m_pDataFormat->FormatSize = sizeof(KSDATAFORMAT); + m_pDataFormat->Flags = 0; + m_pDataFormat->SampleSize = 0; + m_pDataFormat->Reserved = 0; + m_pDataFormat->MajorFormat = GUID(KSDATAFORMAT_TYPE_MUSIC); + m_pDataFormat->SubFormat = GUID(KSDATAFORMAT_SUBTYPE_MIDI); + m_pDataFormat->Specifier = GUID(KSDATAFORMAT_SPECIFIER_NONE); + + bool hasStdStreamingInterface = false; + bool hasStdStreamingMedium = false; + + for ( ULONG i = 0; i < m_cInterfaces; i++ ) { + if (m_pInterfaces[i].Set == KSINTERFACESETID_Standard + && m_pInterfaces[i].Id == KSINTERFACE_STANDARD_STREAMING) + hasStdStreamingInterface = true; + } + + for (ULONG i = 0; i < m_cMediums; i++) { + if (m_pMediums[i].Set == KSMEDIUMSETID_Standard + && m_pMediums[i].Id == KSMEDIUM_STANDARD_DEVIO) + hasStdStreamingMedium = true; + } + + if (!hasStdStreamingInterface) // No standard streaming interfaces on the pin + throw std::runtime_error("CKsMidiPin::CKsMidiPin: no standard streaming interface"); + + if (!hasStdStreamingMedium) // No standard streaming mediums on the pin + throw std::runtime_error("CKsMidiPin::CKsMidiPin: no standard streaming medium"); + + bool hasMidiDataRange = false; + + BYTE const* pDataRangePtr = reinterpret_cast(m_pDataRanges); + + for (ULONG i = 0; i < m_cDataRanges; ++i) { + KSDATARANGE const* pDataRange = reinterpret_cast(pDataRangePtr); + + if (pDataRange->SubFormat == KSDATAFORMAT_SUBTYPE_MIDI) { + hasMidiDataRange = true; + break; + } + + pDataRangePtr += pDataRange->FormatSize; + } + + if (!hasMidiDataRange) // No MIDI dataranges on the pin + throw std::runtime_error("CKsMidiPin::CKsMidiPin: no MIDI datarange"); + } -struct WindowsKsData -{ - WindowsKsData() : m_pPin(NULL), m_Buffer(1024), m_hInputThread(NULL) - { - memset(&overlapped, 0, sizeof(OVERLAPPED)); - m_hExitEvent = ::CreateEvent(NULL, FALSE, FALSE, NULL); - overlapped.hEvent = ::CreateEvent(NULL, FALSE, FALSE, NULL); - m_hInputThread = NULL; - } - - ~WindowsKsData() - { - ::CloseHandle(overlapped.hEvent); - ::CloseHandle(m_hExitEvent); - } - - OVERLAPPED overlapped; - CKsPin* m_pPin; - std::vector m_Buffer; - std::auto_ptr > m_pCaptureEnum; - std::auto_ptr > m_pRenderEnum; - HANDLE m_hInputThread; - HANDLE m_hExitEvent; -}; - -// *********************************************************************// -// API: WINDOWS Kernel Streaming -// Class Definitions: MidiInWinKS -// *********************************************************************// - -static DWORD WINAPI midiKsInputThread(VOID* pUser) -{ - MidiInApi::RtMidiInData* data = static_cast(pUser); - WindowsKsData* apiData = static_cast(data->apiData); - - HANDLE hEvents[] = { apiData->overlapped.hEvent, apiData->m_hExitEvent }; - - while ( true ) { - KSSTREAM_HEADER packet; - memset(&packet, 0, sizeof packet); - packet.Size = sizeof(KSSTREAM_HEADER); - packet.PresentationTime.Time = 0; - packet.PresentationTime.Numerator = 1; - packet.PresentationTime.Denominator = 1; - packet.Data = &apiData->m_Buffer[0]; - packet.DataUsed = 0; - packet.FrameExtent = apiData->m_Buffer.size(); - apiData->m_pPin->ReadData(&packet, &apiData->overlapped); - - DWORD dwRet = ::WaitForMultipleObjects(2, hEvents, FALSE, INFINITE); - - if ( dwRet == WAIT_OBJECT_0 ) { - // parse packet - unsigned char* pData = (unsigned char*)packet.Data; - unsigned int iOffset = 0; - - while ( iOffset < packet.DataUsed ) { - KSMUSICFORMAT* pMusic = (KSMUSICFORMAT*)&pData[iOffset]; - iOffset += sizeof(KSMUSICFORMAT); - - MidiInApi::MidiMessage message; - message.timeStamp = 0; - for(size_t i=0;i < pMusic->ByteCount;++i) - message.bytes.push_back(pData[iOffset+i]); - - if ( data->usingCallback ) { - RtMidiIn::RtMidiCallback callback = (RtMidiIn::RtMidiCallback)data->userCallback; - callback(message.timeStamp, &message.bytes, data->userData); - } - else { - // As long as we haven't reached our queue size limit, push the message. - if ( data->queue.size < data->queue.ringSize ) { - data->queue.ring[data->queue.back++] = message; - if(data->queue.back == data->queue.ringSize) - data->queue.back = 0; - data->queue.size++; - } - else - std::cerr << "\nRtMidiIn: message queue limit reached!!\n\n"; - } - - iOffset += pMusic->ByteCount; - - // re-align on 32 bits - if ( iOffset % 4 != 0 ) - iOffset += (4 - iOffset % 4); - } - } - else - break; - } - return 0; -} + struct WindowsKsData + { + WindowsKsData() : m_pPin(NULL), m_Buffer(1024), m_hInputThread(NULL) + { + memset(&overlapped, 0, sizeof(OVERLAPPED)); + m_hExitEvent = ::CreateEvent(NULL, FALSE, FALSE, NULL); + overlapped.hEvent = ::CreateEvent(NULL, FALSE, FALSE, NULL); + m_hInputThread = NULL; + } + + ~WindowsKsData() + { + ::CloseHandle(overlapped.hEvent); + ::CloseHandle(m_hExitEvent); + } + + OVERLAPPED overlapped; + CKsPin* m_pPin; + std::vector m_Buffer; + std::auto_ptr > m_pCaptureEnum; + std::auto_ptr > m_pRenderEnum; + HANDLE m_hInputThread; + HANDLE m_hExitEvent; + }; + + // *********************************************************************// + // API: WINDOWS Kernel Streaming + // Class Definitions: MidiInWinKS + // *********************************************************************// + + static DWORD WINAPI midiKsInputThread(VOID* pUser) + { + MidiInApi::MidiInData* data = static_cast(pUser); + WindowsKsData* apiData = static_cast(data->apiData); + + HANDLE hEvents[] = { apiData->overlapped.hEvent, apiData->m_hExitEvent }; + + while ( true ) { + KSSTREAM_HEADER packet; + memset(&packet, 0, sizeof packet); + packet.Size = sizeof(KSSTREAM_HEADER); + packet.PresentationTime.Time = 0; + packet.PresentationTime.Numerator = 1; + packet.PresentationTime.Denominator = 1; + packet.Data = &apiData->m_Buffer[0]; + packet.DataUsed = 0; + packet.FrameExtent = apiData->m_Buffer.size(); + apiData->m_pPin->ReadData(&packet, &apiData->overlapped); + + DWORD dwRet = ::WaitForMultipleObjects(2, hEvents, FALSE, INFINITE); + + if ( dwRet == WAIT_OBJECT_0 ) { + // parse packet + unsigned char* pData = (unsigned char*)packet.Data; + unsigned int iOffset = 0; + + while ( iOffset < packet.DataUsed ) { + KSMUSICFORMAT* pMusic = (KSMUSICFORMAT*)&pData[iOffset]; + iOffset += sizeof(KSMUSICFORMAT); + + MidiInApi::MidiMessage message; + message.timeStamp = 0; + for(size_t i=0;i < pMusic->ByteCount;++i) + message.bytes.push_back(pData[iOffset+i]); + + if ( data->usingCallback ) { + MidiCallback callback = (MidiCallback)data->userCallback; + callback(message.timeStamp, &message.bytes, data->userData); + } + else { + // As long as we haven't reached our queue size limit, push the message. + if ( data->queue.size < data->queue.ringSize ) { + data->queue.ring[data->queue.back++] = message; + if(data->queue.back == data->queue.ringSize) + data->queue.back = 0; + data->queue.size++; + } + else + std::cerr << "\nMidiIn: message queue limit reached!!\n\n"; + } + + iOffset += pMusic->ByteCount; + + // re-align on 32 bits + if ( iOffset % 4 != 0 ) + iOffset += (4 - iOffset % 4); + } + } + else + break; + } + return 0; + } -MidiInWinKS :: MidiInWinKS( const std::string clientName, unsigned int queueSizeLimit ) : MidiInApi( queueSizeLimit ) -{ - initialize( clientName ); -} + MidiInWinKS :: MidiInWinKS( const std::string clientName, unsigned int queueSizeLimit ) : MidiInApi( queueSizeLimit ) + { + initialize( clientName ); + } -void MidiInWinKS :: initialize( const std::string& clientName ) -{ - WindowsKsData* data = new WindowsKsData; - apiData_ = (void*)data; - inputData_.apiData = data; - - GUID const aguidEnumCats[] = - { - { STATIC_KSCATEGORY_AUDIO }, { STATIC_KSCATEGORY_CAPTURE } - }; - data->m_pCaptureEnum.reset(new CKsEnumFilters ); - data->m_pCaptureEnum->EnumFilters(aguidEnumCats, 2); -} + void MidiInWinKS :: initialize( const std::string& clientName ) + { + WindowsKsData* data = new WindowsKsData; + apiData_ = (void*)data; + inputData_.apiData = data; + + GUID const aguidEnumCats[] = + { + { STATIC_KSCATEGORY_AUDIO }, { STATIC_KSCATEGORY_CAPTURE } + }; + data->m_pCaptureEnum.reset(new CKsEnumFilters ); + data->m_pCaptureEnum->EnumFilters(aguidEnumCats, 2); + } -MidiInWinKS :: ~MidiInWinKS() -{ - WindowsKsData* data = static_cast(apiData_); - try { - if ( data->m_pPin ) - closePort(); - } - catch(...) { - } - - delete data; -} + MidiInWinKS :: ~MidiInWinKS() + { + WindowsKsData* data = static_cast(apiData_); + try { + if ( data->m_pPin ) + closePort(); + } + catch(...) { + } + + delete data; + } -void MidiInWinKS :: openPort( unsigned int portNumber, const std::string portName ) -{ - WindowsKsData* data = static_cast(apiData_); - - if ( portNumber < 0 || portNumber >= data->m_pCaptureEnum->m_Filters.size() ) { - std::stringstream ost; - ost << "MidiInWinKS::openPort: the 'portNumber' argument (" << portNumber << ") is invalid."; - errorString_ = ost.str(); - error( RtMidiError::WARNING, errorString_ ); - return; - } - - CKsMidiCapFilter* pFilter = data->m_pCaptureEnum->m_Filters[portNumber]; - data->m_pPin = pFilter->CreateCapturePin(); - - if ( data->m_pPin == NULL ) { - std::stringstream ost; - ost << "MidiInWinKS::openPort: KS error opening port (could not create pin)"; - errorString_ = ost.str(); - error( RtMidiError::WARNING, errorString_ ); - return; - } - - data->m_pPin->SetState(KSSTATE_RUN); - - DWORD threadId; - data->m_hInputThread = ::CreateThread(NULL, 0, &midiKsInputThread, &inputData_, 0, &threadId); - if ( data->m_hInputThread == NULL ) { - std::stringstream ost; - ost << "MidiInWinKS::openPort: Could not create input thread : Windows error " << GetLastError() << std::endl;; - errorString_ = ost.str(); - error( RtMidiError::WARNING, errorString_ ); - return; - } - - connected_ = true; -} + void MidiInWinKS :: openPort( unsigned int portNumber, const std::string portName ) + { + WindowsKsData* data = static_cast(apiData_); + + if ( portNumber < 0 || portNumber >= data->m_pCaptureEnum->m_Filters.size() ) { + std::stringstream ost; + ost << "MidiInWinKS::openPort: the 'portNumber' argument (" << portNumber << ") is invalid."; + errorString_ = ost.str(); + error( Error::WARNING, errorString_ ); + return; + } + + CKsMidiCapFilter* pFilter = data->m_pCaptureEnum->m_Filters[portNumber]; + data->m_pPin = pFilter->CreateCapturePin(); + + if ( data->m_pPin == NULL ) { + std::stringstream ost; + ost << "MidiInWinKS::openPort: KS error opening port (could not create pin)"; + errorString_ = ost.str(); + error( Error::WARNING, errorString_ ); + return; + } + + data->m_pPin->SetState(KSSTATE_RUN); + + DWORD threadId; + data->m_hInputThread = ::CreateThread(NULL, 0, &midiKsInputThread, &inputData_, 0, &threadId); + if ( data->m_hInputThread == NULL ) { + std::stringstream ost; + ost << "MidiInWinKS::openPort: Could not create input thread : Windows error " << GetLastError() << std::endl;; + errorString_ = ost.str(); + error( Error::WARNING, errorString_ ); + return; + } + + connected_ = true; + } -void MidiInWinKS :: openVirtualPort( const std::string portName ) -{ - // This function cannot be implemented for the Windows KS MIDI API. - errorString_ = "MidiInWinKS::openVirtualPort: cannot be implemented in Windows KS MIDI API!"; - error( RtMidiError::WARNING, errorString_ ); -} + void MidiInWinKS :: openVirtualPort( const std::string portName ) + { + // This function cannot be implemented for the Windows KS MIDI API. + errorString_ = "MidiInWinKS::openVirtualPort: cannot be implemented in Windows KS MIDI API!"; + error( Error::WARNING, errorString_ ); + } -unsigned int MidiInWinKS :: getPortCount() -{ - WindowsKsData* data = static_cast(apiData_); - return (unsigned int)data->m_pCaptureEnum->m_Filters.size(); -} + unsigned int MidiInWinKS :: getPortCount() + { + WindowsKsData* data = static_cast(apiData_); + return (unsigned int)data->m_pCaptureEnum->m_Filters.size(); + } -std::string MidiInWinKS :: getPortName(unsigned int portNumber) -{ - WindowsKsData* data = static_cast(apiData_); + std::string MidiInWinKS :: getPortName(unsigned int portNumber) + { + WindowsKsData* data = static_cast(apiData_); - if (portNumber < 0 || portNumber >= data->m_pCaptureEnum->m_Filters.size()) { - std::stringstream ost; - ost << "MidiInWinKS::getPortName: the 'portNumber' argument (" << portNumber << ") is invalid."; - errorString_ = ost.str(); - error( RtMidiError::WARNING, errorString_ ); - return; - } + if (portNumber < 0 || portNumber >= data->m_pCaptureEnum->m_Filters.size()) { + std::stringstream ost; + ost << "MidiInWinKS::getPortName: the 'portNumber' argument (" << portNumber << ") is invalid."; + errorString_ = ost.str(); + error( Error::WARNING, errorString_ ); + return; + } - CKsMidiCapFilter* pFilter = data->m_pCaptureEnum->m_Filters[portNumber]; - return pFilter->GetFriendlyName(); -} + CKsMidiCapFilter* pFilter = data->m_pCaptureEnum->m_Filters[portNumber]; + return pFilter->GetFriendlyName(); + } -void MidiInWinKS :: closePort() -{ - WindowsKsData* data = static_cast(apiData_); - connected_ = false; - - if (data->m_hInputThread) { - ::SignalObjectAndWait(data->m_hExitEvent, data->m_hInputThread, INFINITE, FALSE); - ::CloseHandle(data->m_hInputThread); - } - - if (data->m_pPin) { - data->m_pPin->SetState(KSSTATE_PAUSE); - data->m_pPin->SetState(KSSTATE_STOP); - data->m_pPin->ClosePin(); - data->m_pPin = NULL; - } -} + void MidiInWinKS :: closePort() + { + WindowsKsData* data = static_cast(apiData_); + connected_ = false; + + if (data->m_hInputThread) { + ::SignalObjectAndWait(data->m_hExitEvent, data->m_hInputThread, INFINITE, FALSE); + ::CloseHandle(data->m_hInputThread); + } + + if (data->m_pPin) { + data->m_pPin->SetState(KSSTATE_PAUSE); + data->m_pPin->SetState(KSSTATE_STOP); + data->m_pPin->ClosePin(); + data->m_pPin = NULL; + } + } -// *********************************************************************// -// API: WINDOWS Kernel Streaming -// Class Definitions: MidiOutWinKS -// *********************************************************************// + // *********************************************************************// + // API: WINDOWS Kernel Streaming + // Class Definitions: MidiOutWinKS + // *********************************************************************// -MidiOutWinKS :: MidiOutWinKS( const std::string clientName ) : MidiOutApi() -{ - initialize( clientName ); -} + MidiOutWinKS :: MidiOutWinKS( const std::string clientName ) : MidiOutApi() + { + initialize( clientName ); + } -void MidiOutWinKS :: initialize( const std::string& clientName ) -{ - WindowsKsData* data = new WindowsKsData; + void MidiOutWinKS :: initialize( const std::string& clientName ) + { + WindowsKsData* data = new WindowsKsData; - data->m_pPin = NULL; - data->m_pRenderEnum.reset(new CKsEnumFilters ); - GUID const aguidEnumCats[] = - { - { STATIC_KSCATEGORY_AUDIO }, { STATIC_KSCATEGORY_RENDER } - }; - data->m_pRenderEnum->EnumFilters(aguidEnumCats, 2); + data->m_pPin = NULL; + data->m_pRenderEnum.reset(new CKsEnumFilters ); + GUID const aguidEnumCats[] = + { + { STATIC_KSCATEGORY_AUDIO }, { STATIC_KSCATEGORY_RENDER } + }; + data->m_pRenderEnum->EnumFilters(aguidEnumCats, 2); - apiData_ = (void*)data; -} + apiData_ = (void*)data; + } -MidiOutWinKS :: ~MidiOutWinKS() -{ - // Close a connection if it exists. - closePort(); + MidiOutWinKS :: ~MidiOutWinKS() + { + // Close a connection if it exists. + closePort(); - // Cleanup. - WindowsKsData* data = static_cast(apiData_); - delete data; -} + // Cleanup. + WindowsKsData* data = static_cast(apiData_); + delete data; + } -void MidiOutWinKS :: openPort( unsigned int portNumber, const std::string portName ) -{ - WindowsKsData* data = static_cast(apiData_); - - if (portNumber < 0 || portNumber >= data->m_pRenderEnum->m_Filters.size()) { - std::stringstream ost; - ost << "MidiOutWinKS::openPort: the 'portNumber' argument (" << portNumber << ") is invalid."; - errorString_ = ost.str(); - error( RtMidiError::WARNING, errorString_ ); - return; - } - - CKsMidiRenFilter* pFilter = data->m_pRenderEnum->m_Filters[portNumber]; - data->m_pPin = pFilter->CreateRenderPin(); - - if (data->m_pPin == NULL) { - std::stringstream ost; - ost << "MidiOutWinKS::openPort: KS error opening port (could not create pin)"; - errorString_ = ost.str(); - error( RtMidiError::WARNING, errorString_ ); - return; - } - - data->m_pPin->SetState(KSSTATE_RUN); - connected_ = true; -} + void MidiOutWinKS :: openPort( unsigned int portNumber, const std::string portName ) + { + WindowsKsData* data = static_cast(apiData_); + + if (portNumber < 0 || portNumber >= data->m_pRenderEnum->m_Filters.size()) { + std::stringstream ost; + ost << "MidiOutWinKS::openPort: the 'portNumber' argument (" << portNumber << ") is invalid."; + errorString_ = ost.str(); + error( Error::WARNING, errorString_ ); + return; + } + + CKsMidiRenFilter* pFilter = data->m_pRenderEnum->m_Filters[portNumber]; + data->m_pPin = pFilter->CreateRenderPin(); + + if (data->m_pPin == NULL) { + std::stringstream ost; + ost << "MidiOutWinKS::openPort: KS error opening port (could not create pin)"; + errorString_ = ost.str(); + error( Error::WARNING, errorString_ ); + return; + } + + data->m_pPin->SetState(KSSTATE_RUN); + connected_ = true; + } -void MidiOutWinKS :: openVirtualPort( const std::string portName ) -{ - // This function cannot be implemented for the Windows KS MIDI API. - errorString_ = "MidiOutWinKS::openVirtualPort: cannot be implemented in Windows KS MIDI API!"; - error( RtMidiError::WARNING, errorString_ ); -} + void MidiOutWinKS :: openVirtualPort( const std::string portName ) + { + // This function cannot be implemented for the Windows KS MIDI API. + errorString_ = "MidiOutWinKS::openVirtualPort: cannot be implemented in Windows KS MIDI API!"; + error( Error::WARNING, errorString_ ); + } -unsigned int MidiOutWinKS :: getPortCount() -{ - WindowsKsData* data = static_cast(apiData_); - return (unsigned int)data->m_pRenderEnum->m_Filters.size(); -} + unsigned int MidiOutWinKS :: getPortCount() + { + WindowsKsData* data = static_cast(apiData_); + return (unsigned int)data->m_pRenderEnum->m_Filters.size(); + } -std::string MidiOutWinKS :: getPortName( unsigned int portNumber ) -{ - WindowsKsData* data = static_cast(apiData_); + std::string MidiOutWinKS :: getPortName( unsigned int portNumber ) + { + WindowsKsData* data = static_cast(apiData_); - if ( portNumber < 0 || portNumber >= data->m_pRenderEnum->m_Filters.size() ) { - std::stringstream ost; - ost << "MidiOutWinKS::getPortName: the 'portNumber' argument (" << portNumber << ") is invalid."; - errorString_ = ost.str(); - error( RtMidiError::WARNING, errorString_ ); - return; - } + if ( portNumber < 0 || portNumber >= data->m_pRenderEnum->m_Filters.size() ) { + std::stringstream ost; + ost << "MidiOutWinKS::getPortName: the 'portNumber' argument (" << portNumber << ") is invalid."; + errorString_ = ost.str(); + error( Error::WARNING, errorString_ ); + return; + } - CKsMidiRenFilter* pFilter = data->m_pRenderEnum->m_Filters[portNumber]; - return pFilter->GetFriendlyName(); -} + CKsMidiRenFilter* pFilter = data->m_pRenderEnum->m_Filters[portNumber]; + return pFilter->GetFriendlyName(); + } -void MidiOutWinKS :: closePort() -{ - WindowsKsData* data = static_cast(apiData_); - connected_ = false; - - if ( data->m_pPin ) { - data->m_pPin->SetState(KSSTATE_PAUSE); - data->m_pPin->SetState(KSSTATE_STOP); - data->m_pPin->ClosePin(); - data->m_pPin = NULL; - } -} + void MidiOutWinKS :: closePort() + { + WindowsKsData* data = static_cast(apiData_); + connected_ = false; + + if ( data->m_pPin ) { + data->m_pPin->SetState(KSSTATE_PAUSE); + data->m_pPin->SetState(KSSTATE_STOP); + data->m_pPin->ClosePin(); + data->m_pPin = NULL; + } + } -void MidiOutWinKS :: sendMessage(std::vector* pMessage) -{ - std::vector const& msg = *pMessage; - WindowsKsData* data = static_cast(apiData_); - size_t iNumMidiBytes = msg.size(); - size_t pos = 0; - - // write header - KSMUSICFORMAT* pKsMusicFormat = reinterpret_cast(&data->m_Buffer[pos]); - pKsMusicFormat->TimeDeltaMs = 0; - pKsMusicFormat->ByteCount = iNumMidiBytes; - pos += sizeof(KSMUSICFORMAT); - - // write MIDI bytes - if ( pos + iNumMidiBytes > data->m_Buffer.size() ) { - std::stringstream ost; - ost << "KsMidiInput::Write: MIDI buffer too small. Required " << pos + iNumMidiBytes << " bytes, only has " << data->m_Buffer.size(); - errorString_ = ost.str(); - error( RtMidiError::WARNING, errorString_ ); - return; - } - - if ( data->m_pPin == NULL ) { - std::stringstream ost; - ost << "MidiOutWinKS::sendMessage: port is not open"; - errorString_ = ost.str(); - error( RtMidiError::WARNING, errorString_ ); - return; - } - - memcpy(&data->m_Buffer[pos], &msg[0], iNumMidiBytes); - pos += iNumMidiBytes; - - KSSTREAM_HEADER packet; - memset(&packet, 0, sizeof packet); - packet.Size = sizeof(packet); - packet.PresentationTime.Time = 0; - packet.PresentationTime.Numerator = 1; - packet.PresentationTime.Denominator = 1; - packet.Data = const_cast(&data->m_Buffer[0]); - packet.DataUsed = ((pos+3)/4)*4; - packet.FrameExtent = data->m_Buffer.size(); - - data->m_pPin->WriteData(&packet, NULL); + void MidiOutWinKS :: sendMessage(std::vector* pMessage) + { + std::vector const& msg = *pMessage; + WindowsKsData* data = static_cast(apiData_); + size_t iNumMidiBytes = msg.size(); + size_t pos = 0; + + // write header + KSMUSICFORMAT* pKsMusicFormat = reinterpret_cast(&data->m_Buffer[pos]); + pKsMusicFormat->TimeDeltaMs = 0; + pKsMusicFormat->ByteCount = iNumMidiBytes; + pos += sizeof(KSMUSICFORMAT); + + // write MIDI bytes + if ( pos + iNumMidiBytes > data->m_Buffer.size() ) { + std::stringstream ost; + ost << "KsMidiInput::Write: MIDI buffer too small. Required " << pos + iNumMidiBytes << " bytes, only has " << data->m_Buffer.size(); + errorString_ = ost.str(); + error( Error::WARNING, errorString_ ); + return; + } + + if ( data->m_pPin == NULL ) { + std::stringstream ost; + ost << "MidiOutWinKS::sendMessage: port is not open"; + errorString_ = ost.str(); + error( Error::WARNING, errorString_ ); + return; + } + + memcpy(&data->m_Buffer[pos], &msg[0], iNumMidiBytes); + pos += iNumMidiBytes; + + KSSTREAM_HEADER packet; + memset(&packet, 0, sizeof packet); + packet.Size = sizeof(packet); + packet.PresentationTime.Time = 0; + packet.PresentationTime.Numerator = 1; + packet.PresentationTime.Denominator = 1; + packet.Data = const_cast(&data->m_Buffer[0]); + packet.DataUsed = ((pos+3)/4)*4; + packet.FrameExtent = data->m_Buffer.size(); + + data->m_pPin->WriteData(&packet, NULL); + } } - #endif // __WINDOWS_KS__ -//*********************************************************************// -// API: UNIX JACK -// -// Written primarily by Alexander Svetalkin, with updates for delta -// time by Gary Scavone, April 2011. -// -// *********************************************************************// + //*********************************************************************// + // API: UNIX JACK + // + // Written primarily by Alexander Svetalkin, with updates for delta + // time by Gary Scavone, April 2011. + // + // *********************************************************************// #if defined(__UNIX_JACK__) -// JACK header files + // JACK header files #include #include #include #define JACK_RINGBUFFER_SIZE 16384 // Default size for ringbuffer -struct JackMidiData { - jack_client_t *client; - jack_port_t *port; - jack_ringbuffer_t *buffSize; - jack_ringbuffer_t *buffMessage; - jack_time_t lastTime; - MidiInApi :: RtMidiInData *rtMidiIn; - }; - -//*********************************************************************// -// API: JACK -// Class Definitions: MidiInJack -//*********************************************************************// - -static int jackProcessIn( jack_nframes_t nframes, void *arg ) -{ - JackMidiData *jData = (JackMidiData *) arg; - MidiInApi :: RtMidiInData *rtData = jData->rtMidiIn; - jack_midi_event_t event; - jack_time_t time; - - // Is port created? - if ( jData->port == NULL ) return 0; - void *buff = jack_port_get_buffer( jData->port, nframes ); - - // We have midi events in buffer - int evCount = jack_midi_get_event_count( buff ); - for (int j = 0; j < evCount; j++) { - MidiInApi::MidiMessage message; - message.bytes.clear(); - - jack_midi_event_get( &event, buff, j ); - - for ( unsigned int i = 0; i < event.size; i++ ) - message.bytes.push_back( event.buffer[i] ); - - // Compute the delta time. - time = jack_get_time(); - if ( rtData->firstMessage == true ) - rtData->firstMessage = false; - else - message.timeStamp = ( time - jData->lastTime ) * 0.000001; - - jData->lastTime = time; - - if ( !rtData->continueSysex ) { - if ( rtData->usingCallback ) { - RtMidiIn::RtMidiCallback callback = (RtMidiIn::RtMidiCallback) rtData->userCallback; - callback( message.timeStamp, &message.bytes, rtData->userData ); - } - else { - // As long as we haven't reached our queue size limit, push the message. - if ( rtData->queue.size < rtData->queue.ringSize ) { - rtData->queue.ring[rtData->queue.back++] = message; - if ( rtData->queue.back == rtData->queue.ringSize ) - rtData->queue.back = 0; - rtData->queue.size++; - } - else - std::cerr << "\nMidiInJack: message queue limit reached!!\n\n"; - } - } - } - - return 0; -} +namespace rtmidi { + + struct JackMidiData { + jack_client_t *client; + jack_port_t *port; + jack_ringbuffer_t *buffSize; + jack_ringbuffer_t *buffMessage; + jack_time_t lastTime; + MidiInApi :: MidiInData *rtMidiIn; + }; + + //*********************************************************************// + // API: JACK + // Class Definitions: MidiInJack + //*********************************************************************// + + static int jackProcessIn( jack_nframes_t nframes, void *arg ) + { + JackMidiData *jData = (JackMidiData *) arg; + MidiInApi :: MidiInData *rtData = jData->rtMidiIn; + jack_midi_event_t event; + jack_time_t time; + + // Is port created? + if ( jData->port == NULL ) return 0; + void *buff = jack_port_get_buffer( jData->port, nframes ); + + // We have midi events in buffer + int evCount = jack_midi_get_event_count( buff ); + for (int j = 0; j < evCount; j++) { + MidiInApi::MidiMessage message; + message.bytes.clear(); + + jack_midi_event_get( &event, buff, j ); + + for ( unsigned int i = 0; i < event.size; i++ ) + message.bytes.push_back( event.buffer[i] ); + + // Compute the delta time. + time = jack_get_time(); + if ( rtData->firstMessage == true ) + rtData->firstMessage = false; + else + message.timeStamp = ( time - jData->lastTime ) * 0.000001; + + jData->lastTime = time; + + if ( !rtData->continueSysex ) { + if ( rtData->usingCallback ) { + MidiCallback callback = (MidiCallback) rtData->userCallback; + callback( message.timeStamp, &message.bytes, rtData->userData ); + } + else { + // As long as we haven't reached our queue size limit, push the message. + if ( rtData->queue.size < rtData->queue.ringSize ) { + rtData->queue.ring[rtData->queue.back++] = message; + if ( rtData->queue.back == rtData->queue.ringSize ) + rtData->queue.back = 0; + rtData->queue.size++; + } + else + std::cerr << "\nMidiInJack: message queue limit reached!!\n\n"; + } + } + } + + return 0; + } -MidiInJack :: MidiInJack( const std::string clientName, unsigned int queueSizeLimit ) : MidiInApi( queueSizeLimit ) -{ - initialize( clientName ); -} + MidiInJack :: MidiInJack( const std::string clientName, unsigned int queueSizeLimit ) : MidiInApi( queueSizeLimit ) + { + initialize( clientName ); + } -void MidiInJack :: initialize( const std::string& clientName ) -{ - JackMidiData *data = new JackMidiData; - apiData_ = (void *) data; + void MidiInJack :: initialize( const std::string& clientName ) + { + JackMidiData *data = new JackMidiData; + apiData_ = (void *) data; - data->rtMidiIn = &inputData_; - data->port = NULL; - data->client = NULL; - this->clientName = clientName; + data->rtMidiIn = &inputData_; + data->port = NULL; + data->client = NULL; + this->clientName = clientName; - connect(); -} + connect(); + } -void MidiInJack :: connect() -{ - JackMidiData *data = static_cast (apiData_); - if ( data->client ) - return; - - // Initialize JACK client - if (( data->client = jack_client_open( clientName.c_str(), JackNoStartServer, NULL )) == 0) { - errorString_ = "MidiInJack::initialize: JACK server not running?"; - error( RtMidiError::WARNING, errorString_ ); - return; - } - - jack_set_process_callback( data->client, jackProcessIn, data ); - jack_activate( data->client ); -} + void MidiInJack :: connect() + { + JackMidiData *data = static_cast (apiData_); + if ( data->client ) + return; + + // Initialize JACK client + if (( data->client = jack_client_open( clientName.c_str(), JackNoStartServer, NULL )) == 0) { + errorString_ = "MidiInJack::initialize: JACK server not running?"; + error( Error::WARNING, errorString_ ); + return; + } + + jack_set_process_callback( data->client, jackProcessIn, data ); + jack_activate( data->client ); + } -MidiInJack :: ~MidiInJack() -{ - JackMidiData *data = static_cast (apiData_); - closePort(); + MidiInJack :: ~MidiInJack() + { + JackMidiData *data = static_cast (apiData_); + closePort(); - if ( data->client ) - jack_client_close( data->client ); - delete data; -} + if ( data->client ) + jack_client_close( data->client ); + delete data; + } -void MidiInJack :: openPort( unsigned int portNumber, const std::string portName ) -{ - JackMidiData *data = static_cast (apiData_); + void MidiInJack :: openPort( unsigned int portNumber, const std::string portName ) + { + JackMidiData *data = static_cast (apiData_); - connect(); + connect(); - // Creating new port - if ( data->port == NULL) - data->port = jack_port_register( data->client, portName.c_str(), - JACK_DEFAULT_MIDI_TYPE, JackPortIsInput, 0 ); + // Creating new port + if ( data->port == NULL) + data->port = jack_port_register( data->client, portName.c_str(), + JACK_DEFAULT_MIDI_TYPE, JackPortIsInput, 0 ); - if ( data->port == NULL) { - errorString_ = "MidiInJack::openPort: JACK error creating port"; - error( RtMidiError::DRIVER_ERROR, errorString_ ); - return; - } + if ( data->port == NULL) { + errorString_ = "MidiInJack::openPort: JACK error creating port"; + error( Error::DRIVER_ERROR, errorString_ ); + return; + } - // Connecting to the output - std::string name = getPortName( portNumber ); - jack_connect( data->client, name.c_str(), jack_port_name( data->port ) ); -} + // Connecting to the output + std::string name = getPortName( portNumber ); + jack_connect( data->client, name.c_str(), jack_port_name( data->port ) ); + } -void MidiInJack :: openVirtualPort( const std::string portName ) -{ - JackMidiData *data = static_cast (apiData_); + void MidiInJack :: openVirtualPort( const std::string portName ) + { + JackMidiData *data = static_cast (apiData_); - connect(); - if ( data->port == NULL ) - data->port = jack_port_register( data->client, portName.c_str(), - JACK_DEFAULT_MIDI_TYPE, JackPortIsInput, 0 ); + connect(); + if ( data->port == NULL ) + data->port = jack_port_register( data->client, portName.c_str(), + JACK_DEFAULT_MIDI_TYPE, JackPortIsInput, 0 ); - if ( data->port == NULL ) { - errorString_ = "MidiInJack::openVirtualPort: JACK error creating virtual port"; - error( RtMidiError::DRIVER_ERROR, errorString_ ); - } -} + if ( data->port == NULL ) { + errorString_ = "MidiInJack::openVirtualPort: JACK error creating virtual port"; + error( Error::DRIVER_ERROR, errorString_ ); + } + } -unsigned int MidiInJack :: getPortCount() -{ - int count = 0; - JackMidiData *data = static_cast (apiData_); - connect(); - if ( !data->client ) - return 0; + unsigned int MidiInJack :: getPortCount() + { + int count = 0; + JackMidiData *data = static_cast (apiData_); + connect(); + if ( !data->client ) + return 0; - // List of available ports - const char **ports = jack_get_ports( data->client, NULL, JACK_DEFAULT_MIDI_TYPE, JackPortIsOutput ); + // List of available ports + const char **ports = jack_get_ports( data->client, NULL, JACK_DEFAULT_MIDI_TYPE, JackPortIsOutput ); - if ( ports == NULL ) return 0; - while ( ports[count] != NULL ) - count++; + if ( ports == NULL ) return 0; + while ( ports[count] != NULL ) + count++; - free( ports ); + free( ports ); - return count; -} + return count; + } -std::string MidiInJack :: getPortName( unsigned int portNumber ) -{ - JackMidiData *data = static_cast (apiData_); - std::string retStr(""); - - connect(); - - // List of available ports - const char **ports = jack_get_ports( data->client, NULL, - JACK_DEFAULT_MIDI_TYPE, JackPortIsOutput ); - - // Check port validity - if ( ports == NULL ) { - errorString_ = "MidiInJack::getPortName: no ports available!"; - error( RtMidiError::WARNING, errorString_ ); - return retStr; - } - - if ( ports[portNumber] == NULL ) { - std::ostringstream ost; - ost << "MidiInJack::getPortName: the 'portNumber' argument (" << portNumber << ") is invalid."; - errorString_ = ost.str(); - error( RtMidiError::WARNING, errorString_ ); - } - else retStr.assign( ports[portNumber] ); - - free( ports ); - return retStr; -} + std::string MidiInJack :: getPortName( unsigned int portNumber ) + { + JackMidiData *data = static_cast (apiData_); + std::string retStr(""); + + connect(); + + // List of available ports + const char **ports = jack_get_ports( data->client, NULL, + JACK_DEFAULT_MIDI_TYPE, JackPortIsOutput ); + + // Check port validity + if ( ports == NULL ) { + errorString_ = "MidiInJack::getPortName: no ports available!"; + error( Error::WARNING, errorString_ ); + return retStr; + } + + if ( ports[portNumber] == NULL ) { + std::ostringstream ost; + ost << "MidiInJack::getPortName: the 'portNumber' argument (" << portNumber << ") is invalid."; + errorString_ = ost.str(); + error( Error::WARNING, errorString_ ); + } + else retStr.assign( ports[portNumber] ); + + free( ports ); + return retStr; + } -void MidiInJack :: closePort() -{ - JackMidiData *data = static_cast (apiData_); + void MidiInJack :: closePort() + { + JackMidiData *data = static_cast (apiData_); - if ( data->port == NULL ) return; - jack_port_unregister( data->client, data->port ); - data->port = NULL; -} + if ( data->port == NULL ) return; + jack_port_unregister( data->client, data->port ); + data->port = NULL; + } -//*********************************************************************// -// API: JACK -// Class Definitions: MidiOutJack -//*********************************************************************// + //*********************************************************************// + // API: JACK + // Class Definitions: MidiOutJack + //*********************************************************************// -// Jack process callback -static int jackProcessOut( jack_nframes_t nframes, void *arg ) -{ - JackMidiData *data = (JackMidiData *) arg; - jack_midi_data_t *midiData; - int space; + // Jack process callback + static int jackProcessOut( jack_nframes_t nframes, void *arg ) + { + JackMidiData *data = (JackMidiData *) arg; + jack_midi_data_t *midiData; + int space; - // Is port created? - if ( data->port == NULL ) return 0; + // Is port created? + if ( data->port == NULL ) return 0; - void *buff = jack_port_get_buffer( data->port, nframes ); - jack_midi_clear_buffer( buff ); + void *buff = jack_port_get_buffer( data->port, nframes ); + jack_midi_clear_buffer( buff ); - while ( jack_ringbuffer_read_space( data->buffSize ) > 0 ) { - jack_ringbuffer_read( data->buffSize, (char *) &space, (size_t) sizeof(space) ); - midiData = jack_midi_event_reserve( buff, 0, space ); + while ( jack_ringbuffer_read_space( data->buffSize ) > 0 ) { + jack_ringbuffer_read( data->buffSize, (char *) &space, (size_t) sizeof(space) ); + midiData = jack_midi_event_reserve( buff, 0, space ); - jack_ringbuffer_read( data->buffMessage, (char *) midiData, (size_t) space ); - } + jack_ringbuffer_read( data->buffMessage, (char *) midiData, (size_t) space ); + } - return 0; -} + return 0; + } -MidiOutJack :: MidiOutJack( const std::string clientName ) : MidiOutApi() -{ - initialize( clientName ); -} + MidiOutJack :: MidiOutJack( const std::string clientName ) : MidiOutApi() + { + initialize( clientName ); + } -void MidiOutJack :: initialize( const std::string& clientName ) -{ - JackMidiData *data = new JackMidiData; - apiData_ = (void *) data; + void MidiOutJack :: initialize( const std::string& clientName ) + { + JackMidiData *data = new JackMidiData; + apiData_ = (void *) data; - data->port = NULL; - data->client = NULL; - this->clientName = clientName; + data->port = NULL; + data->client = NULL; + this->clientName = clientName; - connect(); -} + connect(); + } -void MidiOutJack :: connect() -{ - JackMidiData *data = static_cast (apiData_); - if ( data->client ) - return; - - // Initialize JACK client - if (( data->client = jack_client_open( clientName.c_str(), JackNoStartServer, NULL )) == 0) { - errorString_ = "MidiOutJack::initialize: JACK server not running?"; - error( RtMidiError::WARNING, errorString_ ); - return; - } - - jack_set_process_callback( data->client, jackProcessOut, data ); - data->buffSize = jack_ringbuffer_create( JACK_RINGBUFFER_SIZE ); - data->buffMessage = jack_ringbuffer_create( JACK_RINGBUFFER_SIZE ); - jack_activate( data->client ); -} + void MidiOutJack :: connect() + { + JackMidiData *data = static_cast (apiData_); + if ( data->client ) + return; + + // Initialize JACK client + if (( data->client = jack_client_open( clientName.c_str(), JackNoStartServer, NULL )) == 0) { + errorString_ = "MidiOutJack::initialize: JACK server not running?"; + error( Error::WARNING, errorString_ ); + return; + } + + jack_set_process_callback( data->client, jackProcessOut, data ); + data->buffSize = jack_ringbuffer_create( JACK_RINGBUFFER_SIZE ); + data->buffMessage = jack_ringbuffer_create( JACK_RINGBUFFER_SIZE ); + jack_activate( data->client ); + } -MidiOutJack :: ~MidiOutJack() -{ - JackMidiData *data = static_cast (apiData_); - closePort(); + MidiOutJack :: ~MidiOutJack() + { + JackMidiData *data = static_cast (apiData_); + closePort(); - if ( data->client ) { - // Cleanup - jack_client_close( data->client ); - jack_ringbuffer_free( data->buffSize ); - jack_ringbuffer_free( data->buffMessage ); - } + if ( data->client ) { + // Cleanup + jack_client_close( data->client ); + jack_ringbuffer_free( data->buffSize ); + jack_ringbuffer_free( data->buffMessage ); + } - delete data; -} + delete data; + } -void MidiOutJack :: openPort( unsigned int portNumber, const std::string portName ) -{ - JackMidiData *data = static_cast (apiData_); + void MidiOutJack :: openPort( unsigned int portNumber, const std::string portName ) + { + JackMidiData *data = static_cast (apiData_); - connect(); + connect(); - // Creating new port - if ( data->port == NULL ) - data->port = jack_port_register( data->client, portName.c_str(), - JACK_DEFAULT_MIDI_TYPE, JackPortIsOutput, 0 ); + // Creating new port + if ( data->port == NULL ) + data->port = jack_port_register( data->client, portName.c_str(), + JACK_DEFAULT_MIDI_TYPE, JackPortIsOutput, 0 ); - if ( data->port == NULL ) { - errorString_ = "MidiOutJack::openPort: JACK error creating port"; - error( RtMidiError::DRIVER_ERROR, errorString_ ); - return; - } + if ( data->port == NULL ) { + errorString_ = "MidiOutJack::openPort: JACK error creating port"; + error( Error::DRIVER_ERROR, errorString_ ); + return; + } - // Connecting to the output - std::string name = getPortName( portNumber ); - jack_connect( data->client, jack_port_name( data->port ), name.c_str() ); -} + // Connecting to the output + std::string name = getPortName( portNumber ); + jack_connect( data->client, jack_port_name( data->port ), name.c_str() ); + } -void MidiOutJack :: openVirtualPort( const std::string portName ) -{ - JackMidiData *data = static_cast (apiData_); + void MidiOutJack :: openVirtualPort( const std::string portName ) + { + JackMidiData *data = static_cast (apiData_); - connect(); - if ( data->port == NULL ) - data->port = jack_port_register( data->client, portName.c_str(), - JACK_DEFAULT_MIDI_TYPE, JackPortIsOutput, 0 ); + connect(); + if ( data->port == NULL ) + data->port = jack_port_register( data->client, portName.c_str(), + JACK_DEFAULT_MIDI_TYPE, JackPortIsOutput, 0 ); - if ( data->port == NULL ) { - errorString_ = "MidiOutJack::openVirtualPort: JACK error creating virtual port"; - error( RtMidiError::DRIVER_ERROR, errorString_ ); - } -} + if ( data->port == NULL ) { + errorString_ = "MidiOutJack::openVirtualPort: JACK error creating virtual port"; + error( Error::DRIVER_ERROR, errorString_ ); + } + } -unsigned int MidiOutJack :: getPortCount() -{ - int count = 0; - JackMidiData *data = static_cast (apiData_); - connect(); - if ( !data->client ) - return 0; + unsigned int MidiOutJack :: getPortCount() + { + int count = 0; + JackMidiData *data = static_cast (apiData_); + connect(); + if ( !data->client ) + return 0; - // List of available ports - const char **ports = jack_get_ports( data->client, NULL, - JACK_DEFAULT_MIDI_TYPE, JackPortIsInput ); + // List of available ports + const char **ports = jack_get_ports( data->client, NULL, + JACK_DEFAULT_MIDI_TYPE, JackPortIsInput ); - if ( ports == NULL ) return 0; - while ( ports[count] != NULL ) - count++; + if ( ports == NULL ) return 0; + while ( ports[count] != NULL ) + count++; - free( ports ); + free( ports ); - return count; -} + return count; + } -std::string MidiOutJack :: getPortName( unsigned int portNumber ) -{ - JackMidiData *data = static_cast (apiData_); - std::string retStr(""); - - connect(); - - // List of available ports - const char **ports = jack_get_ports( data->client, NULL, - JACK_DEFAULT_MIDI_TYPE, JackPortIsInput ); - - // Check port validity - if ( ports == NULL) { - errorString_ = "MidiOutJack::getPortName: no ports available!"; - error( RtMidiError::WARNING, errorString_ ); - return retStr; - } - - if ( ports[portNumber] == NULL) { - std::ostringstream ost; - ost << "MidiOutJack::getPortName: the 'portNumber' argument (" << portNumber << ") is invalid."; - errorString_ = ost.str(); - error( RtMidiError::WARNING, errorString_ ); - } - else retStr.assign( ports[portNumber] ); - - free( ports ); - return retStr; -} + std::string MidiOutJack :: getPortName( unsigned int portNumber ) + { + JackMidiData *data = static_cast (apiData_); + std::string retStr(""); + + connect(); + + // List of available ports + const char **ports = jack_get_ports( data->client, NULL, + JACK_DEFAULT_MIDI_TYPE, JackPortIsInput ); + + // Check port validity + if ( ports == NULL) { + errorString_ = "MidiOutJack::getPortName: no ports available!"; + error( Error::WARNING, errorString_ ); + return retStr; + } + + if ( ports[portNumber] == NULL) { + std::ostringstream ost; + ost << "MidiOutJack::getPortName: the 'portNumber' argument (" << portNumber << ") is invalid."; + errorString_ = ost.str(); + error( Error::WARNING, errorString_ ); + } + else retStr.assign( ports[portNumber] ); + + free( ports ); + return retStr; + } -void MidiOutJack :: closePort() -{ - JackMidiData *data = static_cast (apiData_); + void MidiOutJack :: closePort() + { + JackMidiData *data = static_cast (apiData_); - if ( data->port == NULL ) return; - jack_port_unregister( data->client, data->port ); - data->port = NULL; -} + if ( data->port == NULL ) return; + jack_port_unregister( data->client, data->port ); + data->port = NULL; + } -void MidiOutJack :: sendMessage( std::vector *message ) -{ - int nBytes = message->size(); - JackMidiData *data = static_cast (apiData_); + void MidiOutJack :: sendMessage( std::vector *message ) + { + int nBytes = message->size(); + JackMidiData *data = static_cast (apiData_); - // Write full message to buffer - jack_ringbuffer_write( data->buffMessage, ( const char * ) &( *message )[0], - message->size() ); - jack_ringbuffer_write( data->buffSize, ( char * ) &nBytes, sizeof( nBytes ) ); + // Write full message to buffer + jack_ringbuffer_write( data->buffMessage, ( const char * ) &( *message )[0], + message->size() ); + jack_ringbuffer_write( data->buffSize, ( char * ) &nBytes, sizeof( nBytes ) ); + } } - #endif // __UNIX_JACK__ + diff --git a/RtMidi.h b/RtMidi.h index 433514d0..f40f2df7 100644 --- a/RtMidi.h +++ b/RtMidi.h @@ -1,49 +1,58 @@ /********************* -*- C++ -*- ****************************************/ /*! \class RtMidi - \brief An abstract base class for realtime MIDI input/output. - - This class implements some common functionality for the realtime - MIDI input/output subclasses RtMidiIn and RtMidiOut. - - RtMidi WWW site: http://music.mcgill.ca/~gary/rtmidi/ - - RtMidi: realtime MIDI i/o C++ classes - Copyright (c) 2003-2014 Gary P. Scavone - - Permission is hereby granted, free of charge, to any person - obtaining a copy of this software and associated documentation files - (the "Software"), to deal in the Software without restriction, - including without limitation the rights to use, copy, modify, merge, - publish, distribute, sublicense, and/or sell copies of the Software, - and to permit persons to whom the Software is furnished to do so, - subject to the following conditions: - - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. - - Any person wishing to distribute modifications to the Software is - asked to send the modifications to the original developer so that - they can be incorporated into the canonical version. This is, - however, not a binding provision of this license. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR - ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + \brief An abstract base class for realtime MIDI input/output. + + This class implements some common functionality for the realtime + MIDI input/output subclasses RtMidiIn and RtMidiOut. + + RtMidi WWW site: http://music.mcgill.ca/~gary/rtmidi/ + + RtMidi: realtime MIDI i/o C++ classes + Copyright (c) 2003-2014 Gary P. Scavone + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation files + (the "Software"), to deal in the Software without restriction, + including without limitation the rights to use, copy, modify, merge, + publish, distribute, sublicense, and/or sell copies of the Software, + and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + Any person wishing to distribute modifications to the Software is + asked to send the modifications to the original developer so that + they can be incorporated into the canonical version. This is, + however, not a binding provision of this license. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR + ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**********************************************************************/ /*! \file RtMidi.h - */ +*/ #ifndef RTMIDI_H #define RTMIDI_H -#define RTMIDI_VERSION "2.1.0" +#define RTMIDI_VERSION "3.0.0alpha" + +#ifdef __GNUC__ +#define RTMIDI_DEPRECATED(func) func __attribute__ ((deprecated)) +#elif defined(_MSC_VER) +#define RTMIDI_DEPRECATED(func) __declspec(deprecated) func +#else +#pragma message("WARNING: You need to implement DEPRECATED for this compiler") +#define RTMIDI_DEPRECATED(func) func +#endif #include #include @@ -52,73 +61,142 @@ #include #include -/************************************************************************/ -/*! \class RtMidiError - \brief Exception handling class for RtMidi. +namespace rtmidi { + + //! MIDI API specifier arguments. + enum ApiType { + UNSPECIFIED, /*!< Search for a working compiled API. */ + MACOSX_CORE, /*!< Macintosh OS-X Core Midi API. */ + LINUX_ALSA, /*!< The Advanced Linux Sound Architecture API. */ + UNIX_JACK, /*!< The JACK Low-Latency MIDI Server API. */ + WINDOWS_MM, /*!< The Microsoft Multimedia MIDI API. */ + WINDOWS_KS, /*!< The Microsoft Kernel Streaming MIDI API. */ + RTMIDI_DUMMY /*!< A compilable but non-functional API. */ + }; - The RtMidiError class is quite simple but it does allow errors to be - "caught" by RtMidiError::Type. See the RtMidi documentation to know - which methods can throw an RtMidiError. -*/ -/************************************************************************/ - -class RtMidiError : public std::exception -{ - public: - //! Defined RtMidiError types. - enum Type { - WARNING, /*!< A non-critical error. */ - DEBUG_WARNING, /*!< A non-critical error which might be useful for debugging. */ - UNSPECIFIED, /*!< The default, unspecified error type. */ - NO_DEVICES_FOUND, /*!< No devices found on system. */ - INVALID_DEVICE, /*!< An invalid device ID was specified. */ - MEMORY_ERROR, /*!< An error occured during memory allocation. */ - INVALID_PARAMETER, /*!< An invalid parameter was specified to a function. */ - INVALID_USE, /*!< The function was called incorrectly. */ - DRIVER_ERROR, /*!< A system driver error occured. */ - SYSTEM_ERROR, /*!< A system error occured. */ - THREAD_ERROR /*!< A thread error occured. */ - }; - - //! The constructor. - RtMidiError( const std::string& message, Type type = RtMidiError::UNSPECIFIED ) throw() : message_(message), type_(type) {} - - //! The destructor. - virtual ~RtMidiError( void ) throw() {} - - //! Prints thrown error message to stderr. - virtual void printMessage( void ) const throw() { std::cerr << '\n' << message_ << "\n\n"; } - - //! Returns the thrown error message type. - virtual const Type& getType(void) const throw() { return type_; } - - //! Returns the thrown error message string. - virtual const std::string& getMessage(void) const throw() { return message_; } - - //! Returns the thrown error message as a c-style string. - virtual const char* what( void ) const throw() { return message_.c_str(); } - - protected: - std::string message_; - Type type_; -}; - -//! RtMidi error callback function prototype. -/*! - \param type Type of error. - \param errorText Error description. - - Note that class behaviour is undefined after a critical error (not - a warning) is reported. - */ -typedef void (*RtMidiErrorCallback)( RtMidiError::Type type, const std::string &errorText ); - -class CommonMidiApi { -public: - //! A port descriptor type. - /*! This will be used with scoped pointers to store system dependent - * data for identifying the port. + //! User callback function type definition. + /*! + \param timeStamp timestamp indicating when the event has been received + \param message a pointer to the binary MIDI message + \param userData a pointer that can be set using setUserdata + \sa MidiIn + \sa MidiInApi */ + typedef void (*MidiCallback)( double timeStamp, std::vector *message, void *userData); + + /************************************************************************/ + /*! \class Error + \brief Exception handling class for RtMidi. + + The Error class is quite simple but it does allow errors to be + "caught" by Error::Type. See the RtMidi documentation to know + which methods can throw an Error. + */ + /************************************************************************/ + + class Error : public std::exception + { + public: + //! Defined Error types. + enum Type { + WARNING, /*!< A non-critical error. */ + DEBUG_WARNING, /*!< A non-critical error which might be useful for debugging. */ + UNSPECIFIED, /*!< The default, unspecified error type. */ + NO_DEVICES_FOUND, /*!< No devices found on system. */ + INVALID_DEVICE, /*!< An invalid device ID was specified. */ + MEMORY_ERROR, /*!< An error occured during memory allocation. */ + INVALID_PARAMETER, /*!< An invalid parameter was specified to a function. */ + INVALID_USE, /*!< The function was called incorrectly. */ + DRIVER_ERROR, /*!< A system driver error occured. */ + SYSTEM_ERROR, /*!< A system error occured. */ + THREAD_ERROR /*!< A thread error occured. */ + }; + + //! The constructor. + Error( const std::string& message, Type type = Error::UNSPECIFIED ) throw() : message_(message), type_(type) {} + + //! The destructor. + virtual ~Error( void ) throw() {} + + //! Prints thrown error message to stderr. + virtual void printMessage( void ) const throw() { std::cerr << '\n' << message_ << "\n\n"; } + + //! Returns the thrown error message type. + virtual const Type& getType(void) const throw() { return type_; } + + //! Returns the thrown error message string. + virtual const std::string& getMessage(void) const throw() { return message_; } + + //! Returns the thrown error message as a c-style string. + virtual const char* what( void ) const throw() { return message_.c_str(); } + + protected: + std::string message_; + Type type_; + }; + + //! RtMidi error callback function prototype. + /*! + \param type Type of error. + \param errorText Error description. + + Note that class behaviour is undefined after a critical error (not + a warning) is reported. + */ + typedef void (*ErrorCallback)( Error::Type type, const std::string &errorText ); + + + +#if __cplusplus < 201103L + class PortDescriptor; + + template + class Pointer { + public: + typedef T datatype; + protected: + struct countPointer { + int count; + datatype * descriptor; + }; + public: + Pointer(datatype * p):ptr(new countPointer) { + ptr->count = 1; + ptr->descriptor = p; + } + Pointer(const Pointer & other): + ptr(other.ptr) { + ptr->count++; + } + + ~Pointer() { + if (!ptr) return; + if (!ptr->descriptor) { + delete ptr; + return; + } + if (!(--ptr->count)) { + delete ptr->descriptor; + delete ptr; + } + } + + datatype * operator -> () { + if (!ptr) return 0; + // this should throw an exception + + return ptr->descriptor; + } + protected: + countPointer * ptr; + }; +#else + template + typedef shared_ptr Pointer; +#endif + + class MidiApi; + struct PortDescriptor { //! Flags for formatting a string description of the port. /*! These flags just mark the requirements that the string @@ -159,50 +237,6 @@ class CommonMidiApi { INOUTPUT = 3 /*!< Ports that allow reading and writing (INPUT | OUTPUT) */ }; - -#if __cplusplus < 201103L - class Pointer { - protected: - struct countPointer { - int count; - PortDescriptor * descriptor; - }; - public: - Pointer(PortDescriptor * p):ptr(new countPointer) { - ptr->count = 1; - ptr->descriptor = p; - } - Pointer(const Pointer & other): - ptr(other.ptr) { - ptr->count++; - } - - ~Pointer() { - if (!ptr) return; - if (!ptr->descriptor) { - delete ptr; - return; - } - if (!(--ptr->count)) { - delete ptr->descriptor; - delete ptr; - } - } - - PortDescriptor * operator -> () { - if (!ptr) return 0; - // this should throw an exception - - return ptr->descriptor; - } - protected: - countPointer * ptr; - }; -#else - typedef shared_ptr Pointer; -#endif - - //! Default constructor. /*! * Derived classes should have a constructor. @@ -221,7 +255,7 @@ class CommonMidiApi { * * \return API that can handle this object. */ - virtual CommonMidiApi * getAPI() = 0; + virtual MidiApi * getAPI() = 0; //! Return the port name /*! @@ -242,954 +276,913 @@ class CommonMidiApi { /*! Port descriptors are stored as shared pointers. This avoids unnecessary duplication of the data structure and handles automatic deletion if all references have been removed. */ - typedef std::list PortList; + typedef std::list > PortList; - //! Pure virtal function to create a virtual port, with optional name. - /*! - This function creates a virtual MIDI port to which other - software applications can connect. This type of functionality - is currently only supported by the Macintosh OS-X, any JACK, - and Linux ALSA APIs (the function returns an error for the other APIs). - \param portName An optional name for the applicaction port that is - used to connect to portId can be specified. - */ - virtual void openVirtualPort( const std::string portName = std::string( "RtMidi" ) ) = 0; - //! Pure virtual function to open a MIDI connection given by enumeration number. - /*! \param portNumber An optional port number greater than 0 - can be specified. Otherwise, the default or first port - found is opened. + // **************************************************************** // + // + // MidiInApi / MidiOutApi class declarations. + // + // Subclasses of MidiInApi and MidiOutApi contain all API- and + // OS-specific code necessary to fully implement the RtMidi API. + // + // Note that MidiInApi and MidiOutApi are abstract base classes and + // cannot be explicitly instantiated. MidiIn and MidiOut will + // create instances of a MidiInApi or MidiOutApi subclass. + // + // **************************************************************** // - \param portName An optional name for the applicaction port - that will be generated to connect to portId can be - specified. - */ - virtual void openPort( unsigned int portNumber = 0, const std::string portName = std::string( "RtMidi" ) ) = 0; + class MidiApi + { + public: - //! Pure virtual function to open a MIDI connection given by a port descriptor. - /*! - \param port A port descriptor of the port must be specified. - \param portName An optional name for the applicaction port that is used to connect to portId can be specified. - */ - virtual void openPort( const PortDescriptor & port, const std::string portName = std::string( "RtMidi" ) ) = 0; + MidiApi(); + virtual ~MidiApi(); - //! Pure virtual function to return a port descirptor if the port is open - virtual PortDescriptor::Pointer getDescriptor() = 0; + //! Pure virtal function to create a virtual port, with optional name. + /*! + This function creates a virtual MIDI port to which other + software applications can connect. This type of functionality + is currently only supported by the Macintosh OS-X, any JACK, + and Linux ALSA APIs (the function returns an error for the other APIs). + + \param portName An optional name for the applicaction port that is + used to connect to portId can be specified. + */ + virtual void openVirtualPort( const std::string portName = std::string( "RtMidi" ) ) = 0; + + //! Pure virtual function to open a MIDI connection given by enumeration number. + /*! \param portNumber An optional port number greater than 0 + can be specified. Otherwise, the default or first port + found is opened. + + \param portName An optional name for the applicaction port + that will be generated to connect to portId can be + specified. + */ + virtual void openPort( unsigned int portNumber = 0, const std::string portName = std::string( "RtMidi" ) ) = 0; + + //! Pure virtual function to open a MIDI connection given by a port descriptor. + /*! + \param port A port descriptor of the port must be specified. + \param portName An optional name for the applicaction port that is used to connect to portId can be specified. + */ + virtual void openPort( const PortDescriptor & port, const std::string portName = std::string( "RtMidi" ) ) = 0; - //! Pure virtual function to return a list of all available ports of the current API. - /*! - \param capabilities an optional parameter that describes which - device types are returned. + //! Pure virtual function to return a port descirptor if the port is open + virtual Pointer getDescriptor() = 0; - \return This function returns a list of port descriptors. + //! Pure virtual function to return a list of all available ports of the current API. + /*! + \param capabilities an optional parameter that describes which + device types are returned. - \note An input API may but need not necessarily report - output devices which cannot be used as input if - \ref PortDescriptor::OUTPUT is passed as \ref capabilities parameter. - */ - virtual CommonMidiApi::PortList getPortList(int capabilities = PortDescriptor:: INOUTPUT) = 0; + \return This function returns a list of port descriptors. - //! Pure virtual to return the number of available MIDI ports of the current API. - /*! - \return This function returns the number of MIDI ports of - the selected API. + \note An input API may but need not necessarily report + output devices which cannot be used as input if + \ref PortDescriptor::OUTPUT is passed as \ref capabilities parameter. + */ + virtual PortList getPortList(int capabilities = PortDescriptor:: INOUTPUT) = 0; - \note Only ports are counted that can be used with the - current API so an input API does ignore all output devices - and vice versa. + //! Pure virtual to return the number of available MIDI ports of the current API. + /*! + \return This function returns the number of MIDI ports of + the selected API. - \sa getPortName - */ - virtual unsigned int getPortCount() = 0; + \note Only ports are counted that can be used with the + current API so an input API does ignore all output devices + and vice versa. - //! Pure virtual function to return a string identifier for the specified MIDI port number. - /*! - \param portNumber Number of the device to be referred to. - \return The name of the port with the given Id is returned. - \retval An empty string is returned if an invalid port specifier is provided. + \sa getPortName + */ + virtual unsigned int getPortCount() = 0; + + //! Pure virtual function to return a string identifier for the specified MIDI port number. + /*! + \param portNumber Number of the device to be referred to. + \return The name of the port with the given Id is returned. + \retval An empty string is returned if an invalid port specifier is provided. + + \note Only ports are counted that can be used with the + current API so an input API does ignore all output devices + and vice versa. + + \sa getPortCount() + */ + virtual std::string getPortName( unsigned int portNumber = 0 ) = 0; + + //! Pure virtual function to close an open MIDI connection (if one exists). + virtual void closePort( void ) = 0; + + // ! A basic error reporting function for RtMidi classes. + // static void error( Error::Type type, std::string &errorString ); + + //! Pure virtual function to return whether a port is open or not. + /*! \retval true if a port is open and + \retval false if the port is not open (e.g. not opend or closed). + */ + bool isPortOpen() const { return connected_; } + + //! Pure virtual function to set an error callback function to be invoked when an error has occured. + /*! + The callback function will be called whenever an error has occured. It is best + to set the error callback function before opening a port. + */ + virtual void setErrorCallback( ErrorCallback errorCallback = NULL ); + + + //! Returns the MIDI API specifier for the current instance of RtMidiIn. + virtual ApiType getCurrentApi( void ) throw() = 0; + + //! A basic error reporting function for RtMidi classes. + void error( Error::Type type, std::string errorString ); + + protected: + virtual void initialize( const std::string& clientName ) = 0; + + void *apiData_; + bool connected_; + std::string errorString_; + ErrorCallback errorCallback_; + }; + + class MidiInApi : public MidiApi + { + public: + + MidiInApi( unsigned int queueSizeLimit ); + virtual ~MidiInApi( void ); + void setCallback( MidiCallback callback, void *userData ); + void cancelCallback( void ); + virtual void ignoreTypes( bool midiSysex, bool midiTime, bool midiSense ); + RTMIDI_DEPRECATED(double getMessage( std::vector *message )) + { + if (!message) { + errorString_ = "MidiInApi::getMessage: passed NULL pointer"; + error( Error::WARNING, errorString_ ); + } + return getMessage(*message); + } + double getMessage( std::vector &message ); + + // A MIDI structure used internally by the class to store incoming + // messages. Each message represents one and only one MIDI message. + struct MidiMessage { + std::vector bytes; + double timeStamp; + + // Default constructor. + MidiMessage() + :bytes(0), timeStamp(0.0) {} + }; + + struct MidiQueue { + unsigned int front; + unsigned int back; + unsigned int size; + unsigned int ringSize; + MidiMessage *ring; + + // Default constructor. + MidiQueue() + :front(0), back(0), size(0), ringSize(0) {} + }; + + // The RtMidiInData structure is used to pass private class data to + // the MIDI input handling function or thread. + struct MidiInData { + MidiQueue queue; + MidiMessage message; + unsigned char ignoreFlags; + bool doInput; + bool firstMessage; + void *apiData; + bool usingCallback; + MidiCallback userCallback; + void *userData; + bool continueSysex; + + // Default constructor. + MidiInData() + : ignoreFlags(7), doInput(false), firstMessage(true), + apiData(0), usingCallback(false), userCallback(0), userData(0), + continueSysex(false) {} + }; + + protected: + MidiInData inputData_; + }; + + class MidiOutApi : public MidiApi + { + public: + + MidiOutApi( void ); + virtual ~MidiOutApi( void ); + RTMIDI_DEPRECATED(void sendMessage( std::vector *message )) + { + if (!message) { + errorString_ = "MidiOutApi::sendMessage: no data in message argument!"; + error( Error::WARNING, errorString_ ); + } + sendMessage(*message); + } + virtual void sendMessage( std::vector &message ) = 0; + }; + + + /*! \class Midi + \brief A global class that implements basic backend API handling. - \note Only ports are counted that can be used with the - current API so an input API does ignore all output devices - and vice versa. + This class enhances \ref MidiApi by some functionality to handle + backend API objects. It serves as base class for the public RtMidi + API. - \sa getPortCount() + by Gary P. Scavone, 2003-2014. */ - std::string getPortName( unsigned int portNumber = 0 ); + /**********************************************************************/ + class Midi { + public: + typedef rtmidi::ApiType Api; + //! defined for compatibility + enum Api2 { + UNSPECIFIED = rtmidi::UNSPECIFIED, + MACOSX_CORE = rtmidi::MACOSX_CORE, + LINUX_ALSA = rtmidi::LINUX_ALSA, + UNIX_JACK = rtmidi::UNIX_JACK, + WINDOWS_MM = rtmidi::WINDOWS_MM, + WINDOWS_KS = rtmidi::WINDOWS_KS, + RTMIDI_DUMMY = rtmidi::RTMIDI_DUMMY + }; - //! Pure virtual function to close an open MIDI connection (if one exists). - virtual void closePort( void ) = 0; - // ! A basic error reporting function for RtMidi classes. - // static void error( RtMidiError::Type type, std::string &errorString ); + //! A static function to determine the current RtMidi version. + static std::string getVersion( void ) throw(); - //! Pure virtual function to return whether a port is open or not. - /*! \retval true if a port is open and - \retval false if the port is not open (e.g. not opend or closed). + //! A static function to determine the available compiled MIDI APIs. + /*! + The values returned in the std::vector can be compared against + the enumerated list values. Note that there can be more than one + API compiled for certain operating systems. + */ + static void getCompiledApi( std::vector &apis ) throw(); + + //! Returns the MIDI API specifier for the current instance of RtMidiIn. + ApiType getCurrentApi( void ) throw() + { + if (rtapi_) return rtapi_->getCurrentApi(); + else return rtmidi::UNSPECIFIED; + } + + //! Function to create a virtual port, with optional name. + /*! + This function creates a virtual MIDI port to which other + software applications can connect. This type of functionality + is currently only supported by the Macintosh OS-X, any JACK, + and Linux ALSA APIs (the function returns an error for the other APIs). + + \param portName An optional name for the applicaction port that is + used to connect to portId can be specified. + */ + void openVirtualPort( const std::string portName = std::string( "RtMidi" ) ) + { + if (rtapi_) rtapi_->openVirtualPort(portName); + } + + //! Pure virtual function to open a MIDI connection given by enumeration number. + /*! \param portNumber An optional port number greater than 0 + can be specified. Otherwise, the default or first port + found is opened. + + \param portName An optional name for the applicaction port + that will be generated to connect to portId can be + specified. + */ + void openPort( unsigned int portNumber = 0, + const std::string portName = std::string( "RtMidi" ) ) + { + if (rtapi_) rtapi_->openPort(portNumber,portName); + } + + //! Pure virtual function to open a MIDI connection given by a port descriptor. + /*! + \param port A port descriptor of the port must be specified. + \param portName An optional name for the applicaction port that is used to connect to portId can be specified. + */ + void openPort( const PortDescriptor & port, + const std::string portName = std::string( "RtMidi" ) ) + { + if (rtapi_) rtapi_->openPort(port,portName); + } + + //! Pure virtual function to return a port descirptor if the port is open + Pointer getDescriptor() + { + if (rtapi_) return rtapi_->getDescriptor(); + return 0; + } + + //! Pure virtual function to return a list of all available ports of the current API. + /*! + \param capabilities an optional parameter that describes which + device types are returned. + + \return This function returns a list of port descriptors. + + \note An input API may but need not necessarily report + output devices which cannot be used as input if + \ref PortDescriptor::OUTPUT is passed as \ref capabilities parameter. + */ + PortList getPortList(int capabilities = PortDescriptor:: INOUTPUT) + { + if (rtapi_) return rtapi_->getPortList(capabilities); + return PortList(); + } + + //! Pure virtual to return the number of available MIDI ports of the current API. + /*! + \return This function returns the number of MIDI ports of + the selected API. + + \note Only ports are counted that can be used with the + current API so an input API does ignore all output devices + and vice versa. + + \sa getPortName + */ + unsigned int getPortCount() + { + if (rtapi_) return rtapi_->getPortCount(); + return 0; + } + + //! Pure virtual function to return a string identifier for the specified MIDI port number. + /*! + \param portNumber Number of the device to be referred to. + \return The name of the port with the given Id is returned. + \retval An empty string is returned if an invalid port specifier is provided. + + \note Only ports are counted that can be used with the + current API so an input API does ignore all output devices + and vice versa. + + \sa getPortCount() + */ + std::string getPortName( unsigned int portNumber = 0 ) + { + if (rtapi_) return rtapi_->getPortName(portNumber); + return ""; + } + + //! Close an open MIDI connection (if one exists). + void closePort( void ) + { + if (rtapi_) rtapi_->closePort(); + } + + // ! A basic error reporting function for RtMidi classes. + // static void error( Error::Type type, std::string &errorString ); + + //! Pure virtual function to return whether a port is open or not. + /*! \retval true if a port is open and + \retval false if the port is not open (e.g. not opend or closed). + */ + bool isPortOpen( void ) const + { + if (rtapi_) return rtapi_->isPortOpen(); + return false; + } + + //! Pure virtual function to set an error callback function to be invoked when an error has occured. + /*! + The callback function will be called whenever an error has occured. It is best + to set the error callback function before opening a port. + */ + void setErrorCallback( ErrorCallback errorCallback = NULL ) + { + if (rtapi_) rtapi_->setErrorCallback(errorCallback); + } + + //! A basic error reporting function for RtMidi classes. + void error( Error::Type type, std::string errorString ); + protected: + MidiApi *rtapi_; + + Midi():rtapi_(0) {} + ~Midi() + { + if (rtapi_) { + delete rtapi_; + rtapi_ = 0; + } + } + }; + + /**********************************************************************/ + /*! \class MidiIn + \brief A realtime MIDI input class. + + This class provides a common, platform-independent API for + realtime MIDI input. It allows access to a single MIDI input + port. Incoming MIDI messages are either saved to a queue for + retrieval using the getMessage() function or immediately passed to + a user-specified callback function. Create multiple instances of + this class to connect to more than one MIDI device at the same + time. With the OS-X and Linux ALSA MIDI APIs, it is also possible + to open a virtual input port to which other MIDI software clients + can connect. + + by Gary P. Scavone, 2003-2014. */ - virtual bool isPortOpen( void ) const = 0; + /**********************************************************************/ + + // **************************************************************** // + // + // MidiIn and MidiOut class declarations. + // + // MidiIn / MidiOut are "controllers" used to select an available + // MIDI input or output interface. They present common APIs for the + // user to call but all functionality is implemented by the classes + // MidiInApi, MidiOutApi and their subclasses. MidiIn and MidiOut + // each create an instance of a MidiInApi or MidiOutApi subclass based + // on the user's API choice. If no choice is made, they attempt to + // make a "logical" API selection. + // + // **************************************************************** // + + class MidiIn : public Midi + { + public: + + + //! Default constructor that allows an optional api, client name and queue size. + /*! + An exception will be thrown if a MIDI system initialization + error occurs. The queue size defines the maximum number of + messages that can be held in the MIDI queue (when not using a + callback function). If the queue size limit is reached, + incoming messages will be ignored. + + If no API argument is specified and multiple API support has been + compiled, the default order of use is JACK, ALSA (Linux) and CORE, + JACK (OS-X). + + \param api An optional API id can be specified. + \param clientName An optional Client name can be specified. This + will be used to group the ports that are created + by the application. + \param queueSizeLimit An optional size of the MIDI input queue can be specified. + */ + MidiIn( ApiType api=rtmidi::UNSPECIFIED, + const std::string clientName = std::string( "RtMidi Input Client"), + unsigned int queueSizeLimit = 100 ); + + //! If a MIDI connection is still open, it will be closed by the destructor. + ~MidiIn ( void ) throw(); + + + //! Set a callback function to be invoked for incoming MIDI messages. + /*! + The callback function will be called whenever an incoming MIDI + message is received. While not absolutely necessary, it is best + to set the callback function before opening a MIDI port to avoid + leaving some messages in the queue. + + \param callback A callback function must be given. + \param userData Opitionally, a pointer to additional data can be + passed to the callback function whenever it is called. + */ + void setCallback( MidiCallback callback, void *userData = 0 ) + { + if (rtapi_) + static_cast(rtapi_)->setCallback(callback,userData); + } + + //! Cancel use of the current callback function (if one exists). + /*! + Subsequent incoming MIDI messages will be written to the queue + and can be retrieved with the \e getMessage function. + */ + void cancelCallback() + { + if (rtapi_) + static_cast(rtapi_)->cancelCallback(); + } + + //! Specify whether certain MIDI message types should be queued or ignored during input. + /*! + By default, MIDI timing and active sensing messages are ignored + during message input because of their relative high data rates. + MIDI sysex messages are ignored by default as well. Variable + values of "true" imply that the respective message type will be + ignored. + */ + void ignoreTypes( bool midiSysex = true, + bool midiTime = true, + bool midiSense = true ) + { + if (rtapi_) + static_cast(rtapi_)->ignoreTypes(midiSysex, midiTime, midiSense); + } + + //! Fill the user-provided vector with the data bytes for the next available MIDI message in the input queue and return the event delta-time in seconds. + /*! + This function returns immediately whether a new message is + available or not. A valid message is indicated by a non-zero + vector size. An exception is thrown if an error occurs during + message retrieval or an input connection was not previously + established. + */ + double getMessage( std::vector &message ) + { + if (rtapi_) + return static_cast(rtapi_)->getMessage(message); + std::string errorString_ = "MidiIn::getMessage: No valid API found."; + error( Error::WARNING, errorString_ ); + return 0.0; + } + + //! Fill the user-provided vector with the data bytes for the next available MIDI message in the input queue and return the event delta-time in seconds. + /*! + This function returns immediately whether a new message is + available or not. A valid message is indicated by a non-zero + vector size. An exception is thrown if an error occurs during + message retrieval or an input connection was not previously + established. + + \deprecated + */ + RTMIDI_DEPRECATED(double getMessage( std::vector *message )) + { + if (!message) { + error( Error::WARNING, + "MidiIn::getMessage: passed NULL pointer"); + } + if (rtapi_) + return static_cast(rtapi_)->getMessage(*message); + error( Error::WARNING, + "MidiIn::getMessage: No valid API found."); + return 0.0; + } - //! Pure virtual function to set an error callback function to be invoked when an error has occured. - /*! - The callback function will be called whenever an error has occured. It is best - to set the error callback function before opening a port. + protected: + void openMidiApi( ApiType api, const std::string clientName, unsigned int queueSizeLimit ); + + }; + + /**********************************************************************/ + /*! \class MidiOut + \brief A realtime MIDI output class. + + This class provides a common, platform-independent API for MIDI + output. It allows one to probe available MIDI output ports, to + connect to one such port, and to send MIDI bytes immediately over + the connection. Create multiple instances of this class to + connect to more than one MIDI device at the same time. With the + OS-X and Linux ALSA MIDI APIs, it is also possible to open a + virtual port to which other MIDI software clients can connect. + + by Gary P. Scavone, 2003-2014. */ - virtual void setErrorCallback( RtMidiErrorCallback errorCallback = NULL ) = 0; -}; + /**********************************************************************/ -/**********************************************************************/ -/*! \class RtMidi - \brief A global class that implements basic backend API handling. + class MidiOut : public Midi + { + public: - This class enhances \ref CommonMidiApi by some functionality to handle - backend API objects. It serves as base class for the public RtMidi - API. + //! Default constructor that allows an optional client name. + /*! + An exception will be thrown if a MIDI system initialization error occurs. - by Gary P. Scavone, 2003-2014. -*/ -/**********************************************************************/ -class MidiApi; -class RtMidi : public CommonMidiApi -{ - public: - - //! MIDI API specifier arguments. - enum Api { - UNSPECIFIED, /*!< Search for a working compiled API. */ - MACOSX_CORE, /*!< Macintosh OS-X Core Midi API. */ - LINUX_ALSA, /*!< The Advanced Linux Sound Architecture API. */ - UNIX_JACK, /*!< The JACK Low-Latency MIDI Server API. */ - WINDOWS_MM, /*!< The Microsoft Multimedia MIDI API. */ - WINDOWS_KS, /*!< The Microsoft Kernel Streaming MIDI API. */ - RTMIDI_DUMMY /*!< A compilable but non-functional API. */ - }; - - //! A static function to determine the current RtMidi version. - static std::string getVersion( void ) throw(); - - //! A static function to determine the available compiled MIDI APIs. - /*! - The values returned in the std::vector can be compared against - the enumerated list values. Note that there can be more than one - API compiled for certain operating systems. - */ - static void getCompiledApi( std::vector &apis ) throw(); - - protected: - MidiApi *rtapi_; - - RtMidi(); - virtual ~RtMidi(); - -}; + If no API argument is specified and multiple API support has been + compiled, the default order of use is JACK, ALSA (Linux) and CORE, + JACK (OS-X). + */ + MidiOut( ApiType api=rtmidi::UNSPECIFIED, + const std::string clientName = std::string( "RtMidi Output Client") ); -/**********************************************************************/ -/*! \class RtMidiIn - \brief A realtime MIDI input class. - - This class provides a common, platform-independent API for - realtime MIDI input. It allows access to a single MIDI input - port. Incoming MIDI messages are either saved to a queue for - retrieval using the getMessage() function or immediately passed to - a user-specified callback function. Create multiple instances of - this class to connect to more than one MIDI device at the same - time. With the OS-X, Linux ALSA, and JACK MIDI APIs, it is also - possible to open a virtual input port to which other MIDI software - clients can connect. - - by Gary P. Scavone, 2003-2014. -*/ -/**********************************************************************/ + //! The destructor closes any open MIDI connections. + ~MidiOut( void ) throw(); -// **************************************************************** // -// -// RtMidiIn and RtMidiOut class declarations. -// -// RtMidiIn / RtMidiOut are "controllers" used to select an available -// MIDI input or output interface. They present common APIs for the -// user to call but all functionality is implemented by the classes -// MidiInApi, MidiOutApi and their subclasses. RtMidiIn and RtMidiOut -// each create an instance of a MidiInApi or MidiOutApi subclass based -// on the user's API choice. If no choice is made, they attempt to -// make a "logical" API selection. -// -// **************************************************************** // - -class RtMidiIn : public RtMidi -{ - public: - - //! User callback function type definition. - typedef void (*RtMidiCallback)( double timeStamp, std::vector *message, void *userData); - - //! Default constructor that allows an optional api, client name and queue size. - /*! - An exception will be thrown if a MIDI system initialization - error occurs. The queue size defines the maximum number of - messages that can be held in the MIDI queue (when not using a - callback function). If the queue size limit is reached, - incoming messages will be ignored. - - If no API argument is specified and multiple API support has been - compiled, the default order of use is ALSA, JACK (Linux) and CORE, - JACK (OS-X). - - \param api An optional API id can be specified. - \param clientName An optional client name can be specified. This - will be used to group the ports that are created - by the application. - \param queueSizeLimit An optional size of the MIDI input queue can be specified. - */ - RtMidiIn( RtMidi::Api api=UNSPECIFIED, - const std::string clientName = std::string( "RtMidi Input Client"), - unsigned int queueSizeLimit = 100 ); - - //! If a MIDI connection is still open, it will be closed by the destructor. - ~RtMidiIn ( void ) throw(); - - //! Returns the MIDI API specifier for the current instance of RtMidiIn. - RtMidi::Api getCurrentApi( void ) throw(); - - //! Create a virtual input port, with optional name, to allow software connections (OS X, JACK and ALSA only). - /*! - This function creates a virtual MIDI input port to which other - software applications can connect. This type of functionality - is currently only supported by the Macintosh OS-X, any JACK, - and Linux ALSA APIs (the function returns an error for the other APIs). - - \param portName An optional name for the applicaction port that is - used to connect to portId can be specified. - */ - void openVirtualPort( const std::string portName = std::string( "RtMidi Input" ) ); - - //! Open a MIDI input connection given by enumeration number. - /*! - \param portNumber An optional port number greater than 0 can be specified. - Otherwise, the default or first port found is opened. - \param portName An optional name for the application port that is used to connect to portId can be specified. - */ - void openPort( unsigned int portNumber = 0, const std::string portName = std::string( "RtMidi Input" ) ); - - //! Open a MIDI input connection given by a port descriptor. - /*! - \param port A port descriptor of the port must be specified. - \param portName An optional name for the applicaction port that is used to connect to portId can be specified. - */ - void openPort( const PortDescriptor & port, const std::string portName = std::string( "RtMidi" ) ); - -<<<<<<< HEAD - //! Create a virtual input port, with optional name, to allow software connections (OS X, JACK and ALSA only). - /*! - This function creates a virtual MIDI input port to which other - software applications can connect. This type of functionality - is currently only supported by the Macintosh OS-X, any JACK, - and Linux ALSA APIs (the function returns an error for the other APIs). - - \param portName An optional name for the application port that is - used to connect to portId can be specified. - -======= - //! Returns a port descirptor if the port is open - virtual CommonMidiApi::PortDescriptor::Pointer getDescriptor(); - - //! Return a list of all available input ports of the current API. - /*! - \param capabilities an optional parameter that describes which - device types are returned. - \return This function returns a list of port descriptors. - \note An Output API is not required to return all output ports from RtMidiIn. - */ - virtual CommonMidiApi::PortList getPortList(int capabilities = PortDescriptor:: INPUT); - - //! Return the number of available MIDI input ports. - /*! - \return This function returns the number of midi ports of the selected API. ->>>>>>> 70db5a0... Complete the API part of the new PortDescriptor based API - */ - unsigned int getPortCount(); - - //! Return a string identifier for the specified MIDI input port number. - /*! - \return The name of the port with the given Id is returned. - \retval An empty string is returned if an invalid port specifier is provided. - */ - std::string getPortName( unsigned int portNumber = 0 ); - - //! Close an open MIDI connection (if one exists). - void closePort( void ); - - //! Returns true if a port is open and false if not. - virtual bool isPortOpen() const; - - //! Set a callback function to be invoked for incoming MIDI messages. - /*! - The callback function will be called whenever an incoming MIDI - message is received. While not absolutely necessary, it is best - to set the callback function before opening a MIDI port to avoid - leaving some messages in the queue. - - \param callback A callback function must be given. - \param userData Optionally, a pointer to additional data can be - passed to the callback function whenever it is called. - */ - void setCallback( RtMidiCallback callback, void *userData = 0 ); - - //! Cancel use of the current callback function (if one exists). - /*! - Subsequent incoming MIDI messages will be written to the queue - and can be retrieved with the \e getMessage function. - */ - void cancelCallback(); - - //! Specify whether certain MIDI message types should be queued or ignored during input. - /*! - By default, MIDI timing and active sensing messages are ignored - during message input because of their relative high data rates. - MIDI sysex messages are ignored by default as well. Variable - values of "true" imply that the respective message type will be - ignored. - */ - void ignoreTypes( bool midiSysex = true, bool midiTime = true, bool midiSense = true ); - - //! Fill the user-provided vector with the data bytes for the next available MIDI message in the input queue and return the event delta-time in seconds. - /*! - This function returns immediately whether a new message is - available or not. A valid message is indicated by a non-zero - vector size. An exception is thrown if an error occurs during - message retrieval or an input connection was not previously - established. - */ - double getMessage( std::vector *message ); - - //! Set an error callback function to be invoked when an error has occured. - /*! - The callback function will be called whenever an error has occured. It is best - to set the error callback function before opening a port. - */ - virtual void setErrorCallback( RtMidiErrorCallback errorCallback = NULL ); - - protected: - void openMidiApi( RtMidi::Api api, const std::string clientName, unsigned int queueSizeLimit ); - -}; + //! Immediately send a single message out an open MIDI output port. + /*! + An exception is thrown if an error occurs during output or an + output connection was not previously established. + + \deprecated + */ + RTMIDI_DEPRECATED(void sendMessage( std::vector *message )) + { + if (!message) { + error( Error::WARNING, + "MidiOutApi::sendMessage: no data in message argument!"); + } + if (rtapi_) + static_cast(rtapi_)->sendMessage(*message); + error( Error::WARNING, "MidiOut::sendMessage: The API has not been set."); + } -/**********************************************************************/ -/*! \class RtMidiOut - \brief A realtime MIDI output class. - - This class provides a common, platform-independent API for MIDI - output. It allows one to probe available MIDI output ports, to - connect to one such port, and to send MIDI bytes immediately over - the connection. Create multiple instances of this class to - connect to more than one MIDI device at the same time. With the - OS-X, Linux ALSA and JACK MIDI APIs, it is also possible to open a - virtual port to which other MIDI software clients can connect. - - by Gary P. Scavone, 2003-2014. -*/ -/**********************************************************************/ -class RtMidiOut : public RtMidi -{ - public: - - //! Default constructor that allows an optional client name. - /*! - An exception will be thrown if a MIDI system initialization error occurs. - - If no API argument is specified and multiple API support has been - compiled, the default order of use is ALSA, JACK (Linux) and CORE, - JACK (OS-X). - */ - RtMidiOut( RtMidi::Api api=UNSPECIFIED, - const std::string clientName = std::string( "RtMidi Output Client") ); - - //! The destructor closes any open MIDI connections. - ~RtMidiOut( void ) throw(); - - //! Returns the MIDI API specifier for the current instance of RtMidiOut. - RtMidi::Api getCurrentApi( void ) throw(); - - //! Create a virtual output port, with optional name, to allow software connections (OS X and ALSA only). - /*! - This function creates a virtual MIDI output port to which other - software applications can connect. This type of functionality - is currently only supported by the Macintosh OS-X and Linux ALSA - APIs (the function does nothing with the other APIs). An - exception is thrown if an error occurs while attempting to create - the virtual port. - */ - void openVirtualPort( const std::string portName = std::string( "RtMidi Output" ) ); - - //! Open a MIDI output connection given by an enumeration number. - /*! - An optional port number greater than 0 can be specified. - Otherwise, the default or first port found is opened. An - exception is thrown if an error occurs while attempting to make - the port connection. - */ - void openPort( unsigned int portNumber = 0, const std::string portName = std::string( "RtMidi Output" ) ); - - //! Open a MIDI output connection given by a port descriptor. - /*! - \param port A port descriptor of the port must be specified. - \param portName An optional name for the applicaction port that is used to connect to portId can be specified. - */ - virtual void openPort( const PortDescriptor & port, const std::string portName = std::string( "RtMidi Output" ) ); - - //! Returns a port descirptor if the port is open - /*! \return Port descriptor of the currently open port - * \retval 0 iff the port s not open - */ - virtual CommonMidiApi::PortDescriptor::Pointer getDescriptor(); - - //! Close an open MIDI connection (if one exists). - void closePort( void ); - - //! Returns true if a port is open and false if not. - virtual bool isPortOpen() const; - - //! Return a list of all available ports of the current API. - /*! - \param capabilities an opitonnal parameter that describes which - device types are returned. - \return This function returns a list of port descriptors. - \note An API is not required to return all input ports from RtMidiOut. - */ - virtual CommonMidiApi::PortList getPortList(int capabilities = PortDescriptor::OUTPUT); - - //! Return the number of available MIDI output ports. - unsigned int getPortCount( void ); - - //! Return a string identifier for the specified MIDI port type and number. - /*! - \return The name of the port with the given Id is returned. - \retval An empty string is returned if an invalid port specifier is provided. - */ - std::string getPortName( unsigned int portNumber = 0 ); - - //! Immediately send a single message out an open MIDI output port. - /*! - An exception is thrown if an error occurs during output or an - output connection was not previously established. - */ - void sendMessage( std::vector *message ); - - //! Set an error callback function to be invoked when an error has occured. - /*! - The callback function will be called whenever an error has occured. It is best - to set the error callback function before opening a port. - */ - virtual void setErrorCallback( RtMidiErrorCallback errorCallback = NULL ); - - protected: - void openMidiApi( RtMidi::Api api, const std::string clientName ); -}; - - -// **************************************************************** // -// -// MidiInApi / MidiOutApi class declarations. -// -// Subclasses of MidiInApi and MidiOutApi contain all API- and -// OS-specific code necessary to fully implement the RtMidi API. -// -// Note that MidiInApi and MidiOutApi are abstract base classes and -// cannot be explicitly instantiated. RtMidiIn and RtMidiOut will -// create instances of a MidiInApi or MidiOutApi subclass. -// -// **************************************************************** // - -class MidiApi: public CommonMidiApi -{ - public: - - MidiApi(); - virtual ~MidiApi(); - - virtual unsigned int getPortCount( void ) = 0; - virtual std::string getPortName( unsigned int portNumber ) = 0; - - bool isPortOpen() const { return connected_; } - void setErrorCallback( RtMidiErrorCallback errorCallback ); - - - //! Returns the MIDI API specifier for the current instance of RtMidiIn. - virtual RtMidi::Api getCurrentApi( void ) throw(); - - //! A basic error reporting function for RtMidi classes. - void error( RtMidiError::Type type, std::string errorString ); - -protected: - virtual void initialize( const std::string& clientName ) = 0; - - void *apiData_; - bool connected_; - std::string errorString_; - RtMidiErrorCallback errorCallback_; -}; - -class MidiInApi : public MidiApi -{ - public: - - MidiInApi( unsigned int queueSizeLimit ); - virtual ~MidiInApi( void ); - void setCallback( RtMidiIn::RtMidiCallback callback, void *userData ); - void cancelCallback( void ); - virtual void ignoreTypes( bool midiSysex, bool midiTime, bool midiSense ); - double getMessage( std::vector *message ); - - // A MIDI structure used internally by the class to store incoming - // messages. Each message represents one and only one MIDI message. - struct MidiMessage { - std::vector bytes; - double timeStamp; - - // Default constructor. - MidiMessage() - :bytes(0), timeStamp(0.0) {} - }; - - struct MidiQueue { - unsigned int front; - unsigned int back; - unsigned int size; - unsigned int ringSize; - MidiMessage *ring; - - // Default constructor. - MidiQueue() - :front(0), back(0), size(0), ringSize(0) {} - }; - - // The RtMidiInData structure is used to pass private class data to - // the MIDI input handling function or thread. - struct RtMidiInData { - MidiQueue queue; - MidiMessage message; - unsigned char ignoreFlags; - bool doInput; - bool firstMessage; - void *apiData; - bool usingCallback; - RtMidiIn::RtMidiCallback userCallback; - void *userData; - bool continueSysex; - - // Default constructor. - RtMidiInData() - : ignoreFlags(7), doInput(false), firstMessage(true), - apiData(0), usingCallback(false), userCallback(0), userData(0), - continueSysex(false) {} - }; - - protected: - RtMidiInData inputData_; -}; - -class MidiOutApi : public MidiApi -{ - public: - - MidiOutApi( void ); - virtual ~MidiOutApi( void ); - virtual void sendMessage( std::vector *message ) = 0; -}; - -// **************************************************************** // -// -// Inline RtMidiIn and RtMidiOut definitions. -// -// **************************************************************** // - -inline RtMidi::Api RtMidiIn :: getCurrentApi( void ) throw() -{ - return rtapi_->getCurrentApi(); -} -inline void RtMidiIn :: openVirtualPort( const std::string portName ) -{ - rtapi_->openVirtualPort( portName ); -} -inline void RtMidiIn :: openPort( unsigned int portNumber, - const std::string portName ) -{ - rtapi_->openPort( portNumber, portName ); -} -inline void RtMidiIn :: openPort( const CommonMidiApi::PortDescriptor & port, - const std::string portName) -{ - rtapi_->openPort(port,portName); -} -inline CommonMidiApi::PortDescriptor::Pointer RtMidiIn :: getDescriptor() -{ - return rtapi_->getDescriptor(); -} -inline CommonMidiApi::PortList RtMidiIn :: getPortList(int capabilities) -{ - return rtapi_->getPortList(capabilities); -} -inline unsigned int RtMidiIn :: getPortCount( void ) -{ - return rtapi_->getPortCount(); -} -inline std::string RtMidiIn :: getPortName( unsigned int portNumber ) -{ - return rtapi_->getPortName( portNumber ); -} -inline void RtMidiIn :: closePort( void ) { rtapi_->closePort(); } -inline bool RtMidiIn :: isPortOpen() const { return rtapi_->isPortOpen(); } -inline void RtMidiIn :: setCallback( RtMidiCallback callback, - void *userData ) -{ - ((MidiInApi *)rtapi_)->setCallback( callback, userData ); -} -inline void RtMidiIn :: cancelCallback( void ) -{ - ((MidiInApi *)rtapi_)->cancelCallback(); -} -inline void RtMidiIn :: ignoreTypes( bool midiSysex, - bool midiTime, - bool midiSense ) -{ - ((MidiInApi *)rtapi_)->ignoreTypes( midiSysex, midiTime, midiSense ); -} -inline double RtMidiIn :: getMessage( std::vector *message ) -{ - return ((MidiInApi *)rtapi_)->getMessage( message ); -} -inline void RtMidiIn :: setErrorCallback( RtMidiErrorCallback errorCallback ) -{ - rtapi_->setErrorCallback(errorCallback); -} + //! Immediately send a single message out an open MIDI output port. + /*! + An exception is thrown if an error occurs during output or an + output connection was not previously established. + */ + void sendMessage( std::vector &message ) { + if (rtapi_) + static_cast(rtapi_)->sendMessage(message); + error( Error::WARNING, "MidiOut::sendMessage: The API has not been set."); + } + protected: + void openMidiApi( ApiType api, const std::string clientName ); + }; -inline RtMidi::Api RtMidiOut :: getCurrentApi( void ) throw() -{ - return rtapi_->getCurrentApi(); -} -inline void RtMidiOut :: openPort( unsigned int portNumber, const std::string portName ) -{ - rtapi_->openPort( portNumber, portName ); -} -inline void RtMidiOut :: openVirtualPort( const std::string portName ) -{ - rtapi_->openVirtualPort( portName ); -} -inline void RtMidiOut :: openPort( const CommonMidiApi::PortDescriptor & port, - const std::string portName) -{ - rtapi_->openPort(port,portName); -} -inline CommonMidiApi::PortDescriptor::Pointer RtMidiOut :: getDescriptor() -{ - return rtapi_->getDescriptor(); -} -inline CommonMidiApi::PortList RtMidiOut :: getPortList(int capabilities) -{ - return rtapi_->getPortList(capabilities); -} -inline void RtMidiOut :: closePort( void ) -{ - rtapi_->closePort(); -} -inline bool RtMidiOut :: isPortOpen() const -{ - return rtapi_->isPortOpen(); -} -inline unsigned int RtMidiOut :: getPortCount( void ) -{ - return rtapi_->getPortCount(); -} -inline std::string RtMidiOut :: getPortName( unsigned int portNumber ) -{ - return rtapi_->getPortName( portNumber ); -} -inline void RtMidiOut :: sendMessage( std::vector *message ) -{ - ((MidiOutApi *)rtapi_)->sendMessage( message ); -} -inline void RtMidiOut :: setErrorCallback( RtMidiErrorCallback errorCallback ) -{ - rtapi_->setErrorCallback(errorCallback); -} -// **************************************************************** // -// -// MidiInApi and MidiOutApi subclass prototypes. -// -// **************************************************************** // + // **************************************************************** // + // + // MidiInApi and MidiOutApi subclass prototypes. + // + // **************************************************************** // #if !defined(__LINUX_ALSA__) && !defined(__UNIX_JACK__) && !defined(__MACOSX_CORE__) && !defined(__WINDOWS_MM__) && !defined(__WINDOWS_KS__) - #define __RTMIDI_DUMMY__ +#define __RTMIDI_DUMMY__ #endif #if defined(__MACOSX_CORE__) -class MidiInCore: public MidiInApi -{ - public: - MidiInCore( const std::string clientName, unsigned int queueSizeLimit ); - ~MidiInCore( void ); - RtMidi::Api getCurrentApi( void ) { return RtMidi::MACOSX_CORE; }; - void openPort( unsigned int portNumber, const std::string portName ); - void openVirtualPort( const std::string portName ); - void openPort( const PortDescriptor & port, const std::string portName); - CommonMidiApi::PortDescriptor::Pointer getDescriptor(); - CommonMidiApi::PortList getPortList(int capabilities); - void closePort( void ); - unsigned int getPortCount( void ); - std::string getPortName( unsigned int portNumber ); - - protected: - void initialize( const std::string& clientName ); -}; - -class MidiOutCore: public MidiOutApi -{ - public: - MidiOutCore( const std::string clientName ); - ~MidiOutCore( void ); - RtMidi::Api getCurrentApi( void ) { return RtMidi::MACOSX_CORE; }; - void openPort( unsigned int portNumber, const std::string portName ); - void openVirtualPort( const std::string portName ); - void openPort( const PortDescriptor & port, const std::string portName); - CommonMidiApi::PortDescriptor::Pointer getDescriptor(); - CommonMidiApi::PortList getPortList(int capabilities); - void closePort( void ); - unsigned int getPortCount( void ); - std::string getPortName( unsigned int portNumber ); - void sendMessage( std::vector *message ); - - protected: - void initialize( const std::string& clientName ); -}; + class MidiInCore: public MidiInApi + { + public: + MidiInCore( const std::string clientName, unsigned int queueSizeLimit ); + ~MidiInCore( void ); + ApiType getCurrentApi( void ) { return MACOSX_CORE; }; + void openPort( unsigned int portNumber, const std::string portName ); + void openVirtualPort( const std::string portName ); + void openPort( const PortDescriptor & port, const std::string portName); + Pointer getDescriptor(); + PortList getPortList(int capabilities); + void closePort( void ); + unsigned int getPortCount( void ); + std::string getPortName( unsigned int portNumber ); + + protected: + void initialize( const std::string& clientName ); + }; + + class MidiOutCore: public MidiOutApi + { + public: + MidiOutCore( const std::string clientName ); + ~MidiOutCore( void ); + ApiType getCurrentApi( void ) { return MACOSX_CORE; }; + void openPort( unsigned int portNumber, const std::string portName ); + void openVirtualPort( const std::string portName ); + void openPort( const PortDescriptor & port, const std::string portName); + Pointer getDescriptor(); + PortList getPortList(int capabilities); + void closePort( void ); + unsigned int getPortCount( void ); + std::string getPortName( unsigned int portNumber ); + void sendMessage( std::vector &message ); + + protected: + void initialize( const std::string& clientName ); + }; #endif #if defined(__UNIX_JACK__) -class MidiInJack: public MidiInApi -{ - public: - MidiInJack( const std::string clientName, unsigned int queueSizeLimit ); - ~MidiInJack( void ); - RtMidi::Api getCurrentApi( void ) { return RtMidi::UNIX_JACK; }; - void openPort( unsigned int portNumber, const std::string portName ); - void openVirtualPort( const std::string portName ); - void openPort( const PortDescriptor & port, const std::string portName); - CommonMidiApi::PortDescriptor::Pointer getDescriptor(); - CommonMidiApi::PortList getPortList(int capabilities); - void closePort( void ); - unsigned int getPortCount( void ); - std::string getPortName( unsigned int portNumber ); - - protected: - std::string clientName; - - void connect( void ); - void initialize( const std::string& clientName ); -}; - -class MidiOutJack: public MidiOutApi -{ - public: - MidiOutJack( const std::string clientName ); - ~MidiOutJack( void ); - RtMidi::Api getCurrentApi( void ) { return RtMidi::UNIX_JACK; }; - void openPort( unsigned int portNumber, const std::string portName ); - void openVirtualPort( const std::string portName ); - void openPort( const PortDescriptor & port, const std::string portName); - CommonMidiApi::PortDescriptor::Pointer getDescriptor(); - CommonMidiApi::PortList getPortList(int capabilities); - void closePort( void ); - unsigned int getPortCount( void ); - std::string getPortName( unsigned int portNumber ); - void sendMessage( std::vector *message ); - - protected: - std::string clientName; - - void connect( void ); - void initialize( const std::string& clientName ); -}; + class MidiInJack: public MidiInApi + { + public: + MidiInJack( const std::string clientName, unsigned int queueSizeLimit ); + ~MidiInJack( void ); + ApiType getCurrentApi( void ) { return UNIX_JACK; }; + void openPort( unsigned int portNumber, const std::string portName ); + void openVirtualPort( const std::string portName ); + void openPort( const PortDescriptor & port, const std::string portName); + Pointer getDescriptor(); + PortList getPortList(int capabilities); + void closePort( void ); + unsigned int getPortCount( void ); + std::string getPortName( unsigned int portNumber ); + + protected: + std::string clientName; + + void connect( void ); + void initialize( const std::string& clientName ); + }; + + class MidiOutJack: public MidiOutApi + { + public: + MidiOutJack( const std::string clientName ); + ~MidiOutJack( void ); + ApiType getCurrentApi( void ) { return UNIX_JACK; }; + void openPort( unsigned int portNumber, const std::string portName ); + void openVirtualPort( const std::string portName ); + void openPort( const PortDescriptor & port, const std::string portName); + Pointer getDescriptor(); + PortList getPortList(int capabilities); + void closePort( void ); + unsigned int getPortCount( void ); + std::string getPortName( unsigned int portNumber ); + void sendMessage( std::vector &message ); + + protected: + std::string clientName; + + void connect( void ); + void initialize( const std::string& clientName ); + }; #endif #if defined(__LINUX_ALSA__) -class MidiInAlsa: public MidiInApi -{ - public: - MidiInAlsa( const std::string clientName, unsigned int queueSizeLimit ); - ~MidiInAlsa( void ); - RtMidi::Api getCurrentApi( void ) throw() { return RtMidi::LINUX_ALSA; }; - void openPort( unsigned int portNumber, const std::string portName ); - void openVirtualPort( const std::string portName ); - void openPort( const PortDescriptor & port, const std::string portName); - CommonMidiApi::PortDescriptor::Pointer getDescriptor(); - CommonMidiApi::PortList getPortList(int capabilities); - void closePort( void ); - unsigned int getPortCount( void ); - std::string getPortName( unsigned int portNumber ); - - protected: - void initialize( const std::string& clientName ); -}; - -class MidiOutAlsa: public MidiOutApi -{ - public: - MidiOutAlsa( const std::string clientName ); - ~MidiOutAlsa( void ); - RtMidi::Api getCurrentApi( void ) throw() { return RtMidi::LINUX_ALSA; }; - void openPort( unsigned int portNumber, const std::string portName ); - void openVirtualPort( const std::string portName ); - void openPort( const PortDescriptor & port, const std::string portName); - CommonMidiApi::PortDescriptor::Pointer getDescriptor(); - CommonMidiApi::PortList getPortList(int capabilities); - void closePort( void ); - unsigned int getPortCount( void ); - std::string getPortName( unsigned int portNumber ); - void sendMessage( std::vector *message ); - - protected: - void initialize( const std::string& clientName ); -}; + class MidiInAlsa: public MidiInApi + { + public: + MidiInAlsa( const std::string clientName, unsigned int queueSizeLimit ); + ~MidiInAlsa( void ); + ApiType getCurrentApi( void ) throw() { return LINUX_ALSA; }; + void openPort( unsigned int portNumber, const std::string portName ); + void openVirtualPort( const std::string portName ); + void openPort( const PortDescriptor & port, const std::string portName); + Pointer getDescriptor(); + PortList getPortList(int capabilities); + void closePort( void ); + unsigned int getPortCount( void ); + std::string getPortName( unsigned int portNumber ); + + protected: + void initialize( const std::string& clientName ); + }; + + class MidiOutAlsa: public MidiOutApi + { + public: + MidiOutAlsa( const std::string clientName ); + ~MidiOutAlsa( void ); + ApiType getCurrentApi( void ) throw() { return LINUX_ALSA; }; + void openPort( unsigned int portNumber, const std::string portName ); + void openVirtualPort( const std::string portName ); + void openPort( const PortDescriptor & port, const std::string portName); + Pointer getDescriptor(); + PortList getPortList(int capabilities); + void closePort( void ); + unsigned int getPortCount( void ); + std::string getPortName( unsigned int portNumber ); + void sendMessage( std::vector &message ); + + protected: + void initialize( const std::string& clientName ); + }; #endif #if defined(__WINDOWS_MM__) -class MidiInWinMM: public MidiInApi -{ - public: - MidiInWinMM( const std::string clientName, unsigned int queueSizeLimit ); - ~MidiInWinMM( void ); - RtMidi::Api getCurrentApi( void ) { return RtMidi::WINDOWS_MM; }; - void openPort( unsigned int portNumber, const std::string portName ); - void openVirtualPort( const std::string portName ); - void openPort( const PortDescriptor & port, const std::string portName); - CommonMidiApi::PortDescriptor::Pointer getDescriptor(); - CommonMidiApi::PortList getPortList(int capabilities); - void closePort( void ); - unsigned int getPortCount( void ); - std::string getPortName( unsigned int portNumber ); - - protected: - void initialize( const std::string& clientName ); -}; - -class MidiOutWinMM: public MidiOutApi -{ - public: - MidiOutWinMM( const std::string clientName ); - ~MidiOutWinMM( void ); - RtMidi::Api getCurrentApi( void ) { return RtMidi::WINDOWS_MM; }; - void openPort( unsigned int portNumber, const std::string portName ); - void openVirtualPort( const std::string portName ); - void openPort( const PortDescriptor & port, const std::string portName); - CommonMidiApi::PortDescriptor::Pointer getDescriptor(); - CommonMidiApi::PortList getPortList(int capabilities); - void closePort( void ); - unsigned int getPortCount( void ); - std::string getPortName( unsigned int portNumber ); - void sendMessage( std::vector *message ); - - protected: - void initialize( const std::string& clientName ); -}; + class MidiInWinMM: public MidiInApi + { + public: + MidiInWinMM( const std::string clientName, unsigned int queueSizeLimit ); + ~MidiInWinMM( void ); + ApiType getCurrentApi( void ) { return WINDOWS_MM; }; + void openPort( unsigned int portNumber, const std::string portName ); + void openVirtualPort( const std::string portName ); + void openPort( const PortDescriptor & port, const std::string portName); + Pointer getDescriptor(); + PortList getPortList(int capabilities); + void closePort( void ); + unsigned int getPortCount( void ); + std::string getPortName( unsigned int portNumber ); + + protected: + void initialize( const std::string& clientName ); + }; + + class MidiOutWinMM: public MidiOutApi + { + public: + MidiOutWinMM( const std::string clientName ); + ~MidiOutWinMM( void ); + ApiType getCurrentApi( void ) { return WINDOWS_MM; }; + void openPort( unsigned int portNumber, const std::string portName ); + void openVirtualPort( const std::string portName ); + void openPort( const PortDescriptor & port, const std::string portName); + Pointer getDescriptor(); + PortList getPortList(int capabilities); + void closePort( void ); + unsigned int getPortCount( void ); + std::string getPortName( unsigned int portNumber ); + void sendMessage( std::vector &message ); + + protected: + void initialize( const std::string& clientName ); + }; #endif #if defined(__WINDOWS_KS__) -class MidiInWinKS: public MidiInApi -{ - public: - MidiInWinKS( const std::string clientName, unsigned int queueSizeLimit ); - ~MidiInWinKS( void ); - RtMidi::Api getCurrentApi( void ) { return RtMidi::WINDOWS_KS; }; - void openPort( unsigned int portNumber, const std::string portName ); - void openVirtualPort( const std::string portName ); - void openPort( const PortDescriptor & port, const std::string portName); - CommonMidiApi::PortDescriptor::Pointer getDescriptor(); - CommonMidiApi::PortList getPortList(int capabilities); - void closePort( void ); - unsigned int getPortCount( void ); - std::string getPortName( unsigned int portNumber ); - - protected: - void initialize( const std::string& clientName ); -}; - -class MidiOutWinKS: public MidiOutApi -{ - public: - MidiOutWinKS( const std::string clientName ); - ~MidiOutWinKS( void ); - RtMidi::Api getCurrentApi( void ) { return RtMidi::WINDOWS_KS; }; - void openPort( unsigned int portNumber, const std::string portName ); - void openVirtualPort( const std::string portName ); - void openPort( const PortDescriptor & port, const std::string portName); - CommonMidiApi::PortDescriptor::Pointer getDescriptor(); - CommonMidiApi::PortList getPortList(int capabilities); - void closePort( void ); - unsigned int getPortCount( void ); - std::string getPortName( unsigned int portNumber ); - void sendMessage( std::vector *message ); - - protected: - void initialize( const std::string& clientName ); -}; + class MidiInWinKS: public MidiInApi + { + public: + MidiInWinKS( const std::string clientName, unsigned int queueSizeLimit ); + ~MidiInWinKS( void ); + ApiType getCurrentApi( void ) { return WINDOWS_KS; }; + void openPort( unsigned int portNumber, const std::string portName ); + void openVirtualPort( const std::string portName ); + void openPort( const PortDescriptor & port, const std::string portName); + Pointer getDescriptor(); + PortList getPortList(int capabilities); + void closePort( void ); + unsigned int getPortCount( void ); + std::string getPortName( unsigned int portNumber ); + + protected: + void initialize( const std::string& clientName ); + }; + + class MidiOutWinKS: public MidiOutApi + { + public: + MidiOutWinKS( const std::string clientName ); + ~MidiOutWinKS( void ); + ApiType getCurrentApi( void ) { return WINDOWS_KS; }; + void openPort( unsigned int portNumber, const std::string portName ); + void openVirtualPort( const std::string portName ); + void openPort( const PortDescriptor & port, const std::string portName); + Pointer getDescriptor(); + PortList getPortList(int capabilities); + void closePort( void ); + unsigned int getPortCount( void ); + std::string getPortName( unsigned int portNumber ); + void sendMessage( std::vector &message ); + + protected: + void initialize( const std::string& clientName ); + }; #endif #if defined(__RTMIDI_DUMMY__) -class MidiInDummy: public MidiInApi -{ - public: - MidiInDummy( const std::string /*clientName*/, unsigned int queueSizeLimit ) - : MidiInApi( queueSizeLimit ) { - errorString_ = "MidiInDummy: This class provides no functionality."; - error( RtMidiError::WARNING, errorString_ ); - } - RtMidi::Api getCurrentApi( void ) { return RtMidi::RTMIDI_DUMMY; } - void openPort( unsigned int /*portNumber*/, const std::string /*portName*/ ) {} - void openVirtualPort( const std::string /*portName*/ ) {} - void openPort( const PortDescriptor & port, const std::string portName) {} - CommonMidiApi::PortDescriptor::Pointer getDescriptor() { return 0; } - CommonMidiApi::PortList getPortList(int capabilities) { return CommonMidiApi::PortList(); } - void closePort( void ) {} - unsigned int getPortCount( void ) { return 0; } - std::string getPortName( unsigned int portNumber ) { return ""; } - - protected: - void initialize( const std::string& /*clientName*/ ) {} -}; - -class MidiOutDummy: public MidiOutApi -{ - public: - MidiOutDummy( const std::string /*clientName*/ ) { - errorString_ = "MidiOutDummy: This class provides no functionality."; - error( RtMidiError::WARNING, errorString_ ); - } - RtMidi::Api getCurrentApi( void ) { return RtMidi::RTMIDI_DUMMY; } - void openPort( unsigned int /*portNumber*/, const std::string /*portName*/ ) {} - void openVirtualPort( const std::string /*portName*/ ) {} - void openPort( const PortDescriptor & port, const std::string portName) {} - CommonMidiApi::PortDescriptor::Pointer getDescriptor() { return 0; } - CommonMidiApi::PortList getPortList(int capabilities) { return CommonMidiApi::PortList(); } - void closePort( void ) {} - unsigned int getPortCount( void ) { return 0; } - std::string getPortName( unsigned int /*portNumber*/ ) { return ""; } - void sendMessage( std::vector * /*message*/ ) {} - - protected: - void initialize( const std::string& /*clientName*/ ) {} -}; + class MidiInDummy: public MidiInApi + { + public: + MidiInDummy( const std::string /*clientName*/, unsigned int queueSizeLimit ) + : MidiInApi( queueSizeLimit ) { + errorString_ = "MidiInDummy: This class provides no functionality."; + error( Error::WARNING, errorString_ ); + } + ApiType getCurrentApi( void ) { return RTMIDI_DUMMY; } + void openPort( unsigned int /*portNumber*/, const std::string /*portName*/ ) {} + void openVirtualPort( const std::string /*portName*/ ) {} + void openPort( const PortDescriptor & port, const std::string portName) {} + Pointer getDescriptor() { return 0; } + PortList getPortList(int capabilities) { return PortList(); } + void closePort( void ) {} + unsigned int getPortCount( void ) { return 0; } + std::string getPortName( unsigned int portNumber ) { return ""; } + + protected: + void initialize( const std::string& /*clientName*/ ) {} + }; + + class MidiOutDummy: public MidiOutApi + { + public: + MidiOutDummy( const std::string /*clientName*/ ) { + errorString_ = "MidiOutDummy: This class provides no functionality."; + error( Error::WARNING, errorString_ ); + } + ApiType getCurrentApi( void ) { return RTMIDI_DUMMY; } + void openPort( unsigned int /*portNumber*/, const std::string /*portName*/ ) {} + void openVirtualPort( const std::string /*portName*/ ) {} + void openPort( const PortDescriptor & port, const std::string portName) {} + Pointer getDescriptor() { return 0; } + PortList getPortList(int capabilities) { return PortList(); } + void closePort( void ) {} + unsigned int getPortCount( void ) { return 0; } + std::string getPortName( unsigned int /*portNumber*/ ) { return ""; } + void sendMessage( std::vector & /*message*/ ) {} + + protected: + void initialize( const std::string& /*clientName*/ ) {} + }; #endif +} + +typedef rtmidi::Midi RtMidi; +typedef rtmidi::MidiIn RtMidiIn; +typedef rtmidi::MidiOut RtMidiOut; +typedef rtmidi::Error RtMidiError; #endif From f86c3d17d96727db675ea2a4c214df51e6bf1247 Mon Sep 17 00:00:00 2001 From: Tobias Schlemmer Date: Sun, 30 Mar 2014 16:16:52 +0200 Subject: [PATCH 19/45] Fix phony make target tests. --- Makefile.in | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Makefile.in b/Makefile.in index 82ad7ad7..b51713dd 100644 --- a/Makefile.in +++ b/Makefile.in @@ -22,6 +22,8 @@ CFLAGS = @CXXFLAGS@ -Iinclude -fPIC PREFIX = @prefix@ +.PHONY: tests + all : $(LIBRARIES) tests: From 2b03232b180265c20323674476b6b2576501da94 Mon Sep 17 00:00:00 2001 From: Tobias Schlemmer Date: Sun, 30 Mar 2014 16:19:24 +0200 Subject: [PATCH 20/45] Bump library version. Even though this feature is currently unused we should use a different library version for future development. While we provide workarounds for the API the ABI has changed. --- Makefile.in | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Makefile.in b/Makefile.in index b51713dd..4d8dabfd 100644 --- a/Makefile.in +++ b/Makefile.in @@ -9,8 +9,13 @@ OBJECTS = RtMidi.o LIBNAME = librtmidi STATIC = $(LIBNAME).a SHARED = @sharedlib@ +<<<<<<< HEAD RELEASE = 2.1.0 MAJOR = 2 +======= +RELEASE = 3.0.0 +MAJOR = 3 +>>>>>>> Bump library version. LIBRARIES = $(STATIC) $(SHARED) CC = @CXX@ From 44c645c85348578cd48925a35b010983a35b1fc4 Mon Sep 17 00:00:00 2001 From: Tobias Schlemmer Date: Sun, 30 Mar 2014 16:20:03 +0200 Subject: [PATCH 21/45] Silence some warnings about unused parameters. --- tests/midiout.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/midiout.cpp b/tests/midiout.cpp index 05505cc6..49c5b081 100644 --- a/tests/midiout.cpp +++ b/tests/midiout.cpp @@ -24,7 +24,7 @@ // It returns false if there are no ports available. bool chooseMidiPort( RtMidiOut *rtmidi ); -int main( void ) +int main( int /* argc*/, char */*argv*/[] ) { RtMidiOut *midiout = 0; std::vector message; From 707f3617a70d5b57ce929e18fe4cbff85d66b4d5 Mon Sep 17 00:00:00 2001 From: Tobias Schlemmer Date: Sat, 5 Apr 2014 10:34:05 +0200 Subject: [PATCH 22/45] Provide some abstraction layer that will eventually handle all generic ALSA calls. This layer provides an API that is more consistent with the data used by RtMidi. On the other hand it allows to optionally use a locking mechanism for all sequencer calls so that ALSA may use one client for all threads for certain tasks (or if it is requested). --- RtMidi.cpp | 441 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 435 insertions(+), 6 deletions(-) diff --git a/RtMidi.cpp b/RtMidi.cpp index 6a3098d9..4e19c3b2 100644 --- a/RtMidi.cpp +++ b/RtMidi.cpp @@ -1145,12 +1145,360 @@ namespace rtmidi { #include namespace rtmidi { - // A structure to hold variables related to the ALSA API - // implementation. - struct AlsaMidiData { - snd_seq_t *seq; - unsigned int portNum; - int vport; + struct AlsaMidiData; + + /*! An abstraction layer for the ALSA sequencer layer. It provides + the following functionality: + - dynamic allocation of the sequencer + - optionallay avoid concurrent access to the ALSA sequencer, + which is not thread proof. This feature is controlled by + the parameter \ref locking. + */ + + template + class AlsaSequencer { + public: + AlsaSequencer():seq(0) + { + if (locking) { + pthread_mutexattr_t attr; + pthread_mutexattr_init(&attr); + pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_NORMAL); + pthread_mutex_init(&mutex, &attr); + } + } + + AlsaSequencer(const std::string & name):seq(0) + { + if (locking) { + pthread_mutexattr_t attr; + pthread_mutexattr_init(&attr); + pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_NORMAL); + pthread_mutex_init(&mutex, &attr); + } + init(); + { + scoped_lock lock(mutex); + snd_seq_set_client_name( seq, name.c_str() ); + } + } + + ~AlsaSequencer() + { + if (locking) { + pthread_mutex_destroy(&mutex); + } + } + + std::string GetPortName(int client, int port, int flags) { + init(); + snd_seq_client_info_t *cinfo; + snd_seq_client_info_alloca( &cinfo ); + { + scoped_lock lock (mutex); + snd_seq_get_any_client_info(seq,client,cinfo); + } + + snd_seq_port_info_t *pinfo; + snd_seq_port_info_alloca( &pinfo ); + { + scoped_lock lock (mutex); + snd_seq_get_any_port_info(seq,client,port,pinfo); + } + + int naming = flags & PortDescriptor::NAMING_MASK; + + std::ostringstream os; + switch (naming) { + case PortDescriptor::SESSION_PATH: + if (flags & PortDescriptor::INCLUDE_API) + os << "ALSA:"; + os << client << ":" << port; + break; + case PortDescriptor::STORAGE_PATH: + if (flags & PortDescriptor::INCLUDE_API) + os << "ALSA:"; + os << snd_seq_client_info_get_name(cinfo); + os << ":"; + os << snd_seq_port_info_get_name(pinfo); + if (flags & PortDescriptor::UNIQUE_NAME) + os << ";" << client << ":" << port; + break; + case PortDescriptor::LONG_NAME: + os << snd_seq_client_info_get_name( cinfo ); + if (flags & PortDescriptor::UNIQUE_NAME) { + os << " " << client; + } + os << ":"; + if (flags & PortDescriptor::UNIQUE_NAME) { + os << port; + } + + os << " " << snd_seq_port_info_get_name(pinfo); + if (flags & PortDescriptor::INCLUDE_API) + os << " (ALSA)"; + break; + case PortDescriptor::SHORT_NAME: + default: + os << snd_seq_client_info_get_name( cinfo ); + if (flags & PortDescriptor::UNIQUE_NAME) { + os << " "; + os << client; + } + os << ":" << port; + if (flags & PortDescriptor::INCLUDE_API) + os << " (ALSA)"; + + break; + } + return os.str(); + } + + int getPortCapabilities(int client, int port) { + snd_seq_port_info_t *pinfo; + snd_seq_port_info_alloca( &pinfo ); + { + scoped_lock lock (mutex); + snd_seq_get_any_port_info(seq,client,port,pinfo); + } + unsigned int caps = snd_seq_port_info_get_capability(pinfo); + int retval = (caps & (SND_SEQ_PORT_CAP_READ|SND_SEQ_PORT_CAP_SUBS_READ))? + PortDescriptor::INPUT:0; + if (caps & (SND_SEQ_PORT_CAP_WRITE|SND_SEQ_PORT_CAP_SUBS_WRITE)) + retval |= PortDescriptor::OUTPUT; + return retval; + } + + int getNextClient(snd_seq_client_info_t * cinfo ) { + init(); + scoped_lock lock (mutex); + return snd_seq_query_next_client (seq, cinfo); + } + int getNextPort(snd_seq_port_info_t * pinfo ) { + init(); + scoped_lock lock (mutex); + return snd_seq_query_next_port (seq, pinfo); + } + + int createPort (snd_seq_port_info_t *pinfo) { + init(); + scoped_lock lock (mutex); + return snd_seq_create_port(seq, pinfo); + } + + void deletePort(int port) { + init(); + scoped_lock lock (mutex); + snd_seq_delete_port( seq, port ); + } + + snd_seq_port_subscribe_t * connectPorts(const snd_seq_addr_t & from, + const snd_seq_addr_t & to) { + init(); + snd_seq_port_subscribe_t *subscription; + + if (snd_seq_port_subscribe_malloc( &subscription ) < 0) { + throw Error("MidiInAlsa::openPort: ALSA error allocation port subscription.", + Error::DRIVER_ERROR ); + return 0; + } + snd_seq_port_subscribe_set_sender(subscription, &from); + snd_seq_port_subscribe_set_dest(subscription, &to); + { + scoped_lock lock (mutex); + if ( snd_seq_subscribe_port(seq, subscription) ) { + snd_seq_port_subscribe_free( subscription ); + subscription = 0; + throw Error("MidiInAlsa::openPort: ALSA error making port connection.", + Error::DRIVER_ERROR); + return 0; + } + return subscription; + } + } + + void closePort(snd_seq_port_subscribe_t * subscription ) { + init(); + scoped_lock lock(mutex); + snd_seq_unsubscribe_port( seq, subscription ); + } + + void startQueue(int queue_id) { + init(); + scoped_lock lock(mutex); + snd_seq_start_queue( seq, queue_id, NULL ); + snd_seq_drain_output( seq ); + } + + /*! Use AlsaSequencer like a C pointer. + \note This function breaks the design to control thread safety + by the selection of the \ref locking parameter to the class. + It should be removed as soon as possible in order ensure the + thread policy that has been intended by creating this class. + */ + operator snd_seq_t * () + { + return seq; + } + protected: + struct scoped_lock { + pthread_mutex_t * mutex; + scoped_lock(pthread_mutex_t & m): mutex(&m) + { + if (locking) + pthread_mutex_lock(mutex); + } + ~scoped_lock() + { + if (locking) + pthread_mutex_unlock(mutex); + } + }; + pthread_mutex_t mutex; + snd_seq_t * seq; + + + snd_seq_client_info_t * GetClient(int id) { + init(); + snd_seq_client_info_t * cinfo; + scoped_lock lock(mutex); + snd_seq_get_any_client_info(seq,id,cinfo); + return cinfo; + } + + void init() + { + init (seq); + } + + void init(snd_seq_t * &s) + { + if (s) return; + { + scoped_lock lock(mutex); + int result = snd_seq_open(&s, "default", SND_SEQ_OPEN_DUPLEX, SND_SEQ_NONBLOCK); + if ( result < 0 ) { + throw Error( "MidiInAlsa::initialize: error creating ALSA sequencer client object.", + Error::DRIVER_ERROR ); + return; + } + } + } + }; + typedef AlsaSequencer<1> LockingAlsaSequencer; + typedef AlsaSequencer<0> NonLockingAlsaSequencer; + + struct AlsaPortDescriptor:public PortDescriptor, + public snd_seq_addr_t + { + MidiApi * api; + static LockingAlsaSequencer seq; + AlsaPortDescriptor():api(0) + { + client = 0; + port = 0; + } + AlsaPortDescriptor(int c, int p):api(0) + { + client = c; + port = p; + } + ~AlsaPortDescriptor() {} + MidiApi * getAPI() { + return NULL; + } + std::string getName(int flags = SHORT_NAME | UNIQUE_NAME) { + return seq.GetPortName(client,port,flags); + } + int getCapabilities() { + return seq.getPortCapabilities(client,port); + } + static PortList getPortList(int capabilities); + }; + + LockingAlsaSequencer AlsaPortDescriptor::seq; + + + + PortList AlsaPortDescriptor :: getPortList(int capabilities) + { + PortList list; + snd_seq_client_info_t *cinfo; + snd_seq_port_info_t *pinfo; + int client; + snd_seq_client_info_alloca( &cinfo ); + snd_seq_port_info_alloca( &pinfo ); + + snd_seq_client_info_set_client( cinfo, -1 ); + while ( seq.getNextClient(cinfo ) >= 0 ) { + client = snd_seq_client_info_get_client( cinfo ); + // ignore default device (it is included in the following results again) + if ( client == 0 ) continue; + // Reset query info + snd_seq_port_info_set_client( pinfo, client ); + snd_seq_port_info_set_port( pinfo, -1 ); + while ( seq.getNextPort( pinfo ) >= 0 ) { + unsigned int atyp = snd_seq_port_info_get_type( pinfo ); + // otherwise we get ports without any + if ( !(capabilities & UNLIMITED) && + !( atyp & SND_SEQ_PORT_TYPE_MIDI_GENERIC ) ) continue; + unsigned int caps = snd_seq_port_info_get_capability( pinfo ); + if (capabilities & INPUT) { + /* we need both READ and SUBS_READ */ + if ((caps & (SND_SEQ_PORT_CAP_READ | SND_SEQ_PORT_CAP_SUBS_READ)) + != (SND_SEQ_PORT_CAP_READ | SND_SEQ_PORT_CAP_SUBS_READ)) + continue; + } + if (capabilities & OUTPUT) { + /* we need both WRITE and SUBS_WRITE */ + if ((caps & (SND_SEQ_PORT_CAP_WRITE|SND_SEQ_PORT_CAP_SUBS_WRITE)) + != (SND_SEQ_PORT_CAP_WRITE|SND_SEQ_PORT_CAP_SUBS_WRITE)) + continue; + } + list.push_back(new AlsaPortDescriptor(client,snd_seq_port_info_get_port(pinfo))); + } + } + return list; + } + + static void *alsaMidiHandler( void *ptr ); + + + /*! A structure to hold variables related to the ALSA API + implementation. + + \note After all sequencer handling is covered by the \ref + AlsaSequencer class, we should make seq to be a pointer in order + to allow a common client implementation. + */ + + struct AlsaMidiData:public AlsaPortDescriptor { + AlsaMidiData():seq() { + init(); + } + AlsaMidiData(const std::string &clientName):seq(clientName) { + init(); + } + ~AlsaMidiData() { + if (local.client) + deletePort(); + } + void init () { + local.port = 0; + local.client = 0; + port = -1; + subscription = 0; + coder = 0; + bufferSize = 32; + buffer = 0; + dummy_thread_id = pthread_self(); + thread = dummy_thread_id; + trigger_fds[0] = -1; + trigger_fds[1] = -1; + } + snd_seq_addr_t local; /*!< Our port and client id. If client = 0 (default) this means we didn't aquire a port so far. */ + NonLockingAlsaSequencer seq; + // unsigned int portNum; snd_seq_port_subscribe_t *subscription; snd_midi_event_t *coder; unsigned int bufferSize; @@ -1160,6 +1508,87 @@ namespace rtmidi { unsigned long long lastTime; int queue_id; // an input queue is needed to get timestamped events int trigger_fds[2]; + + void setRemote(const AlsaPortDescriptor * remote) { + port = remote->port; + client = remote->client; + } + void connectPorts(const snd_seq_addr_t &from, + const snd_seq_addr_t &to) { + subscription = seq.connectPorts(from, to); + } + + int openPort(int alsaCapabilities, + const std::string & portName) { + if (subscription) { + api->error( Error::DRIVER_ERROR, + "MidiInAlsa::openPort: ALSA error allocation port subscription." ); + return -99; + } + + snd_seq_port_info_t *pinfo; + snd_seq_port_info_alloca( &pinfo ); + + snd_seq_port_info_set_client( pinfo, 0 ); + snd_seq_port_info_set_port( pinfo, 0 ); + snd_seq_port_info_set_capability( pinfo, + alsaCapabilities); + snd_seq_port_info_set_type( pinfo, + SND_SEQ_PORT_TYPE_MIDI_GENERIC | + SND_SEQ_PORT_TYPE_APPLICATION ); + snd_seq_port_info_set_midi_channels(pinfo, 16); +#ifndef AVOID_TIMESTAMPING + snd_seq_port_info_set_timestamping(pinfo, 1); + snd_seq_port_info_set_timestamp_real(pinfo, 1); + snd_seq_port_info_set_timestamp_queue(pinfo, queue_id); +#endif + snd_seq_port_info_set_name(pinfo, portName.c_str() ); + int createok = seq.createPort(pinfo); + + if ( createok < 0 ) { + api->error( Error::DRIVER_ERROR, + "MidiInAlsa::openPort: ALSA error creating input port." ); + return createok; + } + + local.client = snd_seq_port_info_get_client( pinfo ); + local.port = snd_seq_port_info_get_port(pinfo); + return 0; + } + + void deletePort() { + seq.deletePort(local.port); + local.client = 0; + local.port = 0; + } + + void closePort() { + seq.closePort(subscription ); + snd_seq_port_subscribe_free( subscription ); + subscription = 0; + } + + bool startQueue(void * userdata) { + // Start the input queue +#ifndef AVOID_TIMESTAMPING + seq.startQueue(queue_id); +#endif + // Start our MIDI input thread. + pthread_attr_t attr; + pthread_attr_init(&attr); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); + pthread_attr_setschedpolicy(&attr, SCHED_OTHER); + + int err = pthread_create(&thread, &attr, alsaMidiHandler, userdata); + pthread_attr_destroy(&attr); + if ( err ) { + closePort(); + api->error( Error::THREAD_ERROR, + "MidiInAlsa::openPort: error starting MIDI input thread!" ); + return false; + } + return true; + } }; #define PORT_TYPE( pinfo, bits ) ((snd_seq_port_info_get_capability(pinfo) & (bits)) == (bits)) From a438342abe3661d1a2992ef8cab6c34c5c577040 Mon Sep 17 00:00:00 2001 From: Tobias Schlemmer Date: Sat, 5 Apr 2014 10:41:35 +0200 Subject: [PATCH 23/45] Provide the implementation part of the prvious patch. The ALSA output devices should be still considered broken. --- RtMidi.cpp | 66 ++++++++++++++++++++++++++---------------------------- 1 file changed, 32 insertions(+), 34 deletions(-) diff --git a/RtMidi.cpp b/RtMidi.cpp index 4e19c3b2..17c503eb 100644 --- a/RtMidi.cpp +++ b/RtMidi.cpp @@ -1813,7 +1813,7 @@ namespace rtmidi { // Cleanup. close ( data->trigger_fds[0] ); close ( data->trigger_fds[1] ); - if ( data->vport >= 0 ) snd_seq_delete_port( data->seq, data->vport ); + if ( data->local.client ) data->deletePort(); #ifndef AVOID_TIMESTAMPING snd_seq_free_queue( data->seq, data->queue_id ); #endif @@ -1823,6 +1823,8 @@ namespace rtmidi { void MidiInAlsa :: initialize( const std::string& clientName ) { +#if 0 + /* this will be done in the AlsaSequencer class */ // Set up the ALSA sequencer client. snd_seq_t *seq; int result = snd_seq_open(&seq, "default", SND_SEQ_OPEN_DUPLEX, SND_SEQ_NONBLOCK); @@ -1831,20 +1833,16 @@ namespace rtmidi { error( Error::DRIVER_ERROR, errorString_ ); return; } +#endif + // Save our api-specific connection information. + AlsaMidiData *data = new AlsaMidiData (clientName); // Set client name. - snd_seq_set_client_name( seq, clientName.c_str() ); - // Save our api-specific connection information. - AlsaMidiData *data = (AlsaMidiData *) new AlsaMidiData; - data->seq = seq; - data->portNum = -1; - data->vport = -1; - data->subscription = 0; - data->dummy_thread_id = pthread_self(); - data->thread = data->dummy_thread_id; - data->trigger_fds[0] = -1; - data->trigger_fds[1] = -1; + + + //data->seq = seq; + // data->portNum = -1; apiData_ = (void *) data; inputData_.apiData = (void *) data; @@ -1966,7 +1964,7 @@ namespace rtmidi { snd_seq_port_info_t *pinfo; snd_seq_port_info_alloca( &pinfo ); - if ( data->vport < 0 ) { + if ( !data->local.client ) { snd_seq_port_info_set_client( pinfo, 0 ); snd_seq_port_info_set_port( pinfo, 0 ); snd_seq_port_info_set_capability( pinfo, @@ -1989,11 +1987,11 @@ namespace rtmidi { error( Error::DRIVER_ERROR, errorString_ ); return; } - data->vport = snd_seq_port_info_get_port(pinfo); + data->local.port = snd_seq_port_info_get_port(pinfo); + data->local.client = snd_seq_port_info_get_client(pinfo); } - receiver.client = snd_seq_port_info_get_client( pinfo ); - receiver.port = data->vport; + receiver = data->local; if ( !data->subscription ) { // Make subscription @@ -2062,7 +2060,7 @@ namespace rtmidi { void MidiInAlsa :: openVirtualPort( std::string portName ) { AlsaMidiData *data = static_cast (apiData_); - if ( data->vport < 0 ) { + if ( !data->local.client ) { snd_seq_port_info_t *pinfo; snd_seq_port_info_alloca( &pinfo ); snd_seq_port_info_set_capability( pinfo, @@ -2085,7 +2083,8 @@ namespace rtmidi { error( Error::DRIVER_ERROR, errorString_ ); return; } - data->vport = snd_seq_port_info_get_port(pinfo); + data->local.port = snd_seq_port_info_get_port(pinfo); + data->local.client = snd_seq_port_info_get_client(pinfo); } if ( inputData_.doInput == false ) { @@ -2166,7 +2165,7 @@ namespace rtmidi { // Cleanup. AlsaMidiData *data = static_cast (apiData_); - if ( data->vport >= 0 ) snd_seq_delete_port( data->seq, data->vport ); + if ( data->local.port >= 0 ) snd_seq_delete_port( data->seq, data->local.port ); if ( data->coder ) snd_midi_event_free( data->coder ); if ( data->buffer ) free( data->buffer ); snd_seq_close( data->seq ); @@ -2175,6 +2174,7 @@ namespace rtmidi { void MidiOutAlsa :: initialize( const std::string& clientName ) { +#if 0 // Set up the ALSA sequencer client. snd_seq_t *seq; int result1 = snd_seq_open( &seq, "default", SND_SEQ_OPEN_OUTPUT, SND_SEQ_NONBLOCK ); @@ -2186,15 +2186,13 @@ namespace rtmidi { // Set client name. snd_seq_set_client_name( seq, clientName.c_str() ); +#endif // Save our api-specific connection information. - AlsaMidiData *data = (AlsaMidiData *) new AlsaMidiData; - data->seq = seq; - data->portNum = -1; - data->vport = -1; - data->bufferSize = 32; - data->coder = 0; - data->buffer = 0; + AlsaMidiData *data = new AlsaMidiData(clientName); + // data->seq = seq; + // data->portNum = -1; + int result = snd_midi_event_new( data->bufferSize, &data->coder ); if ( result < 0 ) { delete data; @@ -2281,18 +2279,18 @@ namespace rtmidi { receiver.port = snd_seq_port_info_get_port( pinfo ); sender.client = snd_seq_client_id( data->seq ); - if ( data->vport < 0 ) { - data->vport = snd_seq_create_simple_port( data->seq, portName.c_str(), + if ( data->local.port < 0 ) { + data->local.port = snd_seq_create_simple_port( data->seq, portName.c_str(), SND_SEQ_PORT_CAP_READ|SND_SEQ_PORT_CAP_SUBS_READ, SND_SEQ_PORT_TYPE_MIDI_GENERIC|SND_SEQ_PORT_TYPE_APPLICATION ); - if ( data->vport < 0 ) { + if ( data->local.port < 0 ) { errorString_ = "MidiOutAlsa::openPort: ALSA error creating output port."; error( Error::DRIVER_ERROR, errorString_ ); return; } } - sender.port = data->vport; + sender.port = data->local.port; // Make subscription if (snd_seq_port_subscribe_malloc( &data->subscription ) < 0) { @@ -2328,12 +2326,12 @@ namespace rtmidi { void MidiOutAlsa :: openVirtualPort( std::string portName ) { AlsaMidiData *data = static_cast (apiData_); - if ( data->vport < 0 ) { - data->vport = snd_seq_create_simple_port( data->seq, portName.c_str(), + if ( data->local.port < 0 ) { + data->local.port = snd_seq_create_simple_port( data->seq, portName.c_str(), SND_SEQ_PORT_CAP_READ|SND_SEQ_PORT_CAP_SUBS_READ, SND_SEQ_PORT_TYPE_MIDI_GENERIC|SND_SEQ_PORT_TYPE_APPLICATION ); - if ( data->vport < 0 ) { + if ( data->local.port < 0 ) { errorString_ = "MidiOutAlsa::openVirtualPort: ALSA error creating virtual port."; error( Error::DRIVER_ERROR, errorString_ ); } @@ -2364,7 +2362,7 @@ namespace rtmidi { snd_seq_event_t ev; snd_seq_ev_clear(&ev); - snd_seq_ev_set_source(&ev, data->vport); + snd_seq_ev_set_source(&ev, data->local.port); snd_seq_ev_set_subs(&ev); snd_seq_ev_set_direct(&ev); for ( unsigned int i=0; ibuffer[i] = message.at(i); From ab44c228d377e4c4a6c702808c58717535846e0f Mon Sep 17 00:00:00 2001 From: Tobias Schlemmer Date: Sat, 5 Apr 2014 10:45:12 +0200 Subject: [PATCH 24/45] Provide the header for the previous patches and pass some strings by reference. --- RtMidi.cpp | 10 +-- RtMidi.h | 178 +++++++++++++++++++++++++++++++++++++---------------- 2 files changed, 130 insertions(+), 58 deletions(-) diff --git a/RtMidi.cpp b/RtMidi.cpp index 17c503eb..6289da93 100644 --- a/RtMidi.cpp +++ b/RtMidi.cpp @@ -1854,7 +1854,7 @@ namespace rtmidi { // Create the input queue #ifndef AVOID_TIMESTAMPING - data->queue_id = snd_seq_alloc_named_queue(seq, "Midi Queue"); + data->queue_id = snd_seq_alloc_named_queue(data->seq, "Midi Queue"); // Set arbitrary tempo (mm=100) and resolution (240) snd_seq_queue_tempo_t *qtempo; snd_seq_queue_tempo_alloca(&qtempo); @@ -1932,7 +1932,7 @@ namespace rtmidi { return stringName; } - void MidiInAlsa :: openPort( unsigned int portNumber, const std::string portName ) + void MidiInAlsa :: openPort( unsigned int portNumber, const std::string & portName ) { if ( connected_ ) { errorString_ = "MidiInAlsa::openPort: a valid connection already exists!"; @@ -2041,7 +2041,7 @@ namespace rtmidi { } void MidiInAlsa :: openPort( const PortDescriptor & port, - const std::string portName = std::string( "RtMidi" ) ) + const std::string & portName) { abort(); } @@ -2248,7 +2248,7 @@ namespace rtmidi { return stringName; } - void MidiOutAlsa :: openPort( unsigned int portNumber, const std::string portName ) + void MidiOutAlsa :: openPort( unsigned int portNumber, const std::string & portName ) { if ( connected_ ) { errorString_ = "MidiOutAlsa::openPort: a valid connection already exists!"; @@ -2384,7 +2384,7 @@ namespace rtmidi { } void MidiOutAlsa :: openPort( const PortDescriptor & port, - const std::string portName) + const std::string & portName) { abort(); } diff --git a/RtMidi.h b/RtMidi.h index f40f2df7..c4553673 100644 --- a/RtMidi.h +++ b/RtMidi.h @@ -60,6 +60,7 @@ #include #include #include +#include namespace rtmidi { @@ -152,7 +153,7 @@ namespace rtmidi { template class Pointer { - public: + public: typedef T datatype; protected: struct countPointer { @@ -160,13 +161,15 @@ namespace rtmidi { datatype * descriptor; }; public: + Pointer():ptr(0) {} Pointer(datatype * p):ptr(new countPointer) { ptr->count = 1; ptr->descriptor = p; } Pointer(const Pointer & other): ptr(other.ptr) { - ptr->count++; + if (ptr) + ptr->count++; } ~Pointer() { @@ -187,12 +190,35 @@ namespace rtmidi { return ptr->descriptor; } + + datatype & operator * () { + if (!ptr || !ptr->descriptor) { + throw std::invalid_argument("rtmidi::Pointer: trying to dereference a NULL pointer."); + } + else return (*ptr->descriptor); + } + + bool operator ! () { + return (!ptr || !ptr->descriptor); + } + + Pointer & operator = (const Pointer & other) { + if (ptr) { + if (!(--ptr->count)) { + delete ptr->descriptor; + delete ptr; + } + } + ptr = other.ptr; + ptr->count++; + return *this; + } protected: countPointer * ptr; }; #else template - typedef shared_ptr Pointer; + typedef std::shared_ptr Pointer; #endif class MidiApi; @@ -221,6 +247,10 @@ namespace rtmidi { is more robust to small changes in the surrounding environment than \ref SESSION_PATH */ + NAMING_MASK = 0x0F, /*!< part of the flags + that is concerned with + naming. + */ UNIQUE_NAME = 0x10, /*!< Make all names uniqe. This is usually done by adding numbers to the end of the @@ -232,9 +262,12 @@ namespace rtmidi { //! Flags describing the capabilities of a given port. enum PortCapabilities { - INPUT = 1, /*!< Ports that can be read from. */ - OUTPUT = 2, /*!< Ports that can be written to. */ - INOUTPUT = 3 /*!< Ports that allow reading and writing (INPUT | OUTPUT) */ + INPUT = 1, /*!< Ports that can be read from. */ + OUTPUT = 2, /*!< Ports that can be written to. */ + INOUTPUT = 3, /*!< Ports that allow reading and writing (INPUT | OUTPUT) */ + UNLIMITED = 0x10 /*!< Some APIs can filter out certain ports which they consider + not to be useful. This flags supresses this behaviour and + selects all ports that are useable. */ }; //! Default constructor. @@ -247,7 +280,7 @@ namespace rtmidi { /*! As we might have to destruct the object from the application code * each port id must have a virtual destructor. */ - virtual ~PortDescriptor() = 0; + virtual ~PortDescriptor() {}; //! Get the MIDI api for the current port. /*! This is the only information RtMidi needs to know: Which @@ -269,7 +302,7 @@ namespace rtmidi { /*! \return a capabilities flag describing the capabilities of the port. * \sa PortCapabilities */ - virtual int getCapabilities(); + virtual int getCapabilities() = 0; }; //! A list of port descriptors. @@ -321,14 +354,29 @@ namespace rtmidi { that will be generated to connect to portId can be specified. */ - virtual void openPort( unsigned int portNumber = 0, const std::string portName = std::string( "RtMidi" ) ) = 0; + virtual void openPort( unsigned int portNumber = 0, const std::string & portName = std::string( "RtMidi" ) ) = 0; //! Pure virtual function to open a MIDI connection given by a port descriptor. /*! \param port A port descriptor of the port must be specified. \param portName An optional name for the applicaction port that is used to connect to portId can be specified. */ - virtual void openPort( const PortDescriptor & port, const std::string portName = std::string( "RtMidi" ) ) = 0; + virtual void openPort( const PortDescriptor & port, const std::string & portName = std::string( "RtMidi" ) ) = 0; + + //! Open a MIDI connection given by a port descriptor pointer. + /*! + \param port A pointer to a port descriptor of the port must be specified. + \param portName An optional name for the applicaction port that is used to connect to portId can be specified. + \sa openPort(const PortDescriptor &,const std::string &); + */ + void openPort( Pointer p, const std::string & portName = std::string( "RtMidi" ) ) { + if (!p) { + errorString_ = "MidiApi::openPort: passed NULL pointer"; + error( Error::INVALID_PARAMETER, errorString_ ); + return; + } + openPort(*p, portName); + } //! Pure virtual function to return a port descirptor if the port is open virtual Pointer getDescriptor() = 0; @@ -336,15 +384,16 @@ namespace rtmidi { //! Pure virtual function to return a list of all available ports of the current API. /*! \param capabilities an optional parameter that describes which - device types are returned. + capabilities the device typu \return This function returns a list of port descriptors. \note An input API may but need not necessarily report output devices which cannot be used as input if - \ref PortDescriptor::OUTPUT is passed as \ref capabilities parameter. + \ref 0 is passed as \ref capabilities parameter. + \sa PortDescriptor::PortCapabilitiers */ - virtual PortList getPortList(int capabilities = PortDescriptor:: INOUTPUT) = 0; + virtual PortList getPortList(int capabilities = 0) = 0; //! Pure virtual to return the number of available MIDI ports of the current API. /*! @@ -420,7 +469,7 @@ namespace rtmidi { RTMIDI_DEPRECATED(double getMessage( std::vector *message )) { if (!message) { - errorString_ = "MidiInApi::getMessage: passed NULL pointer"; + errorString_ = "MidiInApi::getMessage: passed NULL pointer"; error( Error::WARNING, errorString_ ); } return getMessage(*message); @@ -484,7 +533,7 @@ namespace rtmidi { RTMIDI_DEPRECATED(void sendMessage( std::vector *message )) { if (!message) { - errorString_ = "MidiOutApi::sendMessage: no data in message argument!"; + errorString_ = "MidiOutApi::sendMessage: no data in message argument!"; error( Error::WARNING, errorString_ ); } sendMessage(*message); @@ -550,7 +599,7 @@ namespace rtmidi { { if (rtapi_) rtapi_->openVirtualPort(portName); } - + //! Pure virtual function to open a MIDI connection given by enumeration number. /*! \param portNumber An optional port number greater than 0 can be specified. Otherwise, the default or first port @@ -572,11 +621,26 @@ namespace rtmidi { \param portName An optional name for the applicaction port that is used to connect to portId can be specified. */ void openPort( const PortDescriptor & port, - const std::string portName = std::string( "RtMidi" ) ) + const std::string & portName = std::string( "RtMidi" ) ) { if (rtapi_) rtapi_->openPort(port,portName); } + //! Open a MIDI connection given by a port descriptor pointer. + /*! + \param port A pointer to a port descriptor of the port must be specified. + \param portName An optional name for the applicaction port that is used to connect to portId can be specified. + \sa openPort(const PortDescriptor &,const std::string &); + */ + void openPort( Pointer p, + const std::string & portName = std::string( "RtMidi" ) ) { + if (!p) { + error( Error::INVALID_PARAMETER, "MidiApi::openPort: passed NULL pointer" ); + return; + } + openPort(*p, portName); + } + //! Pure virtual function to return a port descirptor if the port is open Pointer getDescriptor() { @@ -584,18 +648,27 @@ namespace rtmidi { return 0; } - //! Pure virtual function to return a list of all available ports of the current API. + //! Return a list of all available ports of the current API. /*! - \param capabilities an optional parameter that describes which - device types are returned. + \param capabilities an optional parameter that + describes which capabilities the returned devices + must support. The returned devices may have + additional capabilities to those which have been + requested, but not less. \return This function returns a list of port descriptors. - \note An input API may but need not necessarily report - output devices which cannot be used as input if - \ref PortDescriptor::OUTPUT is passed as \ref capabilities parameter. + \note Each API will request additonal + capabilites. An output API will set always add \ref + PortDescriptor::OUTPUT to the mask while an input + device will always add \ref PortDescriptor::OUTPUT. + + \note An input API may but need not necessarily + report output devices which cannot be used as input + if \ref PortDescriptor::OUTPUT is passed as \ref + capabilities parameter. */ - PortList getPortList(int capabilities = PortDescriptor:: INOUTPUT) + PortList getPortList(int capabilities = 0) { if (rtapi_) return rtapi_->getPortList(capabilities); return PortList(); @@ -640,7 +713,7 @@ namespace rtmidi { void closePort( void ) { if (rtapi_) rtapi_->closePort(); - } + } // ! A basic error reporting function for RtMidi classes. // static void error( Error::Type type, std::string &errorString ); @@ -742,7 +815,6 @@ namespace rtmidi { //! If a MIDI connection is still open, it will be closed by the destructor. ~MidiIn ( void ) throw(); - //! Set a callback function to be invoked for incoming MIDI messages. /*! The callback function will be called whenever an incoming MIDI @@ -817,12 +889,12 @@ namespace rtmidi { RTMIDI_DEPRECATED(double getMessage( std::vector *message )) { if (!message) { - error( Error::WARNING, + error( Error::WARNING, "MidiIn::getMessage: passed NULL pointer"); } if (rtapi_) return static_cast(rtapi_)->getMessage(*message); - error( Error::WARNING, + error( Error::WARNING, "MidiIn::getMessage: No valid API found."); return 0.0; } @@ -870,7 +942,7 @@ namespace rtmidi { /*! An exception is thrown if an error occurs during output or an output connection was not previously established. - + \deprecated */ RTMIDI_DEPRECATED(void sendMessage( std::vector *message )) @@ -918,9 +990,9 @@ namespace rtmidi { MidiInCore( const std::string clientName, unsigned int queueSizeLimit ); ~MidiInCore( void ); ApiType getCurrentApi( void ) { return MACOSX_CORE; }; - void openPort( unsigned int portNumber, const std::string portName ); + void openPort( unsigned int portNumber, const std::string & portName ); void openVirtualPort( const std::string portName ); - void openPort( const PortDescriptor & port, const std::string portName); + void openPort( const PortDescriptor & port, const std::string & portName); Pointer getDescriptor(); PortList getPortList(int capabilities); void closePort( void ); @@ -937,9 +1009,9 @@ namespace rtmidi { MidiOutCore( const std::string clientName ); ~MidiOutCore( void ); ApiType getCurrentApi( void ) { return MACOSX_CORE; }; - void openPort( unsigned int portNumber, const std::string portName ); + void openPort( unsigned int portNumber, const std::string & portName ); void openVirtualPort( const std::string portName ); - void openPort( const PortDescriptor & port, const std::string portName); + void openPort( const PortDescriptor & port, const std::string & portName); Pointer getDescriptor(); PortList getPortList(int capabilities); void closePort( void ); @@ -961,9 +1033,9 @@ namespace rtmidi { MidiInJack( const std::string clientName, unsigned int queueSizeLimit ); ~MidiInJack( void ); ApiType getCurrentApi( void ) { return UNIX_JACK; }; - void openPort( unsigned int portNumber, const std::string portName ); + void openPort( unsigned int portNumber, const std::string & portName ); void openVirtualPort( const std::string portName ); - void openPort( const PortDescriptor & port, const std::string portName); + void openPort( const PortDescriptor & port, const std::string & portName); Pointer getDescriptor(); PortList getPortList(int capabilities); void closePort( void ); @@ -983,9 +1055,9 @@ namespace rtmidi { MidiOutJack( const std::string clientName ); ~MidiOutJack( void ); ApiType getCurrentApi( void ) { return UNIX_JACK; }; - void openPort( unsigned int portNumber, const std::string portName ); + void openPort( unsigned int portNumber, const std::string & portName ); void openVirtualPort( const std::string portName ); - void openPort( const PortDescriptor & port, const std::string portName); + void openPort( const PortDescriptor & port, const std::string & portName); Pointer getDescriptor(); PortList getPortList(int capabilities); void closePort( void ); @@ -1010,9 +1082,9 @@ namespace rtmidi { MidiInAlsa( const std::string clientName, unsigned int queueSizeLimit ); ~MidiInAlsa( void ); ApiType getCurrentApi( void ) throw() { return LINUX_ALSA; }; - void openPort( unsigned int portNumber, const std::string portName ); + void openPort( unsigned int portNumber, const std::string & portName ); void openVirtualPort( const std::string portName ); - void openPort( const PortDescriptor & port, const std::string portName); + void openPort( const PortDescriptor & port, const std::string & portName); Pointer getDescriptor(); PortList getPortList(int capabilities); void closePort( void ); @@ -1029,9 +1101,9 @@ namespace rtmidi { MidiOutAlsa( const std::string clientName ); ~MidiOutAlsa( void ); ApiType getCurrentApi( void ) throw() { return LINUX_ALSA; }; - void openPort( unsigned int portNumber, const std::string portName ); + void openPort( unsigned int portNumber, const std::string & portName ); void openVirtualPort( const std::string portName ); - void openPort( const PortDescriptor & port, const std::string portName); + void openPort( const PortDescriptor & port, const std::string & portName); Pointer getDescriptor(); PortList getPortList(int capabilities); void closePort( void ); @@ -1053,9 +1125,9 @@ namespace rtmidi { MidiInWinMM( const std::string clientName, unsigned int queueSizeLimit ); ~MidiInWinMM( void ); ApiType getCurrentApi( void ) { return WINDOWS_MM; }; - void openPort( unsigned int portNumber, const std::string portName ); + void openPort( unsigned int portNumber, const std::string & portName ); void openVirtualPort( const std::string portName ); - void openPort( const PortDescriptor & port, const std::string portName); + void openPort( const PortDescriptor & port, const std::string & portName); Pointer getDescriptor(); PortList getPortList(int capabilities); void closePort( void ); @@ -1072,9 +1144,9 @@ namespace rtmidi { MidiOutWinMM( const std::string clientName ); ~MidiOutWinMM( void ); ApiType getCurrentApi( void ) { return WINDOWS_MM; }; - void openPort( unsigned int portNumber, const std::string portName ); + void openPort( unsigned int portNumber, const std::string & portName ); void openVirtualPort( const std::string portName ); - void openPort( const PortDescriptor & port, const std::string portName); + void openPort( const PortDescriptor & port, const std::string & portName); Pointer getDescriptor(); PortList getPortList(int capabilities); void closePort( void ); @@ -1096,9 +1168,9 @@ namespace rtmidi { MidiInWinKS( const std::string clientName, unsigned int queueSizeLimit ); ~MidiInWinKS( void ); ApiType getCurrentApi( void ) { return WINDOWS_KS; }; - void openPort( unsigned int portNumber, const std::string portName ); + void openPort( unsigned int portNumber, const std::string & portName ); void openVirtualPort( const std::string portName ); - void openPort( const PortDescriptor & port, const std::string portName); + void openPort( const PortDescriptor & port, const std::string & portName); Pointer getDescriptor(); PortList getPortList(int capabilities); void closePort( void ); @@ -1115,9 +1187,9 @@ namespace rtmidi { MidiOutWinKS( const std::string clientName ); ~MidiOutWinKS( void ); ApiType getCurrentApi( void ) { return WINDOWS_KS; }; - void openPort( unsigned int portNumber, const std::string portName ); + void openPort( unsigned int portNumber, const std::string & portName ); void openVirtualPort( const std::string portName ); - void openPort( const PortDescriptor & port, const std::string portName); + void openPort( const PortDescriptor & port, const std::string & portName); Pointer getDescriptor(); PortList getPortList(int capabilities); void closePort( void ); @@ -1142,9 +1214,9 @@ namespace rtmidi { error( Error::WARNING, errorString_ ); } ApiType getCurrentApi( void ) { return RTMIDI_DUMMY; } - void openPort( unsigned int /*portNumber*/, const std::string /*portName*/ ) {} + void openPort( unsigned int /*portNumber*/, const & std::string /*portName*/ ) {} void openVirtualPort( const std::string /*portName*/ ) {} - void openPort( const PortDescriptor & port, const std::string portName) {} + void openPort( const PortDescriptor & port, const & std::string portName) {} Pointer getDescriptor() { return 0; } PortList getPortList(int capabilities) { return PortList(); } void closePort( void ) {} @@ -1163,9 +1235,9 @@ namespace rtmidi { error( Error::WARNING, errorString_ ); } ApiType getCurrentApi( void ) { return RTMIDI_DUMMY; } - void openPort( unsigned int /*portNumber*/, const std::string /*portName*/ ) {} + void openPort( unsigned int /*portNumber*/, const & std::string /*portName*/ ) {} void openVirtualPort( const std::string /*portName*/ ) {} - void openPort( const PortDescriptor & port, const std::string portName) {} + void openPort( const PortDescriptor & port, const & std::string portName) {} Pointer getDescriptor() { return 0; } PortList getPortList(int capabilities) { return PortList(); } void closePort( void ) {} From db2a4ed52699f4fd5bbb795bba17f34295711f9f Mon Sep 17 00:00:00 2001 From: Tobias Schlemmer Date: Sat, 5 Apr 2014 10:46:15 +0200 Subject: [PATCH 25/45] Some whitespace fixes --- RtMidi.cpp | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/RtMidi.cpp b/RtMidi.cpp index 6289da93..a7e6d126 100644 --- a/RtMidi.cpp +++ b/RtMidi.cpp @@ -647,7 +647,7 @@ namespace rtmidi { MIDIPortRef port; CoreMidiData *data = static_cast (apiData_); - OSStatus result = MIDIInputPortCreate( data->client, + OSStatus result = MIDIInputPortCreate( data->client, CFStringCreateWithCString( NULL, portName.c_str(), kCFStringEncodingASCII ), midiInputCallback, (void *)&inputData_, &port ); if ( result != noErr ) { @@ -837,7 +837,7 @@ namespace rtmidi { if ( anyStrings ) return result; - // Here, either the endpoint had no connections, or we failed to obtain names + // Here, either the endpoint had no connections, or we failed to obtain names return EndpointName( endpoint, false ); } @@ -931,7 +931,7 @@ namespace rtmidi { nameRef = ConnectedEndpointName(portRef); CFStringGetCString( nameRef, name, sizeof(name), CFStringGetSystemEncoding()); CFRelease( nameRef ); - + return stringName = name; } @@ -961,7 +961,7 @@ namespace rtmidi { MIDIPortRef port; CoreMidiData *data = static_cast (apiData_); - OSStatus result = MIDIOutputPortCreate( data->client, + OSStatus result = MIDIOutputPortCreate( data->client, CFStringCreateWithCString( NULL, portName.c_str(), kCFStringEncodingASCII ), &port ); if ( result != noErr ) { @@ -1034,7 +1034,7 @@ namespace rtmidi { // messages. Otherwise, we use a single CoreMidi MIDIPacket. unsigned int nBytes = message->size(); if ( nBytes == 0 ) { - errorString_ = "MidiOutCore::sendMessage: no data in message argument!"; + errorString_ = "MidiOutCore::sendMessage: no data in message argument!"; error( Error::WARNING, errorString_ ); return; } @@ -1092,7 +1092,7 @@ namespace rtmidi { MIDIPacket *packet = MIDIPacketListInit( &packetList ); packet = MIDIPacketListAdd( &packetList, sizeof(packetList), packet, timeStamp, nBytes, (const Byte *) &message->at( 0 ) ); if ( !packet ) { - errorString_ = "MidiOutCore::sendMessage: could not allocate packet list"; + errorString_ = "MidiOutCore::sendMessage: could not allocate packet list"; error( Error::DRIVER_ERROR, errorString_ ); return; } @@ -1976,12 +1976,12 @@ namespace rtmidi { snd_seq_port_info_set_midi_channels(pinfo, 16); #ifndef AVOID_TIMESTAMPING snd_seq_port_info_set_timestamping(pinfo, 1); - snd_seq_port_info_set_timestamp_real(pinfo, 1); + snd_seq_port_info_set_timestamp_real(pinfo, 1); snd_seq_port_info_set_timestamp_queue(pinfo, data->queue_id); #endif snd_seq_port_info_set_name(pinfo, portName.c_str() ); int createok = snd_seq_create_port(data->seq, pinfo); - + if ( createok < 0 ) { errorString_ = "MidiInAlsa::openPort: ALSA error creating input port."; error( Error::DRIVER_ERROR, errorString_ ); @@ -2072,7 +2072,7 @@ namespace rtmidi { snd_seq_port_info_set_midi_channels(pinfo, 16); #ifndef AVOID_TIMESTAMPING snd_seq_port_info_set_timestamping(pinfo, 1); - snd_seq_port_info_set_timestamp_real(pinfo, 1); + snd_seq_port_info_set_timestamp_real(pinfo, 1); snd_seq_port_info_set_timestamp_queue(pinfo, data->queue_id); #endif snd_seq_port_info_set_name(pinfo, portName.c_str()); @@ -2439,7 +2439,7 @@ namespace rtmidi{ //*********************************************************************// static void CALLBACK midiInputCallback( HMIDIIN /*hmin*/, - UINT inputStatus, + UINT inputStatus, DWORD_PTR instancePtr, DWORD_PTR midiMessage, DWORD timestamp ) @@ -2489,8 +2489,8 @@ namespace rtmidi{ for ( int i=0; imessage.bytes.push_back( *ptr++ ); } else { // Sysex message ( MIM_LONGDATA or MIM_LONGERROR ) - MIDIHDR *sysex = ( MIDIHDR *) midiMessage; - if ( !( data->ignoreFlags & 0x01 ) && inputStatus != MIM_LONGERROR ) { + MIDIHDR *sysex = ( MIDIHDR *) midiMessage; + if ( !( data->ignoreFlags & 0x01 ) && inputStatus != MIM_LONGERROR ) { // Sysex message and we're not ignoring it for ( int i=0; i<(int)sysex->dwBytesRecorded; ++i ) apiData->message.bytes.push_back( sysex->lpData[i] ); @@ -2709,7 +2709,7 @@ namespace rtmidi{ stringName = std::string( deviceCaps.szPname ); #endif - // Next lines added to add the portNumber to the name so that + // Next lines added to add the portNumber to the name so that // the device's names are sure to be listed with individual names // even when they have the same brand name std::ostringstream os; @@ -2872,7 +2872,7 @@ namespace rtmidi{ sysex.lpData = (LPSTR) buffer; sysex.dwBufferLength = nBytes; sysex.dwFlags = 0; - result = midiOutPrepareHeader( data->outHandle, &sysex, sizeof(MIDIHDR) ); + result = midiOutPrepareHeader( data->outHandle, &sysex, sizeof(MIDIHDR) ); if ( result != MMSYSERR_NOERROR ) { free( buffer ); errorString_ = "MidiOutWinMM::sendMessage: error preparing sysex header."; From d1dc0fbc9c22c1cc1178a6a422349feed2a7e22f Mon Sep 17 00:00:00 2001 From: Tobias Schlemmer Date: Sat, 5 Apr 2014 10:47:54 +0200 Subject: [PATCH 26/45] Implement some functions. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit MidiInAlsa::openPort MidiInAlsa::getPortList MidiOutAlsa::getPortList Now, we can do some first tests. Test files follow… --- RtMidi.cpp | 41 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 38 insertions(+), 3 deletions(-) diff --git a/RtMidi.cpp b/RtMidi.cpp index a7e6d126..24e237bd 100644 --- a/RtMidi.cpp +++ b/RtMidi.cpp @@ -2043,7 +2043,42 @@ namespace rtmidi { void MidiInAlsa :: openPort( const PortDescriptor & port, const std::string & portName) { - abort(); + AlsaMidiData *data = static_cast (apiData_); + const AlsaPortDescriptor * remote = dynamic_cast(&port); + + if ( !data ) { + errorString_ = "MidiInAlsa::openPort: Internal error: data has not been allocated!"; + error( Error::DRIVER_ERROR, errorString_ ); + return; + } + if ( connected_ ) { + errorString_ = "MidiInAlsa::openPort: a valid connection already exists!"; + error( Error::WARNING, errorString_ ); + return; + } + if (data->subscription) { + error( Error::DRIVER_ERROR, + "MidiInAlsa::openPort: ALSA error allocation port subscription." ); + return; + } + if (!remote) { + errorString_ = "MidiInAlsa::openPort: an invalid (i.e. non-ALSA) port descriptor has been passed to openPort!"; + error( Error::WARNING, errorString_ ); + return; + } + + if (!data->local.client) + data->openPort (SND_SEQ_PORT_CAP_WRITE | SND_SEQ_PORT_CAP_SUBS_WRITE, + portName); + data->setRemote(remote); + data->connectPorts(*remote,data->local); + + + if ( inputData_.doInput == false ) { + inputData_.doInput = data->startQueue(&inputData_); + } + + connected_ = true; } Pointer MidiInAlsa :: getDescriptor() @@ -2052,7 +2087,7 @@ namespace rtmidi { } PortList MidiInAlsa :: getPortList(int capabilities) { - abort(); + return AlsaPortDescriptor::getPortList(capabilities | PortDescriptor::INPUT); } @@ -2394,7 +2429,7 @@ namespace rtmidi { } PortList MidiOutAlsa :: getPortList(int capabilities) { - abort(); + return AlsaPortDescriptor::getPortList(capabilities | PortDescriptor::OUTPUT); } } #endif // __LINUX_ALSA__ From 8d946149387dbba9cb2b1e25d0108baab45e0b0d Mon Sep 17 00:00:00 2001 From: Tobias Schlemmer Date: Sat, 5 Apr 2014 10:50:31 +0200 Subject: [PATCH 27/45] Add first tests for the new port selection API. --- tests/Makefile.in | 8 ++- tests/cmidiin2.cpp | 113 ++++++++++++++++++++++++++++++++++++ tests/midiprobe2.cpp | 134 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 254 insertions(+), 1 deletion(-) create mode 100644 tests/cmidiin2.cpp create mode 100644 tests/midiprobe2.cpp diff --git a/tests/Makefile.in b/tests/Makefile.in index 1826737e..6fe470bd 100644 --- a/tests/Makefile.in +++ b/tests/Makefile.in @@ -1,7 +1,7 @@ ### Do not edit -- Generated by 'configure --with-whatever' from Makefile.in ### RtMidi tests Makefile - for various flavors of unix -PROGRAMS = midiprobe midiout qmidiin cmidiin sysextest +PROGRAMS = midiprobe midiout qmidiin cmidiin sysextest midiprobe2 cmidiin2 RM = /bin/rm SRC_PATH = .. INCLUDE = .. @@ -24,6 +24,9 @@ all : $(PROGRAMS) midiprobe : midiprobe.cpp $(OBJECTS) $(CC) $(CFLAGS) $(DEFS) -o midiprobe midiprobe.cpp $(OBJECT_PATH)/RtMidi.o $(LIBRARY) +midiprobe2 : midiprobe2.cpp $(OBJECTS) + $(CC) $(CFLAGS) $(DEFS) -o midiprobe2 midiprobe2.cpp $(OBJECT_PATH)/RtMidi.o $(LIBRARY) + midiout : midiout.cpp $(OBJECTS) $(CC) $(CFLAGS) $(DEFS) -o midiout midiout.cpp $(OBJECT_PATH)/RtMidi.o $(LIBRARY) @@ -33,6 +36,9 @@ qmidiin : qmidiin.cpp $(OBJECTS) cmidiin : cmidiin.cpp $(OBJECTS) $(CC) $(CFLAGS) $(DEFS) -o cmidiin cmidiin.cpp $(OBJECT_PATH)/RtMidi.o $(LIBRARY) +cmidiin2 : cmidiin2.cpp $(OBJECTS) + $(CC) $(CFLAGS) $(DEFS) -o cmidiin2 cmidiin2.cpp $(OBJECT_PATH)/RtMidi.o $(LIBRARY) + sysextest : sysextest.cpp $(OBJECTS) $(CC) $(CFLAGS) $(DEFS) -o sysextest sysextest.cpp $(OBJECT_PATH)/RtMidi.o $(LIBRARY) diff --git a/tests/cmidiin2.cpp b/tests/cmidiin2.cpp new file mode 100644 index 00000000..0d16eea9 --- /dev/null +++ b/tests/cmidiin2.cpp @@ -0,0 +1,113 @@ +//*****************************************// +// cmidiin.cpp +// by Gary Scavone, 2003-2004. +// +// Simple program to test MIDI input and +// use of a user callback function. +// +//*****************************************// + +#include +#include +#include "RtMidi.h" + +void usage( void ) { + // Error function in case of incorrect command-line + // argument specifications. + std::cout << "\nuseage: cmidiin2 \n"; + std::cout << " where port = the device to use (default = 0).\n\n"; + exit( 0 ); +} + +void mycallback( double deltatime, std::vector< unsigned char > *message, void * /* userData */ ) +{ + unsigned int nBytes = message->size(); + for ( unsigned int i=0; i 0 ) + std::cout << "stamp = " << deltatime << std::endl; +} + +// This function should be embedded in a try/catch block in case of +// an exception. It offers the user a choice of MIDI ports to open. +// It returns false if there are no ports available. +bool chooseMidiPort( RtMidiIn &rtmidi ); + +int main( int argc, char */*argv*/[] ) +{ + + // Minimal command-line check. + if ( argc > 2 ) usage(); + + try { + + // RtMidiIn constructor + RtMidiIn midiin; + + // Call function to select port. + if ( chooseMidiPort( midiin ) == false ) return 0; + + // Set our callback function. This should be done immediately after + // opening the port to avoid having incoming messages written to the + // queue instead of sent to the callback function. + midiin.setCallback( &mycallback ); + + // Don't ignore sysex, timing, or active sensing messages. + midiin.ignoreTypes( false, false, false ); + + std::cout << "\nReading MIDI input ... press to quit.\n"; + char input; + std::cin.get(input); + + } catch ( RtMidiError &error ) { + error.printMessage(); + } +} + +bool chooseMidiPort( RtMidiIn &midi ) +{ + std::cout << "\nWould you like to open a virtual input port? [y/N] "; + + std::string keyHit; + std::getline( std::cin, keyHit ); + if ( keyHit == "y" ) { + midi.openVirtualPort(); + return true; + } + + std::string portName; + rtmidi::PortList list = midi.getPortList(rtmidi::PortDescriptor::INPUT); + if ( list.empty() ) { + std::cout << "No input ports available!" << std::endl; + return false; + } + + rtmidi::Pointer selected = list.front(); + if ( list.size() == 1 ) { + std::cout << "\nOpening " << selected->getName() << std::endl; + } else { + int nr; + std::vector > pointers(list.size()); + // copy the data into a structure that is used by the user interface. + std::copy(list.begin(),list.end(),pointers.begin()); + for (nr = 0 ; nr < (int)pointers.size(); nr++) { + portName = pointers[nr]->getName(rtmidi::PortDescriptor::LONG_NAME + | rtmidi::PortDescriptor::UNIQUE_NAME + | rtmidi::PortDescriptor::INCLUDE_API); + std::cout << " Input port #" << nr << ": " << portName << '\n'; + } + + do { + std::cout << "\nChoose a port number: "; + std::cin >> nr; + } while ( nr >= (int)pointers.size() ); + std::getline( std::cin, keyHit ); // used to clear out stdin + selected = pointers[nr]; + } + + /* The midi setup might have changed meanwhile. + Our portlist is under our control. So we enumerate this list. */ + // midi.openPort( i ); + midi.openPort(selected); + return true; +} diff --git a/tests/midiprobe2.cpp b/tests/midiprobe2.cpp new file mode 100644 index 00000000..9c599c9e --- /dev/null +++ b/tests/midiprobe2.cpp @@ -0,0 +1,134 @@ +// midiprobe.cpp +// +// Simple program to check MIDI inputs and outputs. +// +// by Gary Scavone, 2003-2012. + +#include +#include +#include +#include "RtMidi.h" + +int main() +{ + // Create an api map. + std::map apiMap; + apiMap[RtMidi::MACOSX_CORE] = "OS-X CoreMidi"; + apiMap[RtMidi::WINDOWS_MM] = "Windows MultiMedia"; + apiMap[RtMidi::WINDOWS_KS] = "Windows Kernel Straming"; + apiMap[RtMidi::UNIX_JACK] = "Jack Client"; + apiMap[RtMidi::LINUX_ALSA] = "Linux ALSA"; + apiMap[RtMidi::RTMIDI_DUMMY] = "RtMidi Dummy"; + + std::vector< RtMidi::Api > apis; + RtMidi :: getCompiledApi( apis ); + + std::cout << "\nCompiled APIs:\n"; + for ( unsigned int i=0; igetName() << std::endl; + for (int j = 0 ; j < 4 ; j++ ) { + std::cout << j << ":f:f: " << (*i)->getName (j) << std::endl; + std::cout << j << ":t:f: " << (*i)->getName (j | rtmidi::PortDescriptor::UNIQUE_NAME) << std::endl; + std::cout << j << ":f:t: " << (*i)->getName (j | rtmidi::PortDescriptor::INCLUDE_API) << std::endl; + std::cout << j << ":t:t: " << (*i)->getName (j | rtmidi::PortDescriptor::UNIQUE_NAME + | rtmidi::PortDescriptor::INCLUDE_API) << std::endl; + std::cout << std::endl; + } + std::cout << std::endl; + } + + std::cout << "**********************************************************************" << std::endl; + + // RtMidiOut constructor ... exception possible + RtMidiOut midiout; + + std::cout << "\nCurrent output API: " << apiMap[ midiout.getCurrentApi() ] << std::endl; + + list = midiout.getPortList(); + + // Check inputs. + std::cout << "\nThere are " << list.size() << " MIDI output sinks available.\n"; + + for (rtmidi::PortList::iterator i = list.begin(); + i != list.end(); + i++) { + std::cout << " Output Port: " << (*i)->getName() << std::endl; + for (int j = 0 ; j < 4 ; j++ ) { + std::cout << j << ":f:f: " << (*i)->getName (j) << std::endl; + std::cout << j << ":t:f: " << (*i)->getName (j | rtmidi::PortDescriptor::UNIQUE_NAME) << std::endl; + std::cout << j << ":f:t: " << (*i)->getName (j | rtmidi::PortDescriptor::INCLUDE_API) << std::endl; + std::cout << j << ":t:t: " << (*i)->getName (j | rtmidi::PortDescriptor::UNIQUE_NAME + | rtmidi::PortDescriptor::INCLUDE_API) << std::endl; + std::cout << std::endl; + } + std::cout << std::endl; + } + + std::cout << "**********************************************************************" << std::endl; + std::cout << "* entering unlimited mode *" << std::endl; + std::cout << "**********************************************************************" << std::endl; + + list = midiin.getPortList(rtmidi::PortDescriptor::UNLIMITED); + // Check inputs. + std::cout << "\nThere are " << list.size() << " MIDI input sources available in unlimited mode.\n"; + for (rtmidi::PortList::iterator i = list.begin(); + i != list.end(); + i++) { + std::cout << " Input Port: " << (*i)->getName() << std::endl; + for (int j = 0 ; j < 4 ; j++ ) { + std::cout << j << ":f:f: " << (*i)->getName (j) << std::endl; + std::cout << j << ":t:f: " << (*i)->getName (j | rtmidi::PortDescriptor::UNIQUE_NAME) << std::endl; + std::cout << j << ":f:t: " << (*i)->getName (j | rtmidi::PortDescriptor::INCLUDE_API) << std::endl; + std::cout << j << ":t:t: " << (*i)->getName (j | rtmidi::PortDescriptor::UNIQUE_NAME + | rtmidi::PortDescriptor::INCLUDE_API) << std::endl; + std::cout << std::endl; + } + std::cout << std::endl; + } + + std::cout << "**********************************************************************" << std::endl; + list = midiout.getPortList(rtmidi::PortDescriptor::UNLIMITED); + + // Check inputs. + std::cout << "\nThere are " << list.size() << " MIDI output sinks available in unlimited mode.\n"; + + for (rtmidi::PortList::iterator i = list.begin(); + i != list.end(); + i++) { + std::cout << " Output Port: " << (*i)->getName() << std::endl; + for (int j = 0 ; j < 4 ; j++ ) { + std::cout << j << ":f:f: " << (*i)->getName (j) << std::endl; + std::cout << j << ":t:f: " << (*i)->getName (j | rtmidi::PortDescriptor::UNIQUE_NAME) << std::endl; + std::cout << j << ":f:t: " << (*i)->getName (j | rtmidi::PortDescriptor::INCLUDE_API) << std::endl; + std::cout << j << ":t:t: " << (*i)->getName (j | rtmidi::PortDescriptor::UNIQUE_NAME + | rtmidi::PortDescriptor::INCLUDE_API) << std::endl; + std::cout << std::endl; + } + std::cout << std::endl; + } + + + + } catch ( RtMidiError &error ) { + error.printMessage(); + } + + return 0; +} From c788aeb67f5372f3a0960ac90fc36496cc6a3a34 Mon Sep 17 00:00:00 2001 From: Tobias Schlemmer Date: Sun, 6 Apr 2014 10:50:22 +0200 Subject: [PATCH 28/45] Implement opening ALSA output ports. --- RtMidi.cpp | 46 +++++++++++-- tests/Makefile.in | 8 ++- tests/midiout2.cpp | 159 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 207 insertions(+), 6 deletions(-) create mode 100644 tests/midiout2.cpp diff --git a/RtMidi.cpp b/RtMidi.cpp index 24e237bd..ec15251c 100644 --- a/RtMidi.cpp +++ b/RtMidi.cpp @@ -1293,7 +1293,8 @@ namespace rtmidi { } snd_seq_port_subscribe_t * connectPorts(const snd_seq_addr_t & from, - const snd_seq_addr_t & to) { + const snd_seq_addr_t & to, + bool real_time) { init(); snd_seq_port_subscribe_t *subscription; @@ -1304,6 +1305,10 @@ namespace rtmidi { } snd_seq_port_subscribe_set_sender(subscription, &from); snd_seq_port_subscribe_set_dest(subscription, &to); + if (real_time) { + snd_seq_port_subscribe_set_time_update(subscription, 1); + snd_seq_port_subscribe_set_time_real(subscription, 1); + } { scoped_lock lock (mutex); if ( snd_seq_subscribe_port(seq, subscription) ) { @@ -1313,8 +1318,8 @@ namespace rtmidi { Error::DRIVER_ERROR); return 0; } - return subscription; } + return subscription; } void closePort(snd_seq_port_subscribe_t * subscription ) { @@ -1514,8 +1519,9 @@ namespace rtmidi { client = remote->client; } void connectPorts(const snd_seq_addr_t &from, - const snd_seq_addr_t &to) { - subscription = seq.connectPorts(from, to); + const snd_seq_addr_t &to, + bool real_time) { + subscription = seq.connectPorts(from, to, real_time); } int openPort(int alsaCapabilities, @@ -2421,7 +2427,37 @@ namespace rtmidi { void MidiOutAlsa :: openPort( const PortDescriptor & port, const std::string & portName) { - abort(); + AlsaMidiData *data = static_cast (apiData_); + const AlsaPortDescriptor * remote = dynamic_cast(&port); + + if ( !data ) { + errorString_ = "MidiOutAlsa::openPort: Internal error: data has not been allocated!"; + error( Error::DRIVER_ERROR, errorString_ ); + return; + } + if ( connected_ ) { + errorString_ = "MidiOutAlsa::openPort: a valid connection already exists!"; + error( Error::WARNING, errorString_ ); + return; + } + if (data->subscription) { + error( Error::DRIVER_ERROR, + "MidiOutAlsa::openPort: ALSA error allocation port subscription." ); + return; + } + if (!remote) { + errorString_ = "MidiOutAlsa::openPort: an invalid (i.e. non-ALSA) port descriptor has been passed to openPort!"; + error( Error::WARNING, errorString_ ); + return; + } + + if (!data->local.client) + data->openPort (SND_SEQ_PORT_CAP_READ | SND_SEQ_PORT_CAP_SUBS_READ, + portName); + data->setRemote(remote); + data->connectPorts(data->local,*remote,true); + + connected_ = true; } Pointer MidiOutAlsa :: getDescriptor() { diff --git a/tests/Makefile.in b/tests/Makefile.in index 6fe470bd..bea71da1 100644 --- a/tests/Makefile.in +++ b/tests/Makefile.in @@ -1,7 +1,7 @@ ### Do not edit -- Generated by 'configure --with-whatever' from Makefile.in ### RtMidi tests Makefile - for various flavors of unix -PROGRAMS = midiprobe midiout qmidiin cmidiin sysextest midiprobe2 cmidiin2 +PROGRAMS = midiprobe midiout qmidiin cmidiin sysextest midiprobe2 cmidiin2 qmidiin2 midiout2 RM = /bin/rm SRC_PATH = .. INCLUDE = .. @@ -30,9 +30,15 @@ midiprobe2 : midiprobe2.cpp $(OBJECTS) midiout : midiout.cpp $(OBJECTS) $(CC) $(CFLAGS) $(DEFS) -o midiout midiout.cpp $(OBJECT_PATH)/RtMidi.o $(LIBRARY) +midiout2 : midiout2.cpp $(OBJECTS) + $(CC) $(CFLAGS) $(DEFS) -o midiout2 midiout2.cpp $(OBJECT_PATH)/RtMidi.o $(LIBRARY) + qmidiin : qmidiin.cpp $(OBJECTS) $(CC) $(CFLAGS) $(DEFS) -o qmidiin qmidiin.cpp $(OBJECT_PATH)/RtMidi.o $(LIBRARY) +qmidiin2 : qmidiin2.cpp $(OBJECTS) + $(CC) $(CFLAGS) $(DEFS) -o qmidiin2 qmidiin2.cpp $(OBJECT_PATH)/RtMidi.o $(LIBRARY) + cmidiin : cmidiin.cpp $(OBJECTS) $(CC) $(CFLAGS) $(DEFS) -o cmidiin cmidiin.cpp $(OBJECT_PATH)/RtMidi.o $(LIBRARY) diff --git a/tests/midiout2.cpp b/tests/midiout2.cpp new file mode 100644 index 00000000..5d09b97d --- /dev/null +++ b/tests/midiout2.cpp @@ -0,0 +1,159 @@ +//*****************************************// +// midiout.cpp +// by Gary Scavone, 2003-2004. +// +// Simple program to test MIDI output. +// +//*****************************************// + +#include +#include +#include "RtMidi.h" + +// Platform-dependent sleep routines. +#if defined(__WINDOWS_MM__) +#include +#define SLEEP( milliseconds ) Sleep( (DWORD) milliseconds ) +#else // Unix variants +#include +#define SLEEP( milliseconds ) usleep( (unsigned long) (milliseconds * 1000.0) ) +#endif + +// This function should be embedded in a try/catch block in case of +// an exception. It offers the user a choice of MIDI ports to open. +// It returns false if there are no ports available. +bool chooseMidiPort( RtMidiOut &ortmidi ); + +int main( int /* argc*/, char */*argv*/[] ) +{ + std::vector message; + + // RtMidiOut constructor + try { + RtMidiOut midiout; + + // Call function to select port. + try { + if ( chooseMidiPort( midiout ) == false ) return 1; + } + catch ( RtMidiError &error ) { + error.printMessage(); + return 2; + } + + + SLEEP( 5000 ); + + // Send out a series of MIDI messages. + + // Program change: 192, 5 + message.push_back( 192 ); + message.push_back( 5 ); + midiout.sendMessage( &message ); + + SLEEP( 500 ); + + message[0] = 0xF1; + message[1] = 60; + midiout.sendMessage( &message ); + + // Control Change: 176, 7, 100 (volume) + message[0] = 176; + message[1] = 7; + message.push_back( 100 ); + midiout.sendMessage( &message ); + + // Note On: 144, 64, 90 + message[0] = 144; + message[1] = 64; + message[2] = 90; + midiout.sendMessage( &message ); + + SLEEP( 500 ); + + // Note Off: 128, 64, 40 + message[0] = 128; + message[1] = 64; + message[2] = 40; + midiout.sendMessage( &message ); + + SLEEP( 500 ); + + // Control Change: 176, 7, 40 + message[0] = 176; + message[1] = 7; + message[2] = 40; + midiout.sendMessage( &message ); + + SLEEP( 500 ); + + // Sysex: 240, 67, 4, 3, 2, 247 + message[0] = 240; + message[1] = 67; + message[2] = 4; + message.push_back( 3 ); + message.push_back( 2 ); + message.push_back( 247 ); + midiout.sendMessage( &message ); + + + } + catch ( RtMidiError &error ) { + error.printMessage(); + exit( EXIT_FAILURE ); + } + + return 0; +} + +bool chooseMidiPort( RtMidiOut &midi ) +{ + std::cout << "\nWould you like to open a virtual input port? [y/N] "; + + std::string keyHit; + std::getline( std::cin, keyHit ); + if ( keyHit == "y" ) { + midi.openVirtualPort(); + std::cout << "Press return to start the transmission." << std::endl; + std::getline( std::cin, keyHit ); + + return true; + } + + std::string portName; + rtmidi::PortList list = midi.getPortList(rtmidi::PortDescriptor::INPUT); + if ( list.empty() ) { + std::cout << "No output ports available!" << std::endl; + return false; + } + + rtmidi::Pointer selected = list.front(); + if ( list.size() == 1 ) { + std::cout << "\nOpening " << selected->getName() << std::endl; + } else { + int nr; + std::vector > pointers(list.size()); + // copy the data into a structure that is used by the user interface. + std::copy(list.begin(),list.end(),pointers.begin()); + for (nr = 0 ; nr < (int)pointers.size(); nr++) { + portName = pointers[nr]->getName(rtmidi::PortDescriptor::LONG_NAME + | rtmidi::PortDescriptor::UNIQUE_NAME + | rtmidi::PortDescriptor::INCLUDE_API); + std::cout << " Output port #" << nr << ": " << portName << '\n'; + } + + do { + std::cout << "\nChoose a port number: "; + std::cin >> nr; + } while ( nr >= (int)pointers.size() ); + std::getline( std::cin, keyHit ); // used to clear out stdin + selected = pointers[nr]; + } + + /* The midi setup might have changed meanwhile. + Our portlist is under our control. So we enumerate this list. */ + // midi.openPort( i ); + midi.openPort(selected); + + return true; +} From 33f43631b417b332a9006523fb43f9cd4a7b9fa9 Mon Sep 17 00:00:00 2001 From: Tobias Schlemmer Date: Sun, 6 Apr 2014 10:52:53 +0200 Subject: [PATCH 29/45] Fix port handling of old port handling. This was broken as we use ALSA addresses to store port ids, now. These are stored as unsigned values. --- RtMidi.cpp | 45 +++++++++++++++++++++++---------------------- 1 file changed, 23 insertions(+), 22 deletions(-) diff --git a/RtMidi.cpp b/RtMidi.cpp index ec15251c..5796f5a8 100644 --- a/RtMidi.cpp +++ b/RtMidi.cpp @@ -1293,7 +1293,7 @@ namespace rtmidi { } snd_seq_port_subscribe_t * connectPorts(const snd_seq_addr_t & from, - const snd_seq_addr_t & to, + const snd_seq_addr_t & to, bool real_time) { init(); snd_seq_port_subscribe_t *subscription; @@ -2077,7 +2077,7 @@ namespace rtmidi { data->openPort (SND_SEQ_PORT_CAP_WRITE | SND_SEQ_PORT_CAP_SUBS_WRITE, portName); data->setRemote(remote); - data->connectPorts(*remote,data->local); + data->connectPorts(*remote,data->local,false); if ( inputData_.doInput == false ) { @@ -2206,7 +2206,7 @@ namespace rtmidi { // Cleanup. AlsaMidiData *data = static_cast (apiData_); - if ( data->local.port >= 0 ) snd_seq_delete_port( data->seq, data->local.port ); + if ( data->local.client > 0 ) snd_seq_delete_port( data->seq, data->local.port ); if ( data->coder ) snd_midi_event_free( data->coder ); if ( data->buffer ) free( data->buffer ); snd_seq_close( data->seq ); @@ -2315,23 +2315,22 @@ namespace rtmidi { return; } - snd_seq_addr_t sender, receiver; - receiver.client = snd_seq_port_info_get_client( pinfo ); - receiver.port = snd_seq_port_info_get_port( pinfo ); - sender.client = snd_seq_client_id( data->seq ); - - if ( data->local.port < 0 ) { - data->local.port = snd_seq_create_simple_port( data->seq, portName.c_str(), - SND_SEQ_PORT_CAP_READ|SND_SEQ_PORT_CAP_SUBS_READ, - SND_SEQ_PORT_TYPE_MIDI_GENERIC|SND_SEQ_PORT_TYPE_APPLICATION ); - if ( data->local.port < 0 ) { + data->client = snd_seq_port_info_get_client( pinfo ); + data->port = snd_seq_port_info_get_port( pinfo ); + data->local.client = snd_seq_client_id( data->seq ); + + if ( !data->local.client ) { + int port = snd_seq_create_simple_port( data->seq, portName.c_str(), + SND_SEQ_PORT_CAP_READ|SND_SEQ_PORT_CAP_SUBS_READ, + SND_SEQ_PORT_TYPE_MIDI_GENERIC|SND_SEQ_PORT_TYPE_APPLICATION ); + if ( port < 0 ) { errorString_ = "MidiOutAlsa::openPort: ALSA error creating output port."; error( Error::DRIVER_ERROR, errorString_ ); return; } - } - sender.port = data->local.port; + data->local.port = port; + } // Make subscription if (snd_seq_port_subscribe_malloc( &data->subscription ) < 0) { @@ -2340,8 +2339,8 @@ namespace rtmidi { error( Error::DRIVER_ERROR, errorString_ ); return; } - snd_seq_port_subscribe_set_sender(data->subscription, &sender); - snd_seq_port_subscribe_set_dest(data->subscription, &receiver); + snd_seq_port_subscribe_set_sender(data->subscription, data); + snd_seq_port_subscribe_set_dest(data->subscription, &data->local); snd_seq_port_subscribe_set_time_update(data->subscription, 1); snd_seq_port_subscribe_set_time_real(data->subscription, 1); if ( snd_seq_subscribe_port(data->seq, data->subscription) ) { @@ -2367,15 +2366,17 @@ namespace rtmidi { void MidiOutAlsa :: openVirtualPort( std::string portName ) { AlsaMidiData *data = static_cast (apiData_); - if ( data->local.port < 0 ) { - data->local.port = snd_seq_create_simple_port( data->seq, portName.c_str(), - SND_SEQ_PORT_CAP_READ|SND_SEQ_PORT_CAP_SUBS_READ, - SND_SEQ_PORT_TYPE_MIDI_GENERIC|SND_SEQ_PORT_TYPE_APPLICATION ); + if ( !data->local.client ) { + int port = snd_seq_create_simple_port( data->seq, portName.c_str(), + SND_SEQ_PORT_CAP_READ|SND_SEQ_PORT_CAP_SUBS_READ, + SND_SEQ_PORT_TYPE_MIDI_GENERIC|SND_SEQ_PORT_TYPE_APPLICATION ); - if ( data->local.port < 0 ) { + if ( port < 0 ) { errorString_ = "MidiOutAlsa::openVirtualPort: ALSA error creating virtual port."; error( Error::DRIVER_ERROR, errorString_ ); } + data->local.port = port; + data->local.client = snd_seq_client_id(data->seq); } } From 038472b3f2c29901892c7822211729a935ba6de5 Mon Sep 17 00:00:00 2001 From: Tobias Schlemmer Date: Sun, 6 Apr 2014 10:53:21 +0200 Subject: [PATCH 30/45] fix sendMessage which got an error. --- RtMidi.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/RtMidi.h b/RtMidi.h index c4553673..cfdb34ef 100644 --- a/RtMidi.h +++ b/RtMidi.h @@ -953,7 +953,8 @@ namespace rtmidi { } if (rtapi_) static_cast(rtapi_)->sendMessage(*message); - error( Error::WARNING, "MidiOut::sendMessage: The API has not been set."); + else + error( Error::WARNING, "MidiOut::sendMessage: The API has not been set."); } From 7b9a335142192078b8cdce553e8fb0f303045bb1 Mon Sep 17 00:00:00 2001 From: Tobias Schlemmer Date: Sun, 6 Apr 2014 10:55:22 +0200 Subject: [PATCH 31/45] Adapt qmidiin to the new API. --- tests/qmidiin2.cpp | 117 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 117 insertions(+) create mode 100644 tests/qmidiin2.cpp diff --git a/tests/qmidiin2.cpp b/tests/qmidiin2.cpp new file mode 100644 index 00000000..e3e1a996 --- /dev/null +++ b/tests/qmidiin2.cpp @@ -0,0 +1,117 @@ +//*****************************************// +// qmidiin.cpp +// by Gary Scavone, 2003-2004. +// +// Simple program to test MIDI input and +// retrieval from the queue. +// +//*****************************************// + +#include +#include +#include +#include "RtMidi.h" + +// Platform-dependent sleep routines. +#if defined(__WINDOWS_MM__) +#include +#define SLEEP( milliseconds ) Sleep( (DWORD) milliseconds ) +#else // Unix variants +#include +#define SLEEP( milliseconds ) usleep( (unsigned long) (milliseconds * 1000.0) ) +#endif + +bool done; +static void finish( int /*ignore*/ ){ done = true; } + +void usage( rtmidi::PortList list ) { + // Error function in case of incorrect command-line + // argument specifications. + std::cout << "\nusage: qmidiin \n"; + std::cout << " where port = the device to use (default = first available port).\n\n"; + + std::cout << "Available ports:" << std::endl; + for (rtmidi::PortList::iterator i = list.begin(); + i != list.end(); i++) { + std::cout << (*i)->getName(rtmidi::PortDescriptor::SESSION_PATH | + rtmidi::PortDescriptor::UNIQUE_NAME | + rtmidi::PortDescriptor::INCLUDE_API); + std::cout << "\t"; + std::cout << (*i)->getName() << std::endl; + } + exit( 0 ); +} + +int main( int argc, char *argv[] ) +{ + std::vector message; + int nBytes, i; + double stamp; + + + // RtMidiIn constructor + try { + RtMidiIn midiin; + + + rtmidi::PortList list = midiin.getPortList(); + + // Minimal command-line check. + if ( argc > 2 ) usage(list); + + rtmidi::Pointer port = 0; + // Check available ports vs. specified. + if ( argc == 2 ) { + for (rtmidi::PortList::iterator i = list.begin(); + i != list.end(); i++) { + if (argv[1] == (*i)->getName(rtmidi::PortDescriptor::SESSION_PATH | + rtmidi::PortDescriptor::UNIQUE_NAME | + rtmidi::PortDescriptor::INCLUDE_API)) { + port = *i; + break; + } + } + } else { + port = list.front(); + } + if ( !port ) { + std::cout << "Invalid port specifier!\n"; + usage(list); + } + + try { + midiin.openPort( port ); + } + catch ( RtMidiError &error ) { + error.printMessage(); + return 1; + } + + // Don't ignore sysex, timing, or active sensing messages. + midiin.ignoreTypes( false, false, false ); + + // Install an interrupt handler function. + done = false; + (void) signal(SIGINT, finish); + + // Periodically check input queue. + std::cout << "Reading MIDI from port ... quit with Ctrl-C.\n"; + while ( !done ) { + stamp = midiin.getMessage( &message ); + nBytes = message.size(); + for ( i=0; i 0 ) + std::cout << "stamp = " << stamp << std::endl; + + // Sleep for 10 milliseconds. + SLEEP( 10 ); + } + } + catch ( RtMidiError &error ) { + error.printMessage(); + exit( EXIT_FAILURE ); + } + + return 0; +} From 3733417019055f24f517f9b29e7ac3c653a466f6 Mon Sep 17 00:00:00 2001 From: Tobias Schlemmer Date: Tue, 8 Apr 2014 21:15:55 +0200 Subject: [PATCH 32/45] Implement the missing functions of the proposed port selection API. Signed-off-by: Tobias Schlemmer --- RtMidi.cpp | 99 ++++++++++++++++++++++++++++++++++++++++++++---------- RtMidi.h | 64 +++++++++++++++++++++++------------ 2 files changed, 124 insertions(+), 39 deletions(-) diff --git a/RtMidi.cpp b/RtMidi.cpp index 5796f5a8..35f8765f 100644 --- a/RtMidi.cpp +++ b/RtMidi.cpp @@ -1168,7 +1168,7 @@ namespace rtmidi { } } - AlsaSequencer(const std::string & name):seq(0) + AlsaSequencer(const std::string & n):seq(0),name(n) { if (locking) { pthread_mutexattr_t attr; @@ -1190,6 +1190,13 @@ namespace rtmidi { } } + bool setName(const std::string & n) { + /* we don't want to rename the client after opening it. */ + if (seq) return false; + name = n; + return true; + } + std::string GetPortName(int client, int port, int flags) { init(); snd_seq_client_info_t *cinfo; @@ -1255,6 +1262,7 @@ namespace rtmidi { } int getPortCapabilities(int client, int port) { + init(); snd_seq_port_info_t *pinfo; snd_seq_port_info_alloca( &pinfo ); { @@ -1361,6 +1369,7 @@ namespace rtmidi { }; pthread_mutex_t mutex; snd_seq_t * seq; + std::string name; snd_seq_client_info_t * GetClient(int id) { @@ -1387,6 +1396,7 @@ namespace rtmidi { Error::DRIVER_ERROR ); return; } + snd_seq_set_client_name( seq, name.c_str() ); } } }; @@ -1398,34 +1408,56 @@ namespace rtmidi { { MidiApi * api; static LockingAlsaSequencer seq; - AlsaPortDescriptor():api(0) + AlsaPortDescriptor(const std::string & name):api(0),clientName(name) { client = 0; port = 0; } - AlsaPortDescriptor(int c, int p):api(0) + AlsaPortDescriptor(int c, int p, const std::string & name):api(0),clientName(name) { client = c; port = p; + seq.setName(name); + } + AlsaPortDescriptor(snd_seq_addr_t & other, + const std::string & name):snd_seq_addr_t(other), + clientName(name) { + seq.setName(name); } ~AlsaPortDescriptor() {} - MidiApi * getAPI() { - return NULL; + MidiInApi * getInputApi(unsigned int queueSizeLimit = 100) { + if (getCapabilities() & INPUT) + return new MidiInAlsa(clientName,queueSizeLimit); + else + return 0; + } + MidiOutApi * getOutputApi() { + if (getCapabilities() & OUTPUT) + return new MidiOutAlsa(clientName); + else + return 0; } std::string getName(int flags = SHORT_NAME | UNIQUE_NAME) { return seq.GetPortName(client,port,flags); } + + const std::string & getClientName() { + return clientName; + } int getCapabilities() { + if (!client) return 0; return seq.getPortCapabilities(client,port); } - static PortList getPortList(int capabilities); + static PortList getPortList(int capabilities, const std::string & clientName); + protected: + std::string clientName; }; LockingAlsaSequencer AlsaPortDescriptor::seq; - PortList AlsaPortDescriptor :: getPortList(int capabilities) + PortList AlsaPortDescriptor :: getPortList(int capabilities, const std::string & clientName) { PortList list; snd_seq_client_info_t *cinfo; @@ -1460,7 +1492,7 @@ namespace rtmidi { != (SND_SEQ_PORT_CAP_WRITE|SND_SEQ_PORT_CAP_SUBS_WRITE)) continue; } - list.push_back(new AlsaPortDescriptor(client,snd_seq_port_info_get_port(pinfo))); + list.push_back(new AlsaPortDescriptor(client,snd_seq_port_info_get_port(pinfo),clientName)); } } return list; @@ -1478,13 +1510,19 @@ namespace rtmidi { */ struct AlsaMidiData:public AlsaPortDescriptor { - AlsaMidiData():seq() { + /* + AlsaMidiData():seq() + { init(); } - AlsaMidiData(const std::string &clientName):seq(clientName) { + */ + AlsaMidiData(const std::string &clientName):AlsaPortDescriptor(clientName), + seq(clientName) + { init(); } - ~AlsaMidiData() { + ~AlsaMidiData() + { if (local.client) deletePort(); } @@ -1796,7 +1834,8 @@ namespace rtmidi { return 0; } - MidiInAlsa :: MidiInAlsa( const std::string clientName, unsigned int queueSizeLimit ) : MidiInApi( queueSizeLimit ) + MidiInAlsa :: MidiInAlsa( const std::string clientName, + unsigned int queueSizeLimit ) : MidiInApi( queueSizeLimit ) { initialize( clientName ); } @@ -2087,13 +2126,25 @@ namespace rtmidi { connected_ = true; } - Pointer MidiInAlsa :: getDescriptor() + Pointer MidiInAlsa :: getDescriptor(bool local) { - abort(); + AlsaMidiData *data = static_cast (apiData_); + if (local) { + if (data && data->local.client) { + return new AlsaPortDescriptor(data->local,data->getClientName()); + } + } else { + if (data && data->client) { + return new AlsaPortDescriptor(*data,data->getClientName()); + } + } + return NULL; } PortList MidiInAlsa :: getPortList(int capabilities) { - return AlsaPortDescriptor::getPortList(capabilities | PortDescriptor::INPUT); + AlsaMidiData *data = static_cast (apiData_); + return AlsaPortDescriptor::getPortList(capabilities | PortDescriptor::INPUT, + data->getClientName()); } @@ -2460,13 +2511,25 @@ namespace rtmidi { connected_ = true; } - Pointer MidiOutAlsa :: getDescriptor() + Pointer MidiOutAlsa :: getDescriptor(bool local) { - abort(); + AlsaMidiData *data = static_cast (apiData_); + if (local) { + if (data && data->local.client) { + return new AlsaPortDescriptor(data->local, data->getClientName()); + } + } else { + if (data && data->client) { + return new AlsaPortDescriptor(*data, data->getClientName()); + } + } + return NULL; } PortList MidiOutAlsa :: getPortList(int capabilities) { - return AlsaPortDescriptor::getPortList(capabilities | PortDescriptor::OUTPUT); + AlsaMidiData *data = static_cast (apiData_); + return AlsaPortDescriptor::getPortList(capabilities | PortDescriptor::OUTPUT, + data->getClientName()); } } #endif // __LINUX_ALSA__ diff --git a/RtMidi.h b/RtMidi.h index cfdb34ef..aa05d38d 100644 --- a/RtMidi.h +++ b/RtMidi.h @@ -222,6 +222,8 @@ namespace rtmidi { #endif class MidiApi; + class MidiInApi; + class MidiOutApi; struct PortDescriptor { //! Flags for formatting a string description of the port. @@ -282,13 +284,27 @@ namespace rtmidi { */ virtual ~PortDescriptor() {}; - //! Get the MIDI api for the current port. + //! Get the MIDI input api for the current port. /*! This is the only information RtMidi needs to know: Which - * API should handle this object. + * API should handle this object. This can be used to get + * an API which can send data to the given port. * - * \return API that can handle this object. + * \param queueSizeLimit The limit of the midi queue. This parameter is handled by + * the constructor of the backend API. + * + * \return API that can use this object to connect to an input port or 0 + * if no input API can be created. */ - virtual MidiApi * getAPI() = 0; + virtual MidiInApi * getInputApi(unsigned int queueSizeLimit = 100) = 0; + + //! Get the MIDI output api for the current port. + /*! This is the only information RtMidi needs to know: Which + * API should handle this object. This can be used to get + * an API which can receive data from the given port. + * + * \return API that can use this object to connect to an output port. + */ + virtual MidiOutApi * getOutputApi() = 0; //! Return the port name /*! @@ -378,8 +394,14 @@ namespace rtmidi { openPort(*p, portName); } - //! Pure virtual function to return a port descirptor if the port is open - virtual Pointer getDescriptor() = 0; + //! Pure virtual function to return a port descriptor if the port is open + /*! This function returns a port descriptor that can be used to open another port + either to the connected port or – if the backend supports it – the connecting port. + \param local The parameter local defines whether the function returns a descriptor to + the virtual port (true) or the remote port (false). The function returns 0 if the + port cannot be determined (e.g. if the port is not connected or the backend dosen't support it). + */ + virtual Pointer getDescriptor(bool local=false) = 0; //! Pure virtual function to return a list of all available ports of the current API. /*! @@ -463,7 +485,7 @@ namespace rtmidi { MidiInApi( unsigned int queueSizeLimit ); virtual ~MidiInApi( void ); - void setCallback( MidiCallback callback, void *userData ); + void setCallback( MidiCallback callback, void *userData = 0 ); void cancelCallback( void ); virtual void ignoreTypes( bool midiSysex, bool midiTime, bool midiSense ); RTMIDI_DEPRECATED(double getMessage( std::vector *message )) @@ -642,9 +664,9 @@ namespace rtmidi { } //! Pure virtual function to return a port descirptor if the port is open - Pointer getDescriptor() + Pointer getDescriptor(bool local=false) { - if (rtapi_) return rtapi_->getDescriptor(); + if (rtapi_) return rtapi_->getDescriptor(local); return 0; } @@ -994,7 +1016,7 @@ namespace rtmidi { void openPort( unsigned int portNumber, const std::string & portName ); void openVirtualPort( const std::string portName ); void openPort( const PortDescriptor & port, const std::string & portName); - Pointer getDescriptor(); + Pointer getDescriptor(bool local=false); PortList getPortList(int capabilities); void closePort( void ); unsigned int getPortCount( void ); @@ -1013,7 +1035,7 @@ namespace rtmidi { void openPort( unsigned int portNumber, const std::string & portName ); void openVirtualPort( const std::string portName ); void openPort( const PortDescriptor & port, const std::string & portName); - Pointer getDescriptor(); + Pointer getDescriptor(bool local=false); PortList getPortList(int capabilities); void closePort( void ); unsigned int getPortCount( void ); @@ -1037,7 +1059,7 @@ namespace rtmidi { void openPort( unsigned int portNumber, const std::string & portName ); void openVirtualPort( const std::string portName ); void openPort( const PortDescriptor & port, const std::string & portName); - Pointer getDescriptor(); + Pointer getDescriptor(bool local=false); PortList getPortList(int capabilities); void closePort( void ); unsigned int getPortCount( void ); @@ -1059,7 +1081,7 @@ namespace rtmidi { void openPort( unsigned int portNumber, const std::string & portName ); void openVirtualPort( const std::string portName ); void openPort( const PortDescriptor & port, const std::string & portName); - Pointer getDescriptor(); + Pointer getDescriptor(bool local=false); PortList getPortList(int capabilities); void closePort( void ); unsigned int getPortCount( void ); @@ -1086,7 +1108,7 @@ namespace rtmidi { void openPort( unsigned int portNumber, const std::string & portName ); void openVirtualPort( const std::string portName ); void openPort( const PortDescriptor & port, const std::string & portName); - Pointer getDescriptor(); + Pointer getDescriptor(bool local=false); PortList getPortList(int capabilities); void closePort( void ); unsigned int getPortCount( void ); @@ -1105,7 +1127,7 @@ namespace rtmidi { void openPort( unsigned int portNumber, const std::string & portName ); void openVirtualPort( const std::string portName ); void openPort( const PortDescriptor & port, const std::string & portName); - Pointer getDescriptor(); + Pointer getDescriptor(bool local=false); PortList getPortList(int capabilities); void closePort( void ); unsigned int getPortCount( void ); @@ -1129,7 +1151,7 @@ namespace rtmidi { void openPort( unsigned int portNumber, const std::string & portName ); void openVirtualPort( const std::string portName ); void openPort( const PortDescriptor & port, const std::string & portName); - Pointer getDescriptor(); + Pointer getDescriptor(bool local=false); PortList getPortList(int capabilities); void closePort( void ); unsigned int getPortCount( void ); @@ -1148,7 +1170,7 @@ namespace rtmidi { void openPort( unsigned int portNumber, const std::string & portName ); void openVirtualPort( const std::string portName ); void openPort( const PortDescriptor & port, const std::string & portName); - Pointer getDescriptor(); + Pointer getDescriptor(bool local=false); PortList getPortList(int capabilities); void closePort( void ); unsigned int getPortCount( void ); @@ -1172,7 +1194,7 @@ namespace rtmidi { void openPort( unsigned int portNumber, const std::string & portName ); void openVirtualPort( const std::string portName ); void openPort( const PortDescriptor & port, const std::string & portName); - Pointer getDescriptor(); + Pointer getDescriptor(bool local=false); PortList getPortList(int capabilities); void closePort( void ); unsigned int getPortCount( void ); @@ -1191,7 +1213,7 @@ namespace rtmidi { void openPort( unsigned int portNumber, const std::string & portName ); void openVirtualPort( const std::string portName ); void openPort( const PortDescriptor & port, const std::string & portName); - Pointer getDescriptor(); + Pointer getDescriptor(bool local=false); PortList getPortList(int capabilities); void closePort( void ); unsigned int getPortCount( void ); @@ -1218,7 +1240,7 @@ namespace rtmidi { void openPort( unsigned int /*portNumber*/, const & std::string /*portName*/ ) {} void openVirtualPort( const std::string /*portName*/ ) {} void openPort( const PortDescriptor & port, const & std::string portName) {} - Pointer getDescriptor() { return 0; } + Pointer getDescriptor(bool local=false) { return 0; } PortList getPortList(int capabilities) { return PortList(); } void closePort( void ) {} unsigned int getPortCount( void ) { return 0; } @@ -1239,7 +1261,7 @@ namespace rtmidi { void openPort( unsigned int /*portNumber*/, const & std::string /*portName*/ ) {} void openVirtualPort( const std::string /*portName*/ ) {} void openPort( const PortDescriptor & port, const & std::string portName) {} - Pointer getDescriptor() { return 0; } + Pointer getDescriptor(bool local=false) { return 0; } PortList getPortList(int capabilities) { return PortList(); } void closePort( void ) {} unsigned int getPortCount( void ) { return 0; } From 2a299e32e68528a722654147657a988a92842569 Mon Sep 17 00:00:00 2001 From: Tobias Schlemmer Date: Tue, 8 Apr 2014 21:20:30 +0200 Subject: [PATCH 33/45] Provide a test case that uses virtual ports to test communication with virtual ports. --- tests/Makefile.in | 5 +- tests/cmidiin.cpp | 2 +- tests/loopback.cpp | 189 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 194 insertions(+), 2 deletions(-) create mode 100644 tests/loopback.cpp diff --git a/tests/Makefile.in b/tests/Makefile.in index bea71da1..bc8a728a 100644 --- a/tests/Makefile.in +++ b/tests/Makefile.in @@ -1,7 +1,7 @@ ### Do not edit -- Generated by 'configure --with-whatever' from Makefile.in ### RtMidi tests Makefile - for various flavors of unix -PROGRAMS = midiprobe midiout qmidiin cmidiin sysextest midiprobe2 cmidiin2 qmidiin2 midiout2 +PROGRAMS = midiprobe midiout qmidiin cmidiin sysextest midiprobe2 cmidiin2 qmidiin2 midiout2 loopback RM = /bin/rm SRC_PATH = .. INCLUDE = .. @@ -48,6 +48,9 @@ cmidiin2 : cmidiin2.cpp $(OBJECTS) sysextest : sysextest.cpp $(OBJECTS) $(CC) $(CFLAGS) $(DEFS) -o sysextest sysextest.cpp $(OBJECT_PATH)/RtMidi.o $(LIBRARY) +loopback : loopback.cpp $(OBJECTS) + $(CC) $(CFLAGS) $(DEFS) -o loopback loopback.cpp $(OBJECT_PATH)/RtMidi.o $(LIBRARY) + clean : $(RM) -f $(OBJECT_PATH)/*.o $(RM) -f $(PROGRAMS) *.exe diff --git a/tests/cmidiin.cpp b/tests/cmidiin.cpp index be78dbbd..49e48edb 100644 --- a/tests/cmidiin.cpp +++ b/tests/cmidiin.cpp @@ -19,7 +19,7 @@ void usage( void ) { exit( 0 ); } -void mycallback( double deltatime, std::vector< unsigned char > *message, void */*userData*/ ) +void mycallback( double deltatime, std::vector< unsigned char > *message, void * /* userData */ ) { unsigned int nBytes = message->size(); for ( unsigned int i=0; i +#include +#include "RtMidi.h" + +// Platform-dependent sleep routines. +#if defined(__WINDOWS_MM__) +#include +#define SLEEP( milliseconds ) Sleep( (DWORD) milliseconds ) +#else // Unix variants +#include +#define SLEEP( milliseconds ) usleep( (unsigned long) (milliseconds * 1000.0) ) +#endif + + +/* Here, we store the expected output. Timing is not tested */ +std::vector virtualinstring; +const char * virtualinstringgoal = + "\xc0\x5\xf1\x3c\xb0\x7\x64\x90\x40\x5a\x80\x40\x28\xb0\x7\x28\xf0\x43\x4\x3\x2\xf7"; +std::vector instring; +const char * instringgoal = + "\xc0\x6\xf1\x3d\xb0\x8\x64\x90\x41\x5a\x80\x41\x28\xb0\x8\x28\xf0\x43\x4\x3\x3\xf7"; + +void mycallback1( double deltatime, std::vector< unsigned char > *message, void * /* userData */ ) +{ + unsigned int nBytes = message->size(); + for ( unsigned int i=0; iat(i)); + // std::cout << "\\x" << std::hex << (int)message->at(i) << std::flush; + } + /* if ( nBytes > 0 ) + std::cout << "stamp = " << deltatime << std::endl; + */ +} + +void mycallback2( double deltatime, std::vector< unsigned char > *message, void * /* userData */ ) +{ + unsigned int nBytes = message->size(); + for ( unsigned int i=0; iat(i)); + // std::cout << "\\x" << std::hex << (int)message->at(i); + } + /* + if ( nBytes > 0 ) + std::cout << "stamp = " << deltatime << std::endl; + */ +} + + + +int main( int argc, char */*argv*/[] ) +{ + + std::vector message; + + try { + + // RtMidiIn constructor + RtMidiIn virtualin; + // RtMidiIn constructor + RtMidiOut virtualout; + + virtualin.openVirtualPort("RtMidi Test Virtual In"); + virtualout.openVirtualPort("RtMidi Test Virtual Out"); + + rtmidi::Pointer indescriptor + = virtualin.getDescriptor(true); + + rtmidi::Pointer outdescriptor + = virtualout.getDescriptor(true); + + { // avoid problems with wrong destruction order + /* use smart pointers to handle deletion */ + rtmidi::Pointer midiin = outdescriptor->getInputApi(); + if (!midiin) abort(); + rtmidi::Pointer midiout = indescriptor->getOutputApi(); + if (!midiout) abort(); + + + + midiin->openPort(outdescriptor); + midiout->openPort(indescriptor); + + + // Set our callback function. This should be done immediately after + // opening the port to avoid having incoming messages written to the + // queue instead of sent to the callback function. + midiin->setCallback( &mycallback1 ); + virtualin.setCallback( &mycallback2 ); + + // Don't ignore sysex, timing, or active sensing messages. + // Don't ignore sysex, timing, or active sensing messages. + midiin->ignoreTypes( false, false, false ); + virtualin.ignoreTypes( false, false, false ); + + SLEEP( 5000 ); + + // Send out a series of MIDI messages. + + // Program change: 192, 5 + message.push_back( 192 ); + message.push_back( 5 ); + midiout->sendMessage( &message ); + message[1] = 6; + virtualout.sendMessage(&message); + + SLEEP( 500 ); + + message[0] = 0xF1; + message[1] = 60; + midiout->sendMessage( &message ); + message[1] = 61; + virtualout.sendMessage(&message); + + // Control Change: 176, 7, 100 (volume) + message[0] = 176; + message[1] = 7; + message.push_back( 100 ); + midiout->sendMessage( &message ); + message[1] = 8; + virtualout.sendMessage ( &message ); + + // Note On: 144, 64, 90 + message[0] = 144; + message[1] = 64; + message[2] = 90; + midiout->sendMessage( &message ); + message[1] = 65; + virtualout.sendMessage( &message ); + + SLEEP( 500 ); + + // Note Off: 128, 64, 40 + message[0] = 128; + message[1] = 64; + message[2] = 40; + midiout->sendMessage( &message ); + message[1] = 65; + virtualout.sendMessage( &message ); + + SLEEP( 500 ); + + // Control Change: 176, 7, 40 + message[0] = 176; + message[1] = 7; + message[2] = 40; + midiout->sendMessage( &message ); + message[1] = 8; + virtualout.sendMessage( &message ); + + SLEEP( 500 ); + + // Sysex: 240, 67, 4, 3, 2, 247 + message[0] = 240; + message[1] = 67; + message[2] = 4; + message.push_back( 3 ); + message.push_back( 2 ); + message.push_back( 247 ); + midiout->sendMessage( &message ); + message[4] = 3; + virtualout.sendMessage( &message ); + + SLEEP( 500 ); + } + const unsigned char * goal = reinterpret_cast(instringgoal); + size_t i; + for (i = 0 ; i < instring.size() && goal[i] ; i++) + if (instring[i] != goal[i]) abort(); + if (i != instring.size()) abort(); + goal = reinterpret_cast(virtualinstringgoal); + for (i = 0 ; i < virtualinstring.size() && goal[i] ; i++) + if (virtualinstring[i] != goal[i]) abort(); + if (i != virtualinstring.size()) abort(); + + } catch ( RtMidiError &error ) { + error.printMessage(); + } +} From 91848086b91f8bf34a64d2ecbb325b4bc13b9014 Mon Sep 17 00:00:00 2001 From: Tobias Schlemmer Date: Sun, 13 Apr 2014 22:07:06 +0200 Subject: [PATCH 34/45] Some whitespace changes. --- RtMidi.cpp | 80 +++++++++++++++++++++++++++--------------------------- 1 file changed, 40 insertions(+), 40 deletions(-) diff --git a/RtMidi.cpp b/RtMidi.cpp index 35f8765f..a40e583b 100644 --- a/RtMidi.cpp +++ b/RtMidi.cpp @@ -406,11 +406,11 @@ namespace rtmidi { } #if defined(__MACOSX_CORE__) - // The CoreMIDI API is based on the use of a callback function for - // MIDI input. We convert the system specific time stamps to delta - // time values. +// The CoreMIDI API is based on the use of a callback function for +// MIDI input. We convert the system specific time stamps to delta +// time values. - // OS-X CoreMIDI header files. +// OS-X CoreMIDI header files. #include #include #include @@ -1128,20 +1128,20 @@ namespace rtmidi { #if defined(__LINUX_ALSA__) - // The ALSA Sequencer API is based on the use of a callback function for - // MIDI input. - // - // Thanks to Pedro Lopez-Cabanillas for help with the ALSA sequencer - // time stamps and other assorted fixes!!! +// The ALSA Sequencer API is based on the use of a callback function for +// MIDI input. +// +// Thanks to Pedro Lopez-Cabanillas for help with the ALSA sequencer +// time stamps and other assorted fixes!!! - // If you don't need timestamping for incoming MIDI events, define the - // preprocessor definition AVOID_TIMESTAMPING to save resources - // associated with the ALSA sequencer queues. +// If you don't need timestamping for incoming MIDI events, define the +// preprocessor definition AVOID_TIMESTAMPING to save resources +// associated with the ALSA sequencer queues. #include #include - // ALSA header file. +// ALSA header file. #include namespace rtmidi { @@ -1151,8 +1151,8 @@ namespace rtmidi { the following functionality: - dynamic allocation of the sequencer - optionallay avoid concurrent access to the ALSA sequencer, - which is not thread proof. This feature is controlled by - the parameter \ref locking. + which is not thread proof. This feature is controlled by + the parameter \ref locking. */ template @@ -1478,7 +1478,7 @@ namespace rtmidi { unsigned int atyp = snd_seq_port_info_get_type( pinfo ); // otherwise we get ports without any if ( !(capabilities & UNLIMITED) && - !( atyp & SND_SEQ_PORT_TYPE_MIDI_GENERIC ) ) continue; + !( atyp & SND_SEQ_PORT_TYPE_MIDI_GENERIC ) ) continue; unsigned int caps = snd_seq_port_info_get_capability( pinfo ); if (capabilities & INPUT) { /* we need both READ and SUBS_READ */ @@ -1511,10 +1511,10 @@ namespace rtmidi { struct AlsaMidiData:public AlsaPortDescriptor { /* - AlsaMidiData():seq() - { - init(); - } + AlsaMidiData():seq() + { + init(); + } */ AlsaMidiData(const std::string &clientName):AlsaPortDescriptor(clientName), seq(clientName) @@ -1566,7 +1566,7 @@ namespace rtmidi { const std::string & portName) { if (subscription) { api->error( Error::DRIVER_ERROR, - "MidiInAlsa::openPort: ALSA error allocation port subscription." ); + "MidiInAlsa::openPort: ALSA error allocation port subscription." ); return -99; } @@ -2535,22 +2535,22 @@ namespace rtmidi { #endif // __LINUX_ALSA__ - //*********************************************************************// - // API: Windows Multimedia Library (MM) - //*********************************************************************// +//*********************************************************************// +// API: Windows Multimedia Library (MM) +//*********************************************************************// - // API information deciphered from: - // - http://msdn.microsoft.com/library/default.asp?url=/library/en-us/multimed/htm/_win32_midi_reference.asp +// API information deciphered from: +// - http://msdn.microsoft.com/library/default.asp?url=/library/en-us/multimed/htm/_win32_midi_reference.asp - // Thanks to Jean-Baptiste Berruchon for the sysex code. +// Thanks to Jean-Baptiste Berruchon for the sysex code. #if defined(__WINDOWS_MM__) - // The Windows MM API is based on the use of a callback function for - // MIDI input. We convert the system specific time stamps to delta - // time values. +// The Windows MM API is based on the use of a callback function for +// MIDI input. We convert the system specific time stamps to delta +// time values. - // Windows MM MIDI header files. +// Windows MM MIDI header files. #include #include @@ -3081,15 +3081,15 @@ namespace rtmidi{ #define INSTANTIATE_GUID(a) GUID const a = { STATIC_ ## a } - INSTANTIATE_GUID(GUID_NULL); - INSTANTIATE_GUID(KSPROPSETID_Pin); - INSTANTIATE_GUID(KSPROPSETID_Connection); - INSTANTIATE_GUID(KSPROPSETID_Topology); - INSTANTIATE_GUID(KSINTERFACESETID_Standard); - INSTANTIATE_GUID(KSMEDIUMSETID_Standard); - INSTANTIATE_GUID(KSDATAFORMAT_TYPE_MUSIC); - INSTANTIATE_GUID(KSDATAFORMAT_SUBTYPE_MIDI); - INSTANTIATE_GUID(KSDATAFORMAT_SPECIFIER_NONE); +INSTANTIATE_GUID(GUID_NULL); +INSTANTIATE_GUID(KSPROPSETID_Pin); +INSTANTIATE_GUID(KSPROPSETID_Connection); +INSTANTIATE_GUID(KSPROPSETID_Topology); +INSTANTIATE_GUID(KSINTERFACESETID_Standard); +INSTANTIATE_GUID(KSMEDIUMSETID_Standard); +INSTANTIATE_GUID(KSDATAFORMAT_TYPE_MUSIC); +INSTANTIATE_GUID(KSDATAFORMAT_SUBTYPE_MIDI); +INSTANTIATE_GUID(KSDATAFORMAT_SPECIFIER_NONE); #undef INSTANTIATE_GUID namespace rtmidi { From 0231a29334e443cfd27a9b483160e4d587bfe122 Mon Sep 17 00:00:00 2001 From: Tobias Schlemmer Date: Sun, 13 Apr 2014 22:20:19 +0200 Subject: [PATCH 35/45] Implement new port selection API for JACK --- RtMidi.cpp | 697 ++++++++++++++++++++++++++++++++++++++++++++++----- RtMidi.h | 4 +- configure.ac | 14 ++ 3 files changed, 647 insertions(+), 68 deletions(-) diff --git a/RtMidi.cpp b/RtMidi.cpp index a40e583b..459e41c2 100644 --- a/RtMidi.cpp +++ b/RtMidi.cpp @@ -38,6 +38,7 @@ #include "RtMidi.h" #include +#include namespace rtmidi { //*********************************************************************// @@ -4101,7 +4102,7 @@ namespace rtmidi { #if defined(__UNIX_JACK__) - // JACK header files +// JACK header files #include #include #include @@ -4110,15 +4111,431 @@ namespace rtmidi { namespace rtmidi { - struct JackMidiData { - jack_client_t *client; - jack_port_t *port; + struct JackMidiData; + static int jackProcessIn( jack_nframes_t nframes, void *arg ); + static int jackProcessOut( jack_nframes_t nframes, void *arg ); + + template + class JackSequencer { + public: + JackSequencer():client(0),name(),data(0) + { + if (locking) { + pthread_mutexattr_t attr; + pthread_mutexattr_init(&attr); + pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_NORMAL); + pthread_mutex_init(&mutex, &attr); + } + } + + JackSequencer(const std::string & n, bool startqueue, JackMidiData * d):client(0),name(n),data(d) + { + if (locking) { + pthread_mutexattr_t attr; + pthread_mutexattr_init(&attr); + pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_NORMAL); + pthread_mutex_init(&mutex, &attr); + } + init(client,startqueue); + } + + ~JackSequencer() + { + { + scoped_lock lock (mutex); + if (client) + jack_client_close (client); + } + if (locking) { + pthread_mutex_destroy(&mutex); + } + } + + bool setName(const std::string & n) { + /* we don't want to rename the client after opening it. */ + if (client) return false; + name = n; + return true; + } + + const char ** getPortList(unsigned long flags) { + init(); + return jack_get_ports(client, + NULL, + "midi", + flags); + } + + jack_port_t * getPort(const char * name) { + init(); + return jack_port_by_name(client,name); + } + + std::string getPortName(jack_port_t * port, int flags) { + init(); + int naming = flags & PortDescriptor::NAMING_MASK; + + std::ostringstream os; + switch (naming) { + case PortDescriptor::SESSION_PATH: + if (flags & PortDescriptor::INCLUDE_API) + os << "JACK:"; +#if __UNIX_JACK_HAS_UUID__ + os << "UUID:" << std::hex << jack_port_uuid(port); +#else + os << jack_port_name(port); +#endif + break; + case PortDescriptor::STORAGE_PATH: + if (flags & PortDescriptor::INCLUDE_API) + os << "JACK:"; + os << jack_port_name(port); + break; + case PortDescriptor::LONG_NAME: + os << jack_port_name(port); + if (flags & PortDescriptor::INCLUDE_API) + os << " (JACK)"; + break; + case PortDescriptor::SHORT_NAME: + default: + os << jack_port_short_name(port); + if (flags & PortDescriptor::INCLUDE_API) + os << " (JACK)"; + break; + } + return os.str(); + } + + int getPortCapabilities(jack_port_t * port) { + if (!port) return 0; + const char * type = jack_port_type(port); + if (strcmp(type,JACK_DEFAULT_MIDI_TYPE)) return 0; + int flags = jack_port_flags(port); + int retval = 0; + /* a JACK input port is capable of handling output to it and vice versa */ + if (flags & JackPortIsInput) + retval |= PortDescriptor::OUTPUT; + if (flags & JackPortIsOutput) + retval |= PortDescriptor::INPUT; + + return retval; + } + +#if 0 + int getNextClient(snd_seq_client_info_t * cinfo ) { + init(); + scoped_lock lock (mutex); + return snd_seq_query_next_client (client, cinfo); + } + int getNextPort(snd_seq_port_info_t * pinfo ) { + init(); + scoped_lock lock (mutex); + return snd_seq_query_next_port (client, pinfo); + } +#endif + + jack_port_t * createPort (const std::string & portName, unsigned long portOptions) { + init(); + scoped_lock lock (mutex); + return jack_port_register(client, + portName.c_str(), + JACK_DEFAULT_MIDI_TYPE, + portOptions, + 0); + } + + void deletePort(jack_port_t * port) { + init(); + scoped_lock lock (mutex); + jack_port_unregister( client, port ); + } + + void connectPorts(jack_port_t * from, + jack_port_t * to) + { + init(); + jack_connect( client, + jack_port_name( from ), + jack_port_name( to ) ); + } + + void closePort(jack_port_t * from, + jack_port_t * to) + { + init(); + jack_disconnect( client, + jack_port_name( from ), + jack_port_name( to ) ); + } + +#if 0 + void startQueue(int queue_id) { + init(); + scoped_lock lock(mutex); + snd_seq_start_queue( client, queue_id, NULL ); + snd_seq_drain_output( client ); + } +#endif + + /*! Use JackSequencer like a C pointer. + \note This function breaks the design to control thread safety + by the selection of the \ref locking parameter to the class. + It should be removed as soon as possible in order ensure the + thread policy that has been intended by creating this class. + */ + operator jack_client_t * () + { + return client; + } + protected: + struct scoped_lock { + pthread_mutex_t * mutex; + scoped_lock(pthread_mutex_t & m): mutex(&m) + { + if (locking) + pthread_mutex_lock(mutex); + } + ~scoped_lock() + { + if (locking) + pthread_mutex_unlock(mutex); + } + }; + pthread_mutex_t mutex; + jack_client_t * client; + std::string name; + JackMidiData * data; + +#if 0 + snd_seq_client_info_t * GetClient(int id) { + init(); + snd_seq_client_info_t * cinfo; + scoped_lock lock(mutex); + snd_seq_get_any_client_info(client,id,cinfo); + return cinfo; + } +#endif + + void init() + { + init (client,false); + } + + void init(jack_client_t * &c, bool isoutput) + { + if (c) return; + { + scoped_lock lock(mutex); + if (( client = jack_client_open( name.c_str(), + JackNoStartServer, + NULL )) == 0) { + throw Error("JackSequencer::init: Could not connect to JACK server. Is it runnig?", + Error::WARNING); + return; + } + + if (isoutput && data) { + jack_set_process_callback( client, jackProcessOut, data ); + } else if (data) + jack_set_process_callback( client, jackProcessIn, data ); + jack_activate( client ); + } + } + }; + typedef JackSequencer<1> LockingJackSequencer; + typedef JackSequencer<0> NonLockingJackSequencer; + + struct JackPortDescriptor:public PortDescriptor + { + MidiApi * api; + static LockingJackSequencer seq; + JackPortDescriptor(const std::string & name):api(0),clientName(name) + { + port = 0; + } + JackPortDescriptor(const char * portname, const std::string & name):api(0),clientName(name) + { + port = seq.getPort(portname); + seq.setName(name); + } + JackPortDescriptor(jack_port_t * other, + const std::string & name):api(0), + clientName(name) + { + port = other; + seq.setName(name); + } + JackPortDescriptor(JackPortDescriptor & other, + const std::string & name):api(0), + clientName(name) + { + port = other.port; + seq.setName(name); + } + ~JackPortDescriptor() + { + } + MidiInApi * getInputApi(unsigned int queueSizeLimit = 100) { + if (getCapabilities() & INPUT) + return new MidiInJack(clientName,queueSizeLimit); + else + return 0; + } + MidiOutApi * getOutputApi() { + if (getCapabilities() & OUTPUT) + return new MidiOutJack(clientName); + else + return 0; + } + + + std::string getName(int flags = SHORT_NAME | UNIQUE_NAME) { + return seq.getPortName(port,flags); + } + + const std::string & getClientName() { + return clientName; + } + int getCapabilities() { + return seq.getPortCapabilities(port); + } + static PortList getPortList(int capabilities, const std::string & clientName); + + operator jack_port_t * () const { return port; } + + protected: + std::string clientName; + jack_port_t * port; + + friend struct JackMidiData; + }; + + LockingJackSequencer JackPortDescriptor::seq; + + + + PortList JackPortDescriptor :: getPortList(int capabilities, const std::string & clientName) + { + PortList list; + unsigned long flags = 0; + + if (capabilities & INPUT) { + flags |= JackPortIsOutput; + } + if (capabilities & OUTPUT) { + flags |= JackPortIsInput; + } + const char ** ports = seq.getPortList(flags); + if (!ports) return list; + for (const char ** port = ports; *port; port++) { + list.push_back(new JackPortDescriptor(*port, clientName)); + } + jack_free(ports); + return list; + } + + /*! A structure to hold variables related to the JACK API + implementation. + + \note After all sequencer handling is covered by the \ref + JackSequencer class, we should make seq to be a pointer in order + to allow a common client implementation. + */ + + struct JackMidiData:public JackPortDescriptor { + jack_port_t * local; jack_ringbuffer_t *buffSize; jack_ringbuffer_t *buffMessage; jack_time_t lastTime; MidiInApi :: MidiInData *rtMidiIn; + NonLockingJackSequencer seq; + + /* + JackMidiData():seq() + { + init(); + } + */ + JackMidiData(const std::string &clientName, + MidiInApi :: MidiInData &inputData_):JackPortDescriptor(clientName), + local(0), + buffSize(0), + buffMessage(0), + lastTime(0), + rtMidiIn(&inputData_), + seq(clientName,false,this) + { + } + + /** + * Create output midi data. + * + * \param clientName + * + * \return + */ + JackMidiData(const std::string &clientName):JackPortDescriptor(clientName), + local(0), + buffSize(jack_ringbuffer_create( JACK_RINGBUFFER_SIZE )), + buffMessage(jack_ringbuffer_create( JACK_RINGBUFFER_SIZE )), + lastTime(0), + rtMidiIn(), + seq(clientName,true,this) + {} + + + ~JackMidiData() + { + if (local) + deletePort(); + if (buffSize) + jack_ringbuffer_free( buffSize ); + if (buffMessage) + jack_ringbuffer_free( buffMessage ); + } + + + + + void setRemote(jack_port_t * remote) { + port = remote; + } + + void connectPorts(jack_port_t * from, + jack_port_t * to) { + seq.connectPorts(from, to); + } + + int openPort(unsigned long jackCapabilities, + const std::string & portName) { + local = seq.createPort(portName, jackCapabilities); + if (!local) { + api->error( Error::DRIVER_ERROR, + "MidiInJack::openPort: JACK error opening port subscription." ); + return -99; + } + return 0; + } + + void deletePort() { + seq.deletePort(local); + local = 0; + } + + void closePort(bool output_is_remote) { + if (output_is_remote) { + seq.closePort( local, port ); + } else { + seq.closePort( port, local ); + } + port = 0; + } + + operator jack_port_t * () const { return port; } }; + + //*********************************************************************// // API: JACK // Class Definitions: MidiInJack @@ -4132,8 +4549,8 @@ namespace rtmidi { jack_time_t time; // Is port created? - if ( jData->port == NULL ) return 0; - void *buff = jack_port_get_buffer( jData->port, nframes ); + if ( jData->local == NULL ) return 0; + void *buff = jack_port_get_buffer( jData->local, nframes ); // We have midi events in buffer int evCount = jack_midi_get_event_count( buff ); @@ -4184,25 +4601,22 @@ namespace rtmidi { void MidiInJack :: initialize( const std::string& clientName ) { - JackMidiData *data = new JackMidiData; + JackMidiData *data = new JackMidiData(clientName,inputData_); apiData_ = (void *) data; - - data->rtMidiIn = &inputData_; - data->port = NULL; - data->client = NULL; this->clientName = clientName; - - connect(); } +#if 0 void MidiInJack :: connect() { + abort(); + // this should be unnecessary JackMidiData *data = static_cast (apiData_); - if ( data->client ) + if ( data->local ) return; // Initialize JACK client - if (( data->client = jack_client_open( clientName.c_str(), JackNoStartServer, NULL )) == 0) { + if (( data->local = jack_client_open( clientName.c_str(), JackNoStartServer, NULL )) == 0) { errorString_ = "MidiInJack::initialize: JACK server not running?"; error( Error::WARNING, errorString_ ); return; @@ -4211,29 +4625,32 @@ namespace rtmidi { jack_set_process_callback( data->client, jackProcessIn, data ); jack_activate( data->client ); } +#endif MidiInJack :: ~MidiInJack() { JackMidiData *data = static_cast (apiData_); closePort(); +#if 0 if ( data->client ) jack_client_close( data->client ); +#endif delete data; } - void MidiInJack :: openPort( unsigned int portNumber, const std::string portName ) + void MidiInJack :: openPort( unsigned int portNumber, const std::string & portName ) { JackMidiData *data = static_cast (apiData_); - connect(); + // connect(); // Creating new port - if ( data->port == NULL) - data->port = jack_port_register( data->client, portName.c_str(), - JACK_DEFAULT_MIDI_TYPE, JackPortIsInput, 0 ); + if ( data->local == NULL) + data->local = jack_port_register( data->seq, portName.c_str(), + JACK_DEFAULT_MIDI_TYPE, JackPortIsInput, 0 ); - if ( data->port == NULL) { + if ( data->local == NULL) { errorString_ = "MidiInJack::openPort: JACK error creating port"; error( Error::DRIVER_ERROR, errorString_ ); return; @@ -4241,34 +4658,107 @@ namespace rtmidi { // Connecting to the output std::string name = getPortName( portNumber ); - jack_connect( data->client, name.c_str(), jack_port_name( data->port ) ); + jack_connect( data->seq, name.c_str(), jack_port_name( data->local ) ); } void MidiInJack :: openVirtualPort( const std::string portName ) { JackMidiData *data = static_cast (apiData_); + // connect(); + if ( data->local == NULL ) + data->local = jack_port_register( data->seq, portName.c_str(), + JACK_DEFAULT_MIDI_TYPE, JackPortIsInput, 0 ); + + if ( data->local == NULL ) { + errorString_ = "MidiInJack::openVirtualPort: JACK error creating virtual port"; + error( Error::DRIVER_ERROR, errorString_ ); + } + } + + void MidiInJack :: openPort( const PortDescriptor & p, + const std::string & portName ) + { + JackMidiData *data = static_cast (apiData_); + const JackPortDescriptor * port = dynamic_cast(&p); + + if ( !data ) { + errorString_ = "MidiInAlsa::openPort: Internal error: data has not been allocated!"; + error( Error::DRIVER_ERROR, errorString_ ); + return; + } +#if 0 + if ( connected_ ) { + errorString_ = "MidiInAlsa::openPort: a valid connection already exists!"; + error( Error::WARNING, errorString_ ); + return; + } +#endif + if (!port) { + errorString_ = "MidiInAlsa::openPort: an invalid (i.e. non-ALSA) port descriptor has been passed to openPort!"; + error( Error::WARNING, errorString_ ); + return; + } + + if (!data->local) + data->openPort (JackPortIsInput, + portName); + data->setRemote(*port); + data->connectPorts(*port,data->local); + +#if 0 + connect(); - if ( data->port == NULL ) + + // Creating new port + if ( data->port == NULL) data->port = jack_port_register( data->client, portName.c_str(), JACK_DEFAULT_MIDI_TYPE, JackPortIsInput, 0 ); - if ( data->port == NULL ) { - errorString_ = "MidiInJack::openVirtualPort: JACK error creating virtual port"; + if ( data->port == NULL) { + errorString_ = "MidiInJack::openPort: JACK error creating port"; error( Error::DRIVER_ERROR, errorString_ ); + return; } + + // Connecting to the output + std::string name = getPortName( portNumber ); + jack_connect( data->client, name.c_str(), jack_port_name( data->port ) ); +#endif + } + + Pointer MidiInJack :: getDescriptor(bool local) + { + JackMidiData *data = static_cast (apiData_); + if (local) { + if (data && data->local) { + return new JackPortDescriptor(data->local,data->getClientName()); + } + } else { + if (data && *data) { + return new JackPortDescriptor(*data,data->getClientName()); + } + } + return NULL; + } + + PortList MidiInJack :: getPortList(int capabilities) + { + JackMidiData *data = static_cast (apiData_); + return JackPortDescriptor::getPortList(capabilities | PortDescriptor::INPUT, + data->getClientName()); } unsigned int MidiInJack :: getPortCount() { int count = 0; + // connect(); JackMidiData *data = static_cast (apiData_); - connect(); - if ( !data->client ) + if ( !(data->seq) ) return 0; // List of available ports - const char **ports = jack_get_ports( data->client, NULL, JACK_DEFAULT_MIDI_TYPE, JackPortIsOutput ); + const char **ports = jack_get_ports( data->seq, NULL, JACK_DEFAULT_MIDI_TYPE, JackPortIsOutput ); if ( ports == NULL ) return 0; while ( ports[count] != NULL ) @@ -4284,10 +4774,10 @@ namespace rtmidi { JackMidiData *data = static_cast (apiData_); std::string retStr(""); - connect(); + // connect(); // List of available ports - const char **ports = jack_get_ports( data->client, NULL, + const char **ports = jack_get_ports( data->seq, NULL, JACK_DEFAULT_MIDI_TYPE, JackPortIsOutput ); // Check port validity @@ -4313,9 +4803,9 @@ namespace rtmidi { { JackMidiData *data = static_cast (apiData_); - if ( data->port == NULL ) return; - jack_port_unregister( data->client, data->port ); - data->port = NULL; + if ( data->local == NULL ) return; + jack_port_unregister( data->seq, data->local ); + data->local = NULL; } //*********************************************************************// @@ -4331,9 +4821,9 @@ namespace rtmidi { int space; // Is port created? - if ( data->port == NULL ) return 0; + if ( data->local == NULL ) return 0; - void *buff = jack_port_get_buffer( data->port, nframes ); + void *buff = jack_port_get_buffer( data->local, nframes ); jack_midi_clear_buffer( buff ); while ( jack_ringbuffer_read_space( data->buffSize ) > 0 ) { @@ -4353,24 +4843,23 @@ namespace rtmidi { void MidiOutJack :: initialize( const std::string& clientName ) { - JackMidiData *data = new JackMidiData; + JackMidiData *data = new JackMidiData(clientName); apiData_ = (void *) data; - - data->port = NULL; - data->client = NULL; this->clientName = clientName; - connect(); + // connect(); } void MidiOutJack :: connect() { + abort(); +#if 0 JackMidiData *data = static_cast (apiData_); - if ( data->client ) + if ( data->seq ) return; // Initialize JACK client - if (( data->client = jack_client_open( clientName.c_str(), JackNoStartServer, NULL )) == 0) { + if (( data->seq = jack_client_open( clientName.c_str(), JackNoStartServer, NULL )) == 0) { errorString_ = "MidiOutJack::initialize: JACK server not running?"; error( Error::WARNING, errorString_ ); return; @@ -4380,6 +4869,7 @@ namespace rtmidi { data->buffSize = jack_ringbuffer_create( JACK_RINGBUFFER_SIZE ); data->buffMessage = jack_ringbuffer_create( JACK_RINGBUFFER_SIZE ); jack_activate( data->client ); +#endif } MidiOutJack :: ~MidiOutJack() @@ -4387,28 +4877,30 @@ namespace rtmidi { JackMidiData *data = static_cast (apiData_); closePort(); - if ( data->client ) { +#if 0 + if ( data->seq ) { // Cleanup jack_client_close( data->client ); jack_ringbuffer_free( data->buffSize ); jack_ringbuffer_free( data->buffMessage ); } +#endif delete data; } - void MidiOutJack :: openPort( unsigned int portNumber, const std::string portName ) + void MidiOutJack :: openPort( unsigned int portNumber, const std::string & portName ) { JackMidiData *data = static_cast (apiData_); - connect(); + // connect(); // Creating new port - if ( data->port == NULL ) - data->port = jack_port_register( data->client, portName.c_str(), - JACK_DEFAULT_MIDI_TYPE, JackPortIsOutput, 0 ); + if ( data->local == NULL ) + data->local = jack_port_register( data->seq, portName.c_str(), + JACK_DEFAULT_MIDI_TYPE, JackPortIsOutput, 0 ); - if ( data->port == NULL ) { + if ( data->local == NULL ) { errorString_ = "MidiOutJack::openPort: JACK error creating port"; error( Error::DRIVER_ERROR, errorString_ ); return; @@ -4416,34 +4908,107 @@ namespace rtmidi { // Connecting to the output std::string name = getPortName( portNumber ); - jack_connect( data->client, jack_port_name( data->port ), name.c_str() ); + jack_connect( data->seq, jack_port_name( data->local ), name.c_str() ); } void MidiOutJack :: openVirtualPort( const std::string portName ) { JackMidiData *data = static_cast (apiData_); + // connect(); + if ( data->local == NULL ) + data->local = jack_port_register( data->seq, portName.c_str(), + JACK_DEFAULT_MIDI_TYPE, JackPortIsOutput, 0 ); + + if ( data->local == NULL ) { + errorString_ = "MidiOutJack::openVirtualPort: JACK error creating virtual port"; + error( Error::DRIVER_ERROR, errorString_ ); + } + } + + void MidiOutJack :: openPort( const PortDescriptor & p, + const std::string & portName ) + { + JackMidiData *data = static_cast (apiData_); + const JackPortDescriptor * port = dynamic_cast(&p); + + if ( !data ) { + errorString_ = "MidiInAlsa::openPort: Internal error: data has not been allocated!"; + error( Error::DRIVER_ERROR, errorString_ ); + return; + } +#if 0 + if ( connected_ ) { + errorString_ = "MidiInAlsa::openPort: a valid connection already exists!"; + error( Error::WARNING, errorString_ ); + return; + } +#endif + if (!port) { + errorString_ = "MidiInAlsa::openPort: an invalid (i.e. non-ALSA) port descriptor has been passed to openPort!"; + error( Error::WARNING, errorString_ ); + return; + } + + if (!data->local) + data->openPort (JackPortIsOutput, + portName); + data->setRemote(*port); + data->connectPorts(data->local,*port); + +#if 0 + connect(); - if ( data->port == NULL ) + + // Creating new port + if ( data->port == NULL) data->port = jack_port_register( data->client, portName.c_str(), - JACK_DEFAULT_MIDI_TYPE, JackPortIsOutput, 0 ); + JACK_DEFAULT_MIDI_TYPE, JackPortIsInput, 0 ); - if ( data->port == NULL ) { - errorString_ = "MidiOutJack::openVirtualPort: JACK error creating virtual port"; + if ( data->port == NULL) { + errorString_ = "MidiOutJack::openPort: JACK error creating port"; error( Error::DRIVER_ERROR, errorString_ ); + return; + } + + // Connecting to the output + std::string name = getPortName( portNumber ); + jack_connect( data->client, name.c_str(), jack_port_name( data->port ) ); +#endif + } + + Pointer MidiOutJack :: getDescriptor(bool local) + { + JackMidiData *data = static_cast (apiData_); + if (local) { + if (data && data->local) { + return new JackPortDescriptor(data->local,data->getClientName()); + } + } else { + if (data && *data) { + return new JackPortDescriptor(*data,data->getClientName()); + } } + return NULL; + } + + PortList MidiOutJack :: getPortList(int capabilities) + { + JackMidiData *data = static_cast (apiData_); + return JackPortDescriptor::getPortList(capabilities | PortDescriptor::OUTPUT, + data->getClientName()); } unsigned int MidiOutJack :: getPortCount() { int count = 0; JackMidiData *data = static_cast (apiData_); - connect(); - if ( !data->client ) + // connect(); + if ( !data->seq ) return 0; // List of available ports - const char **ports = jack_get_ports( data->client, NULL, + const char **ports = jack_get_ports( data->seq, NULL, JACK_DEFAULT_MIDI_TYPE, JackPortIsInput ); if ( ports == NULL ) return 0; @@ -4460,10 +5025,10 @@ namespace rtmidi { JackMidiData *data = static_cast (apiData_); std::string retStr(""); - connect(); + // connect(); // List of available ports - const char **ports = jack_get_ports( data->client, NULL, + const char **ports = jack_get_ports( data->seq, NULL, JACK_DEFAULT_MIDI_TYPE, JackPortIsInput ); // Check port validity @@ -4489,19 +5054,19 @@ namespace rtmidi { { JackMidiData *data = static_cast (apiData_); - if ( data->port == NULL ) return; - jack_port_unregister( data->client, data->port ); - data->port = NULL; + if ( data->local == NULL ) return; + jack_port_unregister( data->seq, data->local ); + data->local = NULL; } - void MidiOutJack :: sendMessage( std::vector *message ) + void MidiOutJack :: sendMessage( std::vector &message ) { - int nBytes = message->size(); + int nBytes = message.size(); JackMidiData *data = static_cast (apiData_); // Write full message to buffer - jack_ringbuffer_write( data->buffMessage, ( const char * ) &( *message )[0], - message->size() ); + jack_ringbuffer_write( data->buffMessage, ( const char * ) &( message[0] ), + message.size() ); jack_ringbuffer_write( data->buffSize, ( char * ) &nBytes, sizeof( nBytes ) ); } } diff --git a/RtMidi.h b/RtMidi.h index aa05d38d..f49cbb89 100644 --- a/RtMidi.h +++ b/RtMidi.h @@ -1055,7 +1055,7 @@ namespace rtmidi { public: MidiInJack( const std::string clientName, unsigned int queueSizeLimit ); ~MidiInJack( void ); - ApiType getCurrentApi( void ) { return UNIX_JACK; }; + ApiType getCurrentApi( void ) throw() { return UNIX_JACK; }; void openPort( unsigned int portNumber, const std::string & portName ); void openVirtualPort( const std::string portName ); void openPort( const PortDescriptor & port, const std::string & portName); @@ -1077,7 +1077,7 @@ namespace rtmidi { public: MidiOutJack( const std::string clientName ); ~MidiOutJack( void ); - ApiType getCurrentApi( void ) { return UNIX_JACK; }; + ApiType getCurrentApi( void ) throw() { return UNIX_JACK; }; void openPort( unsigned int portNumber, const std::string & portName ); void openVirtualPort( const std::string portName ); void openPort( const PortDescriptor & port, const std::string & portName); diff --git a/configure.ac b/configure.ac index f4f497aa..e0361195 100644 --- a/configure.ac +++ b/configure.ac @@ -68,6 +68,13 @@ case $host in api="$api -D__UNIX_JACK__" AC_MSG_RESULT(using JACK) AC_CHECK_LIB(jack, jack_client_open, , AC_MSG_ERROR(JACK support requires the jack library!))], ) + AC_LANG_PUSH(C++) + AC_TRY_COMPILE([ +#include + ],[ +return jack_port_uuid(NULL); + ],api="$api -D__UNIX_JACK_HAS_UUID__") + AC_LANG_POP(C++) # Look for ALSA flag AC_ARG_WITH(alsa, [ --with-alsa = choose native ALSA sequencer API support (linux only)], [ @@ -92,6 +99,13 @@ case $host in api="$api -D__UNIX_JACK__" AC_MSG_RESULT(using JACK) AC_CHECK_LIB(jack, jack_client_open, , AC_MSG_ERROR(JACK support requires the jack library!))], ) + AC_LANG_PUSH(C++) + AC_TRY_COMPILE([ +#include + ],[ +return jack_port_uuid(NULL); + ],api="$api -D__UNIX_JACK_HAS_UUID__") + AC_LANG_POP(C++) # Look for Core flag AC_ARG_WITH(core, [ --with-core = choose CoreMidi API support (mac only)], [ From f9cd8fa994f4c5f4b68d18ecb12edf9159a531de Mon Sep 17 00:00:00 2001 From: Tobias Schlemmer Date: Sun, 13 Apr 2014 22:09:07 +0200 Subject: [PATCH 36/45] Fix checking for the length of the gool. --- tests/loopback.cpp | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/tests/loopback.cpp b/tests/loopback.cpp index 9ce6464d..2ddefd92 100644 --- a/tests/loopback.cpp +++ b/tests/loopback.cpp @@ -31,6 +31,13 @@ std::vector instring; const char * instringgoal = "\xc0\x6\xf1\x3d\xb0\x8\x64\x90\x41\x5a\x80\x41\x28\xb0\x8\x28\xf0\x43\x4\x3\x3\xf7"; +inline size_t getlength(const char * messages) { + size_t retval = 0; + const unsigned char * c = reinterpret_cast(messages); + while (*(c++) != 0xf7) retval++; + return ++retval; +} + void mycallback1( double deltatime, std::vector< unsigned char > *message, void * /* userData */ ) { unsigned int nBytes = message->size(); @@ -175,12 +182,24 @@ int main( int argc, char */*argv*/[] ) } const unsigned char * goal = reinterpret_cast(instringgoal); size_t i; - for (i = 0 ; i < instring.size() && goal[i] ; i++) + std::cout << "Virtual output -> input:" << std::endl; + if (instring.size() != getlength(instringgoal)) abort(); + for (i = 0 ; i < instring.size() && goal[i] ; i++){ + std::cout << " " << std::hex << (int) instring[i]; + std::cout << "/" << std::hex << (int) goal[i] << std::flush; if (instring[i] != goal[i]) abort(); + } + std::cout << std::endl; if (i != instring.size()) abort(); goal = reinterpret_cast(virtualinstringgoal); - for (i = 0 ; i < virtualinstring.size() && goal[i] ; i++) + std::cout << "Output -> virtual input:" << std::endl; + if (instring.size() != getlength(virtualinstringgoal)) abort(); + for (i = 0 ; i < virtualinstring.size() && goal[i] ; i++) { + std::cout << " " << std::hex << (int) virtualinstring[i]; + std::cout << "/" << std::hex << (int) goal[i] << std::flush; if (virtualinstring[i] != goal[i]) abort(); + } + std::cout << std::endl; if (i != virtualinstring.size()) abort(); } catch ( RtMidiError &error ) { From 9a6f98e7d832b8e0249c78826a87966f0b860cf7 Mon Sep 17 00:00:00 2001 From: Tobias Schlemmer Date: Sun, 13 Apr 2014 22:19:08 +0200 Subject: [PATCH 37/45] Really show output ports to the user in midiout2. --- tests/midiout2.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/midiout2.cpp b/tests/midiout2.cpp index 5d09b97d..bf45a266 100644 --- a/tests/midiout2.cpp +++ b/tests/midiout2.cpp @@ -121,7 +121,7 @@ bool chooseMidiPort( RtMidiOut &midi ) } std::string portName; - rtmidi::PortList list = midi.getPortList(rtmidi::PortDescriptor::INPUT); + rtmidi::PortList list = midi.getPortList(rtmidi::PortDescriptor::OUTPUT); if ( list.empty() ) { std::cout << "No output ports available!" << std::endl; return false; From 45edd5916a7c3af114210bd9642f5af1b7d5953f Mon Sep 17 00:00:00 2001 From: Tobias Schlemmer Date: Sun, 13 Apr 2014 23:14:00 +0200 Subject: [PATCH 38/45] Flush the output queue when a JACK client connection is going to be closed. --- RtMidi.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/RtMidi.cpp b/RtMidi.cpp index 459e41c2..4f2fd4b2 100644 --- a/RtMidi.cpp +++ b/RtMidi.cpp @@ -4143,8 +4143,11 @@ namespace rtmidi { { { scoped_lock lock (mutex); - if (client) + if (client) { + jack_deactivate (client); + // the latter doesn't flush the queue jack_client_close (client); + } } if (locking) { pthread_mutex_destroy(&mutex); From 34e475eed1f57a8657d5c6a4591ab1cda9bb706f Mon Sep 17 00:00:00 2001 From: Tobias Schlemmer Date: Sun, 13 Apr 2014 23:15:11 +0200 Subject: [PATCH 39/45] Update midiout2 provides a virtual output port (not input port) ;-) --- tests/midiout2.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/midiout2.cpp b/tests/midiout2.cpp index bf45a266..068e7cb2 100644 --- a/tests/midiout2.cpp +++ b/tests/midiout2.cpp @@ -108,7 +108,7 @@ int main( int /* argc*/, char */*argv*/[] ) bool chooseMidiPort( RtMidiOut &midi ) { - std::cout << "\nWould you like to open a virtual input port? [y/N] "; + std::cout << "\nWould you like to open a virtual output port? [y/N] "; std::string keyHit; std::getline( std::cin, keyHit ); From c77b94bf1e04cfc8d08cd2d6b933fd85c6ea2a09 Mon Sep 17 00:00:00 2001 From: Tobias Schlemmer Date: Thu, 1 May 2014 22:00:55 +0200 Subject: [PATCH 40/45] Implement the new API for CoreMidi. --- RtMidi.cpp | 1308 +++++++++++++++++++++++++++++++++++++++++++++------- RtMidi.h | 4 +- 2 files changed, 1132 insertions(+), 180 deletions(-) diff --git a/RtMidi.cpp b/RtMidi.cpp index 4f2fd4b2..ef2ae052 100644 --- a/RtMidi.cpp +++ b/RtMidi.cpp @@ -418,13 +418,984 @@ namespace rtmidi { namespace rtmidi { + /*! An abstraction layer for the CORE sequencer layer. It provides + the following functionality: + - dynamic allocation of the sequencer + - optionallay avoid concurrent access to the CORE sequencer, + which is not thread proof. This feature is controlled by + the parameter \ref locking. + */ + + // This function was submitted by Douglas Casey Tucker and apparently + // derived largely from PortMidi. + // or copied from the Apple developer Q&A website + // https://developer.apple.com/library/mac/qa/qa1374/_index.html + + CFStringRef EndpointName( MIDIEndpointRef endpoint, bool isExternal ) + { + CFMutableStringRef result = CFStringCreateMutable( NULL, 0 ); + CFStringRef str; + + // Begin with the endpoint's name. + str = NULL; + MIDIObjectGetStringProperty( endpoint, kMIDIPropertyName, &str ); + if ( str != NULL ) { + CFStringAppend( result, str ); + CFRelease( str ); + } + + MIDIEntityRef entity = 0; + MIDIEndpointGetEntity( endpoint, &entity ); + if ( entity == 0 ) + // probably virtual + return result; + + if ( CFStringGetLength( result ) == 0 ) { + // endpoint name has zero length -- try the entity + str = NULL; + MIDIObjectGetStringProperty( entity, kMIDIPropertyName, &str ); + if ( str != NULL ) { + CFStringAppend( result, str ); + CFRelease( str ); + } + } + // now consider the device's name + MIDIDeviceRef device = 0; + MIDIEntityGetDevice( entity, &device ); + if ( device == 0 ) + return result; + + str = NULL; + MIDIObjectGetStringProperty( device, kMIDIPropertyName, &str ); + if ( CFStringGetLength( result ) == 0 ) { + CFRelease( result ); + return str; + } + if ( str != NULL ) { + // if an external device has only one entity, throw away + // the endpoint name and just use the device name + if ( isExternal && MIDIDeviceGetNumberOfEntities( device ) < 2 ) { + CFRelease( result ); + return str; + } else { + if ( CFStringGetLength( str ) == 0 ) { + CFRelease( str ); + return result; + } + // does the entity name already start with the device name? + // (some drivers do this though they shouldn't) + // if so, do not prepend + if ( CFStringCompareWithOptions( result, /* endpoint name */ + str /* device name */, + CFRangeMake(0, CFStringGetLength( str ) ), 0 ) != kCFCompareEqualTo ) { + // prepend the device name to the entity name + if ( CFStringGetLength( result ) > 0 ) + CFStringInsert( result, 0, CFSTR(" ") ); + CFStringInsert( result, 0, str ); + } + CFRelease( str ); + } + } + return result; + } + + // This function was submitted by Douglas Casey Tucker and apparently + // derived largely from PortMidi. + // Nearly the same text can be found in the Apple Q&A qa1374: + // https://developer.apple.com/library/mac/qa/qa1374/_index.html + static CFStringRef ConnectedEndpointName( MIDIEndpointRef endpoint ) + { + CFMutableStringRef result = CFStringCreateMutable( NULL, 0 ); + CFStringRef str; + OSStatus err; + int i; + + // Does the endpoint have connections? + CFDataRef connections = NULL; + int nConnected = 0; + bool anyStrings = false; + err = MIDIObjectGetDataProperty( endpoint, kMIDIPropertyConnectionUniqueID, &connections ); + if ( connections != NULL ) { + // It has connections, follow them + // Concatenate the names of all connected devices + nConnected = CFDataGetLength( connections ) / sizeof(MIDIUniqueID); + if ( nConnected ) { + const SInt32 *pid = (const SInt32 *)(CFDataGetBytePtr(connections)); + for ( i=0; i + class CoreSequencer { + public: + CoreSequencer():seq(0) + { + if (locking) { + pthread_mutexattr_t attr; + pthread_mutexattr_init(&attr); + pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_NORMAL); + pthread_mutex_init(&mutex, &attr); + } + } + + CoreSequencer(const std::string & n):seq(0),name(n) + { + if (locking) { + pthread_mutexattr_t attr; + pthread_mutexattr_init(&attr); + pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_NORMAL); + pthread_mutex_init(&mutex, &attr); + } + init(); + } + + ~CoreSequencer() + { + if (seq) { + scoped_lock lock(mutex); + MIDIClientDispose(seq); + seq = 0; + } + if (locking) { + pthread_mutex_destroy(&mutex); + } + } + + bool setName(const std::string & n) { + /* we don't want to rename the client after opening it. */ + if (seq) return false; + name = n; + return true; + } + + static std::string str(CFStringRef s) { + const char * cstr = + CFStringGetCStringPtr(s,kCFStringEncodingUTF8); + if (cstr) return cstr; + + CFIndex len = CFStringGetLength(s); + std::string retval; + retval.resize(CFStringGetMaximumSizeForEncoding(len, + kCFStringEncodingUTF8)+1); + CFStringGetBytes(s, + CFRangeMake(0, len), + kCFStringEncodingUTF8, + 0, + false, + reinterpret_cast(&retval[0]), + retval.size()-1, + &len); + retval.resize(len); + return retval; + } + + +#if 0 +// Obtain the name of an endpoint, following connections. + +// The result should be released by the caller. + + static CFStringRef CreateConnectedEndpointName(MIDIEndpointRef endpoint) + { + CFMutableStringRef result = CFStringCreateMutable(NULL, 0); + CFStringRef str; + OSStatus err; + + + // Does the endpoint have connections? + CFDataRef connections = NULL; + int nConnected = 0; + bool anyStrings = false; + err = MIDIObjectGetDataProperty(endpoint, kMIDIPropertyConnectionUniqueID, &connections); + if (connections != NULL) { + // It has connections, follow them + // Concatenate the names of all connected devices + nConnected = CFDataGetLength(connections) / sizeof(MIDIUniqueID); + + if (nConnected) { + const SInt32 *pid = reinterpret_cast(CFDataGetBytePtr(connections)); + for (int i = 0; i < nConnected; ++i, ++pid) { + MIDIUniqueID id = EndianS32_BtoN(*pid); + MIDIObjectRef connObject; + MIDIObjectType connObjectType; + err = MIDIObjectFindByUniqueID(id, &connObject, &connObjectType); + if (err == noErr) { + if (connObjectType == kMIDIObjectType_ExternalSource || + connObjectType == kMIDIObjectType_ExternalDestination) { + // Connected to an external device's endpoint (10.3 and later). + str = EndpointName(static_cast(connObject), true); + } else { + // Connected to an external device (10.2) (or something else, catch-all) + str = NULL; + MIDIObjectGetStringProperty(connObject, kMIDIPropertyName, &str); + } + + if (str != NULL) { + if (anyStrings) + CFStringAppend(result, CFSTR(", ")); + else anyStrings = true; + CFStringAppend(result, str); + CFRelease(str); + } + } + } + } + CFRelease(connections); + } + + + if (anyStrings) + return result; + else + CFRelease(result); + + // Here, either the endpoint had no connections, or we failed to obtain names for any of them. + return CreateEndpointName(endpoint, false); + } + + + +////////////////////////////////////// + +// Obtain the name of an endpoint without regard for whether it has connections. + +// The result should be released by the caller. + + static CFStringRef CreateEndpointName(MIDIEndpointRef endpoint, bool isExternal) + { + CFMutableStringRef result = CFStringCreateMutable(NULL, 0); + CFStringRef str; + + // begin with the endpoint's name + str = NULL; + MIDIObjectGetStringProperty(endpoint, kMIDIPropertyName, &str); + if (str != NULL) { + CFStringAppend(result, str); + CFRelease(str); + } + + MIDIEntityRef entity = NULL; + MIDIEndpointGetEntity(endpoint, &entity); + if (entity == NULL) + // probably virtual + return result; + + if (CFStringGetLength(result) == 0) { + // endpoint name has zero length -- try the entity + str = NULL; + MIDIObjectGetStringProperty(entity, kMIDIPropertyName, &str); + if (str != NULL) { + CFStringAppend(result, str); + CFRelease(str); + } + } + + + + // now consider the device's name + MIDIDeviceRef device = NULL; + MIDIEntityGetDevice(entity, &device); + if (device == NULL) return result; + + str = NULL; + MIDIObjectGetStringProperty(device, kMIDIPropertyName, &str); + if (str != NULL) { + // if an external device has only one entity, throw away + // the endpoint name and just use the device name + if (isExternal && MIDIDeviceGetNumberOfEntities(device) < 2) { + CFRelease(result); + return str; + } else { + // does the entity name already start with the device name? + // (some drivers do this though they shouldn't) + // if so, do not prepend + + if (CFStringCompareWithOptions(str /* device name */, + result /* endpoint name */, + CFRangeMake(0, + CFStringGetLength(str)), + 0) + != kCFCompareEqualTo) { + // prepend the device name to the entity name + if (CFStringGetLength(result) > 0) + CFStringInsert(result, 0, CFSTR(" ")); + CFStringInsert(result, 0, str); + } + CFRelease(str); + } + } + + return result; + } +#endif + + static std::string getConnectionsString(MIDIEndpointRef port) + { + /* This function is derived from + CreateConnectedEndpointName at Apple Q&A */ + std::ostringstream result; + CFDataRef connections = NULL; + OSStatus err = MIDIObjectGetDataProperty(port, + kMIDIPropertyConnectionUniqueID, + &connections); + if (err != noErr) + return result.str(); + + if (!connections) + return result.str(); + CFIndex size = CFDataGetLength( connections ) / sizeof(MIDIUniqueID); + if (!size) { + CFRelease(connections); + return result.str(); + } + + CFStringRef strRef; + const SInt32 *pid + = reinterpret_cast(CFDataGetBytePtr(connections)); + bool anyStrings = false; + for (int i = 0; i < size; ++i, ++pid) { + MIDIUniqueID id = EndianS32_BtoN(*pid); + MIDIObjectRef connObject; + MIDIObjectType connObjectType; + err = MIDIObjectFindByUniqueID(id, &connObject, &connObjectType); + if (err != noErr) + continue; + + if (connObjectType == kMIDIObjectType_ExternalSource || + connObjectType == kMIDIObjectType_ExternalDestination) { + // Connected to an external + // device's endpoint + // (10.3 and later). + strRef = EndpointName(static_cast(connObject), + true); + } else { + // Connected to an external device + // (10.2) (or something else, catch-all) + strRef = NULL; + MIDIObjectGetStringProperty(connObject, + kMIDIPropertyName, &strRef); + } + + if (strRef != NULL) { + if (anyStrings) + result << ", "; + else anyStrings = true; + result << str(strRef); + CFRelease(strRef); + } + } + CFRelease(connections); + return result.str(); + } + + static std::string getPortName(MIDIEndpointRef port, int flags) { + std::string clientname; + std::string devicename; + std::string portname; + std::string entityname; + std::string externaldevicename; + std::string connections; + std::string recommendedname; +// bool isVirtual; + bool hasManyEndpoints = false; + CFStringRef nameRef; + MIDIObjectGetStringProperty(port, + kMIDIPropertyDisplayName, + &nameRef); + recommendedname = str(nameRef); + connections = getConnectionsString(port); + + MIDIObjectGetStringProperty(port, + kMIDIPropertyName, + &nameRef); + portname = str(nameRef); + CFRelease( nameRef ); + + MIDIEntityRef entity = NULL; + MIDIEndpointGetEntity(port, &entity); + // entity == NULL: probably virtual + if (entity != NULL) { + nameRef = NULL; + MIDIObjectGetStringProperty(entity, kMIDIPropertyName, &nameRef); + if (str != NULL) { + entityname = str(nameRef); + CFRelease(nameRef); + } + + // now consider the device's name + MIDIDeviceRef device = NULL; + MIDIEntityGetDevice(entity, &device); + if (device != NULL) { + hasManyEndpoints = MIDIDeviceGetNumberOfEntities(device) >= 2; + MIDIObjectGetStringProperty(device, + kMIDIPropertyName, + &nameRef); + devicename = str(nameRef); + CFRelease(nameRef); + } + // does the entity name already start with the device name? + // (some drivers do this though they shouldn't) + if (entityname.substr(0,devicename.length()) + == devicename) { + int start = devicename.length(); + while (isspace(entityname[start])) + start++; + entityname = entityname.substr(start); + } + } + + int naming = flags & PortDescriptor::NAMING_MASK; + + std::ostringstream os; + switch (naming) { + case PortDescriptor::SESSION_PATH: + if (flags & PortDescriptor::INCLUDE_API) + os << "CORE:"; + os << port; + break; + case PortDescriptor::STORAGE_PATH: + if (flags & PortDescriptor::INCLUDE_API) + os << "CORE:"; + os << clientname; + os << ":" << devicename; + os << ":" << portname; + os << ":" << entityname; + os << ":" << externaldevicename; + os << ":" << connections; + os << ":" << recommendedname; + if (flags & PortDescriptor::UNIQUE_NAME) + os << ";" << port; + break; + case PortDescriptor::LONG_NAME: + os << devicename; + if (hasManyEndpoints) { + if (!portname.empty()) { + os << ": "; + os << portname; + } else { + os << ": "; + os << entityname; + } + } + if (!connections.empty()) { + os << " ⇒ "; + os << connections; + } + if (flags & + (PortDescriptor::INCLUDE_API + | PortDescriptor::UNIQUE_NAME)) { + os << " ("; + if (flags & + PortDescriptor::INCLUDE_API) { + os << "CORE"; + if (flags & PortDescriptor::UNIQUE_NAME) + os << ":"; + } + if (flags & PortDescriptor::UNIQUE_NAME) { + os << port; + } + os << ")"; + } + break; + case PortDescriptor::SHORT_NAME: + default: + if (!recommendedname.empty()) { + os << recommendedname; + } else if (!connections.empty()) { + os << connections; + } else { + os << devicename; + if (hasManyEndpoints) { + if (!portname.empty()) { + os << portname; + } else { + os << entityname; + } + } + } + if (flags & + (PortDescriptor::INCLUDE_API + | PortDescriptor::UNIQUE_NAME)) { + os << " ("; + if (flags & + PortDescriptor::INCLUDE_API) { + os << "CORE"; + if (flags & PortDescriptor::UNIQUE_NAME) + os << ":"; + } + if (flags & PortDescriptor::UNIQUE_NAME) { + os << port; + } + os << ")"; + } + break; + } + return os.str(); + } + + int getPortCapabilities(MIDIEndpointRef port) { + int retval = 0; + MIDIEntityRef entity = 0; + OSStatus stat = + MIDIEndpointGetEntity(port,&entity); + if (stat == kMIDIObjectNotFound) { + // plan B for virtual ports + MIDIUniqueID uid; + stat = MIDIObjectGetIntegerProperty (port, + kMIDIPropertyUniqueID, + &uid); + if (stat != noErr) { + throw + Error("CoreSequencer::getPortCapabilties: \ +Could not get the UID of a midi endpoint.", + Error::DRIVER_ERROR); + return 0; + } + MIDIObjectRef obj; + MIDIObjectType type; + stat = MIDIObjectFindByUniqueID (uid, + &obj, + &type); + if (stat != noErr || obj != port) { + throw + Error("CoreSequencer::getPortCapabilties: \ +Could not get the endpoint back from UID of a midi endpoint.", + Error::DRIVER_ERROR); + return 0; + } + if (type == kMIDIObjectType_Source + || type == kMIDIObjectType_ExternalSource) + return PortDescriptor::INPUT; + else if (type == kMIDIObjectType_Destination + || type == kMIDIObjectType_ExternalDestination) + return PortDescriptor::OUTPUT; + else { + return 0; + } + + } else if (stat != noErr) { + throw + Error("CoreSequencer::getPortCapabilties: \ +Could not get the entity of a midi endpoint.", + Error::DRIVER_ERROR); + return 0; + } + /* Theoretically Mac OS X could silently use + the same endpoint reference for input and + output. We might benefit from this + behaviour. + \todo: Find a way to query the object + whether it can act as source or destination. + */ + ItemCount count = + MIDIEntityGetNumberOfDestinations(entity); + for (ItemCount i = 0; i < count ; i++) { + MIDIEndpointRef dest= + MIDIEntityGetDestination(entity,i); + if (dest == port) { + retval |= + PortDescriptor::OUTPUT; + break; + } + } + count = + MIDIEntityGetNumberOfSources(entity); + for (ItemCount i = 0; i < count ; i++) { + MIDIEndpointRef src= + MIDIEntityGetSource(entity,i); + if (src == port) { + retval |= + PortDescriptor::INPUT; + } + } + return retval; + } + +#if 0 + int getNextClient(snd_seq_client_info_t * cinfo ) { + init(); + scoped_lock lock (mutex); + return snd_seq_query_next_client (seq, cinfo); + } + int getNextPort(snd_seq_port_info_t * pinfo ) { + init(); + scoped_lock lock (mutex); + return snd_seq_query_next_port (seq, pinfo); + } +#endif + + MIDIPortRef createPort (std::string portName, + int flags, + MidiInApi::MidiInData * data = NULL) + { + init(); + scoped_lock lock (mutex); + MIDIPortRef port = 0; + OSStatus result; + switch (flags) { + case PortDescriptor::INPUT: + result = MIDIInputPortCreate(seq, + CFStringCreateWithCString( + NULL, + portName.c_str(), + kCFStringEncodingUTF8 ), + midiInputCallback, + (void *)data, + &port); + break; + case PortDescriptor::OUTPUT: + result + = MIDIOutputPortCreate(seq, + CFStringCreateWithCString( + NULL, + portName.c_str(), + kCFStringEncodingUTF8 ), + &port); + break; + default: + throw Error("CoreSequencer::createPort:\ + Error creating OS X MIDI port because of invalid port flags", + Error::DRIVER_ERROR); + } + if ( result != noErr ) { + throw Error( + "CoreSequencer::createPort:\ + error creating OS-X MIDI port.", + Error::DRIVER_ERROR); + } + return port; + } + + MIDIEndpointRef createVirtualPort (std::string portName, + int flags, + MidiInApi::MidiInData * data = NULL) + { + init(); + scoped_lock lock (mutex); + MIDIEndpointRef port = 0; + OSStatus result; + switch (flags) { + case PortDescriptor::INPUT: + result + = MIDIDestinationCreate(seq, + CFStringCreateWithCString( + NULL, + portName.c_str(), + kCFStringEncodingUTF8 ), + midiInputCallback, + (void *)data, + &port); + break; + case PortDescriptor::OUTPUT: + result + = MIDISourceCreate(seq, + CFStringCreateWithCString( + NULL, + portName.c_str(), + kCFStringEncodingUTF8 ), + &port); + break; + default: + throw Error(Error::DRIVER_ERROR, + "CoreSequencer::createVirtualPort:\ + Error creating OS X MIDI port because of invalid port flags"); + } + if ( result != noErr ) { + throw Error( Error::DRIVER_ERROR, + "CoreSequencer::createVirtualPort: error creating OS-X MIDI port." ); + } + return port; + } + +#if 0 + void deletePort(int port) { + init(); + scoped_lock lock (mutex); + snd_seq_delete_port( seq, port ); + } + + snd_seq_port_subscribe_t * connectPorts(const snd_seq_addr_t & from, + const snd_seq_addr_t & to, + bool real_time) { + init(); + snd_seq_port_subscribe_t *subscription; + + if (snd_seq_port_subscribe_malloc( &subscription ) < 0) { + throw Error("MidiInCore::openPort: CORE error allocation port subscription.", + Error::DRIVER_ERROR ); + return 0; + } + snd_seq_port_subscribe_set_sender(subscription, &from); + snd_seq_port_subscribe_set_dest(subscription, &to); + if (real_time) { + snd_seq_port_subscribe_set_time_update(subscription, 1); + snd_seq_port_subscribe_set_time_real(subscription, 1); + } + { + scoped_lock lock (mutex); + if ( snd_seq_subscribe_port(seq, subscription) ) { + snd_seq_port_subscribe_free( subscription ); + subscription = 0; + throw Error("MidiInCore::openPort: CORE error making port connection.", + Error::DRIVER_ERROR); + return 0; + } + } + return subscription; + } + + void closePort(snd_seq_port_subscribe_t * subscription ) { + init(); + scoped_lock lock(mutex); + snd_seq_unsubscribe_port( seq, subscription ); + } + + + void startQueue(int queue_id) { + init(); + scoped_lock lock(mutex); + snd_seq_start_queue( seq, queue_id, NULL ); + snd_seq_drain_output( seq ); + } +#endif + + /*! Use CoreSequencer like a C pointer. + \note This function breaks the design to control thread safety + by the selection of the \ref locking parameter to the class. + It should be removed as soon as possible in order ensure the + thread policy that has been intended by creating this class. + */ + operator MIDIClientRef () + { + return seq; + } + protected: + struct scoped_lock { + pthread_mutex_t * mutex; + scoped_lock(pthread_mutex_t & m): mutex(&m) + { + if (locking) + pthread_mutex_lock(mutex); + } + ~scoped_lock() + { + if (locking) + pthread_mutex_unlock(mutex); + } + }; + pthread_mutex_t mutex; + MIDIClientRef seq; + std::string name; + +#if 0 + snd_seq_client_info_t * GetClient(int id) { + init(); + snd_seq_client_info_t * cinfo; + scoped_lock lock(mutex); + snd_seq_get_any_client_info(seq,id,cinfo); + return cinfo; + } +#endif + + void init() + { + init (seq); + } + + void init(MIDIClientRef &s) + { + if (s) return; + { + scoped_lock lock(mutex); + OSStatus result = MIDIClientCreate( + CFStringCreateWithCString( NULL, + name.c_str(), + kCFStringEncodingUTF8), + NULL, NULL, &s ); + if ( result != noErr ) { + throw Error( + "CoreSequencer::initialize: \ +Error creating OS-X MIDI client object.", + Error::DRIVER_ERROR); + return; + } + } + } + }; + typedef CoreSequencer<1> LockingCoreSequencer; + typedef CoreSequencer<0> NonLockingCoreSequencer; + + struct CorePortDescriptor:public PortDescriptor { + CorePortDescriptor(const std::string & name):api(0), + clientName(name), + endpoint(0) + { + } + CorePortDescriptor(MIDIEndpointRef p, + const std::string & name):api(0), + clientName(name), + endpoint(p) + { + seq.setName(name); + } + CorePortDescriptor(CorePortDescriptor & + other):PortDescriptor(other), + api(other.api), + clientName(other.clientName), + endpoint(other.endpoint) + { + seq.setName(clientName); + } + ~CorePortDescriptor() {} + + MidiInApi * getInputApi(unsigned int queueSizeLimit = 100) { + if (getCapabilities() & INPUT) + return new MidiInCore(clientName,queueSizeLimit); + else + return 0; + } + + MidiOutApi * getOutputApi() { + if (getCapabilities() & OUTPUT) + return new MidiOutCore(clientName); + else + return 0; + } + + void setEndpoint(MIDIEndpointRef e) + { + endpoint = e; + } + MIDIEndpointRef getEndpoint() const + { + return endpoint; + } + + std::string getName(int flags = SHORT_NAME | UNIQUE_NAME) { + return seq.getPortName(endpoint,flags); + } + + const std::string & getClientName() { + return clientName; + } + int getCapabilities() { + if (!endpoint) return 0; + return seq.getPortCapabilities(endpoint); + } + static PortList getPortList(int capabilities, const std::string & clientName); + protected: + MidiApi * api; + static LockingCoreSequencer seq; + + std::string clientName; + MIDIEndpointRef endpoint; + }; + + LockingCoreSequencer CorePortDescriptor::seq; + + + + PortList CorePortDescriptor :: getPortList(int capabilities, const std::string & clientName) + { + PortList list; + + CFRunLoopRunInMode( kCFRunLoopDefaultMode, 0, false ); + int caps = capabilities & PortDescriptor::INOUTPUT; + bool unlimited = capabilities & PortDescriptor::UNLIMITED; + bool forceInput = PortDescriptor::INPUT & caps; + bool forceOutput = PortDescriptor::OUTPUT & caps; + bool allowOutput = forceOutput || !forceInput; + bool allowInput = forceInput || !forceOutput; + if (allowOutput) { + ItemCount count = + MIDIGetNumberOfDestinations(); + for (ItemCount i = 0 ; i < count; i++) { + MIDIEndpointRef destination = + MIDIGetDestination(i); + if ((seq.getPortCapabilities(destination) + & caps) == caps) + list.push_back(new CorePortDescriptor(destination, + clientName)); + } + // Combined sources and destinations + // should be both occur as destinations and as + // sources. So we have finished the search, here. + } else if (allowInput) { + ItemCount count = + MIDIGetNumberOfSources(); + for (ItemCount i = 0 ; i < count; i++) { + MIDIEndpointRef src = + MIDIGetSource(i); + if ((seq.getPortCapabilities(src) + & caps) == caps) + list.push_back(new CorePortDescriptor(src, + clientName)); + } + } + return list; + } + + // A structure to hold variables related to the CoreMIDI API // implementation. - struct CoreMidiData { - MIDIClientRef client; - MIDIPortRef port; - MIDIEndpointRef endpoint; - MIDIEndpointRef destinationId; + struct CoreMidiData:public CorePortDescriptor { + CoreMidiData(std::string clientname):CorePortDescriptor(clientname), + client(clientname), + localEndpoint(0), + localPort(0) {} + ~CoreMidiData() { + if (localEndpoint) + MIDIEndpointDispose(localEndpoint); + localEndpoint = 0; + } + + void openPort(const std::string & name, + int flags, + MidiInApi::MidiInData * data = NULL) { + localPort = client.createPort(name, flags, data); + } + + void setRemote(const CorePortDescriptor & remote) + { + setEndpoint(remote.getEndpoint()); + } + + NonLockingCoreSequencer client; + MIDIEndpointRef localEndpoint; + MIDIPortRef localPort; unsigned long long lastTime; MIDISysexSendRequest sysexreq; }; @@ -586,7 +1557,9 @@ namespace rtmidi { } } - MidiInCore :: MidiInCore( const std::string clientName, unsigned int queueSizeLimit ) : MidiInApi( queueSizeLimit ) + MidiInCore :: MidiInCore( const std::string clientName, + unsigned int queueSizeLimit ) : + MidiInApi( queueSizeLimit ) { initialize( clientName ); } @@ -598,31 +1571,19 @@ namespace rtmidi { // Cleanup. CoreMidiData *data = static_cast (apiData_); - MIDIClientDispose( data->client ); - if ( data->endpoint ) MIDIEndpointDispose( data->endpoint ); delete data; } void MidiInCore :: initialize( const std::string& clientName ) { - // Set up our client. - MIDIClientRef client; - OSStatus result = MIDIClientCreate( CFStringCreateWithCString( NULL, clientName.c_str(), kCFStringEncodingASCII ), NULL, NULL, &client ); - if ( result != noErr ) { - errorString_ = "MidiInCore::initialize: error creating OS-X MIDI client object."; - error( Error::DRIVER_ERROR, errorString_ ); - return; - } - // Save our api-specific connection information. - CoreMidiData *data = (CoreMidiData *) new CoreMidiData; - data->client = client; - data->endpoint = 0; + CoreMidiData *data = (CoreMidiData *) new CoreMidiData(clientName); apiData_ = (void *) data; inputData_.apiData = (void *) data; } - void MidiInCore :: openPort( unsigned int portNumber, const std::string portName ) + void MidiInCore :: openPort( unsigned int portNumber, + const std::string & portName ) { if ( connected_ ) { errorString_ = "MidiInCore::openPort: a valid connection already exists!"; @@ -649,7 +1610,7 @@ namespace rtmidi { MIDIPortRef port; CoreMidiData *data = static_cast (apiData_); OSStatus result = MIDIInputPortCreate( data->client, - CFStringCreateWithCString( NULL, portName.c_str(), kCFStringEncodingASCII ), + CFStringCreateWithCString( NULL, portName.c_str(), kCFStringEncodingUTF8 ), midiInputCallback, (void *)&inputData_, &port ); if ( result != noErr ) { MIDIClientDispose( data->client ); @@ -679,7 +1640,8 @@ namespace rtmidi { } // Save our api-specific port information. - data->port = port; + data->localPort = port; + data->setEndpoint(endpoint); connected_ = true; } @@ -691,7 +1653,7 @@ namespace rtmidi { // Create a virtual MIDI input destination. MIDIEndpointRef endpoint; OSStatus result = MIDIDestinationCreate( data->client, - CFStringCreateWithCString( NULL, portName.c_str(), kCFStringEncodingASCII ), + CFStringCreateWithCString( NULL, portName.c_str(), kCFStringEncodingUTF8 ), midiInputCallback, (void *)&inputData_, &endpoint ); if ( result != noErr ) { errorString_ = "MidiInCore::openVirtualPort: error creating virtual OS-X MIDI destination."; @@ -700,146 +1662,91 @@ namespace rtmidi { } // Save our api-specific connection information. - data->endpoint = endpoint; + data->localEndpoint = endpoint; } - void MidiInCore :: closePort( void ) + void MidiInCore :: openPort( const PortDescriptor & port, + const std::string & portName) { - if ( connected_ ) { - CoreMidiData *data = static_cast (apiData_); - MIDIPortDispose( data->port ); - connected_ = false; + CoreMidiData *data = static_cast (apiData_); + const CorePortDescriptor * remote = dynamic_cast(&port); + + if ( !data ) { + errorString_ = "MidiInCore::openPort: Internal error: data has not been allocated!"; + error( Error::DRIVER_ERROR, errorString_ ); + return; + } + if ( connected_ || data -> localEndpoint) { + errorString_ = "MidiInCore::openPort: a valid connection already exists!"; + error( Error::WARNING, errorString_ ); + return; + } + if (!remote) { + errorString_ = "MidiInCore::openPort: an invalid (i.e. non-CORE) port descriptor has been passed to openPort!"; + error( Error::WARNING, errorString_ ); + return; } - } - unsigned int MidiInCore :: getPortCount() - { - CFRunLoopRunInMode( kCFRunLoopDefaultMode, 0, false ); - return MIDIGetNumberOfSources(); + data->openPort (portName, + PortDescriptor::INPUT, + &inputData_); + data->setRemote(*remote); + OSStatus result = + MIDIPortConnectSource(data->localPort, + data->getEndpoint(), + NULL); + if ( result != noErr ) { + error(Error::DRIVER_ERROR, + "CoreSequencer::createPort:\ + error creating OS-X MIDI port."); + } + + connected_ = true; } - // This function was submitted by Douglas Casey Tucker and apparently - // derived largely from PortMidi. - CFStringRef EndpointName( MIDIEndpointRef endpoint, bool isExternal ) + Pointer MidiInCore :: getDescriptor(bool local) { - CFMutableStringRef result = CFStringCreateMutable( NULL, 0 ); - CFStringRef str; - - // Begin with the endpoint's name. - str = NULL; - MIDIObjectGetStringProperty( endpoint, kMIDIPropertyName, &str ); - if ( str != NULL ) { - CFStringAppend( result, str ); - CFRelease( str ); + CoreMidiData *data = static_cast + (apiData_); + if (!data) { + return NULL; } - - MIDIEntityRef entity = 0; - MIDIEndpointGetEntity( endpoint, &entity ); - if ( entity == 0 ) - // probably virtual - return result; - - if ( CFStringGetLength( result ) == 0 ) { - // endpoint name has zero length -- try the entity - str = NULL; - MIDIObjectGetStringProperty( entity, kMIDIPropertyName, &str ); - if ( str != NULL ) { - CFStringAppend( result, str ); - CFRelease( str ); + if (local) { + if (data && data->localEndpoint) { + return new + CorePortDescriptor(data->localEndpoint, + data->getClientName()); } - } - // now consider the device's name - MIDIDeviceRef device = 0; - MIDIEntityGetDevice( entity, &device ); - if ( device == 0 ) - return result; - - str = NULL; - MIDIObjectGetStringProperty( device, kMIDIPropertyName, &str ); - if ( CFStringGetLength( result ) == 0 ) { - CFRelease( result ); - return str; - } - if ( str != NULL ) { - // if an external device has only one entity, throw away - // the endpoint name and just use the device name - if ( isExternal && MIDIDeviceGetNumberOfEntities( device ) < 2 ) { - CFRelease( result ); - return str; - } else { - if ( CFStringGetLength( str ) == 0 ) { - CFRelease( str ); - return result; - } - // does the entity name already start with the device name? - // (some drivers do this though they shouldn't) - // if so, do not prepend - if ( CFStringCompareWithOptions( result, /* endpoint name */ - str /* device name */, - CFRangeMake(0, CFStringGetLength( str ) ), 0 ) != kCFCompareEqualTo ) { - // prepend the device name to the entity name - if ( CFStringGetLength( result ) > 0 ) - CFStringInsert( result, 0, CFSTR(" ") ); - CFStringInsert( result, 0, str ); - } - CFRelease( str ); + } else { + if (data->getEndpoint()) { + return new CorePortDescriptor(*data); } } - return result; + return NULL; } - // This function was submitted by Douglas Casey Tucker and apparently - // derived largely from PortMidi. - static CFStringRef ConnectedEndpointName( MIDIEndpointRef endpoint ) + PortList MidiInCore :: getPortList(int capabilities) { - CFMutableStringRef result = CFStringCreateMutable( NULL, 0 ); - CFStringRef str; - OSStatus err; - int i; + CoreMidiData *data = static_cast (apiData_); + return CorePortDescriptor::getPortList(capabilities | PortDescriptor::INPUT, + data->getClientName()); + } - // Does the endpoint have connections? - CFDataRef connections = NULL; - int nConnected = 0; - bool anyStrings = false; - err = MIDIObjectGetDataProperty( endpoint, kMIDIPropertyConnectionUniqueID, &connections ); - if ( connections != NULL ) { - // It has connections, follow them - // Concatenate the names of all connected devices - nConnected = CFDataGetLength( connections ) / sizeof(MIDIUniqueID); - if ( nConnected ) { - const SInt32 *pid = (const SInt32 *)(CFDataGetBytePtr(connections)); - for ( i=0; i (apiData_); + MIDIPortDispose( data->localPort ); + data->localPort = 0; + connected_ = false; } - if ( anyStrings ) - return result; + } - // Here, either the endpoint had no connections, or we failed to obtain names - return EndpointName( endpoint, false ); + unsigned int MidiInCore :: getPortCount() + { + CFRunLoopRunInMode( kCFRunLoopDefaultMode, 0, false ); + return MIDIGetNumberOfSources(); } std::string MidiInCore :: getPortName( unsigned int portNumber ) @@ -860,7 +1767,7 @@ namespace rtmidi { portRef = MIDIGetSource( portNumber ); nameRef = ConnectedEndpointName(portRef); - CFStringGetCString( nameRef, name, sizeof(name), CFStringGetSystemEncoding()); + CFStringGetCString( nameRef, name, sizeof(name), kCFStringEncodingUTF8); CFRelease( nameRef ); return stringName = name; @@ -883,26 +1790,13 @@ namespace rtmidi { // Cleanup. CoreMidiData *data = static_cast (apiData_); - MIDIClientDispose( data->client ); - if ( data->endpoint ) MIDIEndpointDispose( data->endpoint ); delete data; } void MidiOutCore :: initialize( const std::string& clientName ) { - // Set up our client. - MIDIClientRef client; - OSStatus result = MIDIClientCreate( CFStringCreateWithCString( NULL, clientName.c_str(), kCFStringEncodingASCII ), NULL, NULL, &client ); - if ( result != noErr ) { - errorString_ = "MidiOutCore::initialize: error creating OS-X MIDI client object."; - error( Error::DRIVER_ERROR, errorString_ ); - return; - } - // Save our api-specific connection information. - CoreMidiData *data = (CoreMidiData *) new CoreMidiData; - data->client = client; - data->endpoint = 0; + CoreMidiData *data = (CoreMidiData *) new CoreMidiData(clientName); apiData_ = (void *) data; } @@ -930,13 +1824,14 @@ namespace rtmidi { portRef = MIDIGetDestination( portNumber ); nameRef = ConnectedEndpointName(portRef); - CFStringGetCString( nameRef, name, sizeof(name), CFStringGetSystemEncoding()); + CFStringGetCString( nameRef, name, sizeof(name), kCFStringEncodingUTF8); CFRelease( nameRef ); return stringName = name; } - void MidiOutCore :: openPort( unsigned int portNumber, const std::string portName ) + void MidiOutCore :: openPort( unsigned int portNumber, + const std::string &portName ) { if ( connected_ ) { errorString_ = "MidiOutCore::openPort: a valid connection already exists!"; @@ -963,7 +1858,7 @@ namespace rtmidi { MIDIPortRef port; CoreMidiData *data = static_cast (apiData_); OSStatus result = MIDIOutputPortCreate( data->client, - CFStringCreateWithCString( NULL, portName.c_str(), kCFStringEncodingASCII ), + CFStringCreateWithCString( NULL, portName.c_str(), kCFStringEncodingUTF8 ), &port ); if ( result != noErr ) { MIDIClientDispose( data->client ); @@ -983,8 +1878,8 @@ namespace rtmidi { } // Save our api-specific connection information. - data->port = port; - data->destinationId = destination; + data->localPort = port; + data->setEndpoint(destination); connected_ = true; } @@ -992,7 +1887,7 @@ namespace rtmidi { { if ( connected_ ) { CoreMidiData *data = static_cast (apiData_); - MIDIPortDispose( data->port ); + MIDIPortDispose( data->localPort ); connected_ = false; } } @@ -1001,7 +1896,7 @@ namespace rtmidi { { CoreMidiData *data = static_cast (apiData_); - if ( data->endpoint ) { + if ( data->localEndpoint ) { errorString_ = "MidiOutCore::openVirtualPort: a virtual output port already exists!"; error( Error::WARNING, errorString_ ); return; @@ -1010,7 +1905,7 @@ namespace rtmidi { // Create a virtual MIDI output source. MIDIEndpointRef endpoint; OSStatus result = MIDISourceCreate( data->client, - CFStringCreateWithCString( NULL, portName.c_str(), kCFStringEncodingASCII ), + CFStringCreateWithCString( NULL, portName.c_str(), kCFStringEncodingUTF8 ), &endpoint ); if ( result != noErr ) { errorString_ = "MidiOutCore::initialize: error creating OS-X virtual MIDI source."; @@ -1019,9 +1914,66 @@ namespace rtmidi { } // Save our api-specific connection information. - data->endpoint = endpoint; + data->localEndpoint = endpoint; + } + + void MidiOutCore :: openPort( const PortDescriptor & port, + const std::string & portName) + { + CoreMidiData *data = static_cast (apiData_); + const CorePortDescriptor * remote = dynamic_cast(&port); + + if ( !data ) { + errorString_ = "MidiOutCore::openPort: Internal error: data has not been allocated!"; + error( Error::DRIVER_ERROR, errorString_ ); + return; + } + if ( connected_ || data -> localEndpoint) { + errorString_ = "MidiOutCore::openPort: a valid connection already exists!"; + error( Error::WARNING, errorString_ ); + return; + } + if (!remote) { + errorString_ = "MidiOutCore::openPort: an invalid (i.e. non-CORE) port descriptor has been passed to openPort!"; + error( Error::WARNING, errorString_ ); + return; + } + + data->openPort (portName, + PortDescriptor::OUTPUT); + data->setRemote(*remote); + connected_ = true; + } + + Pointer MidiOutCore :: getDescriptor(bool local) + { + CoreMidiData *data = static_cast + (apiData_); + if (!data) { + return NULL; + } + if (local) { + if (data && data->localEndpoint) { + return new + CorePortDescriptor(data->localEndpoint, + data->getClientName()); + } + } else { + if (data->getEndpoint()) { + return new CorePortDescriptor(*data); + } + } + return NULL; + } + + PortList MidiOutCore :: getPortList(int capabilities) + { + CoreMidiData *data = static_cast (apiData_); + return CorePortDescriptor::getPortList(capabilities | PortDescriptor::OUTPUT, + data->getClientName()); } + // Not necessary if we don't treat sysex messages any differently than // normal messages ... see below. //static void sysexCompletionProc( MIDISysexSendRequest *sreq ) @@ -1029,11 +1981,11 @@ namespace rtmidi { // free( sreq ); //} - void MidiOutCore :: sendMessage( std::vector *message ) + void MidiOutCore :: sendMessage( std::vector &message ) { // We use the MIDISendSysex() function to asynchronously send sysex // messages. Otherwise, we use a single CoreMidi MIDIPacket. - unsigned int nBytes = message->size(); + unsigned int nBytes = message.size(); if ( nBytes == 0 ) { errorString_ = "MidiOutCore::sendMessage: no data in message argument!"; error( Error::WARNING, errorString_ ); @@ -1051,7 +2003,7 @@ namespace rtmidi { // messages through the normal mechanism. In addition, this avoids // the problem of virtual ports not receiving sysex messages. - if ( message->at(0) == 0xF0 ) { + if ( message.at(0) == 0xF0 ) { // Apple's fantastic API requires us to free the allocated data in // the completion callback but trashes the pointer and size before @@ -1064,7 +2016,7 @@ namespace rtmidi { char * sysexBuffer = ((char *) newRequest) + sizeof(struct MIDISysexSendRequest); // Copy data to buffer. - for ( unsigned int i=0; iat(i); + for ( unsigned int i=0; idestination = data->destinationId; newRequest->data = (Byte *)sysexBuffer; @@ -1091,7 +2043,7 @@ namespace rtmidi { MIDIPacketList packetList; MIDIPacket *packet = MIDIPacketListInit( &packetList ); - packet = MIDIPacketListAdd( &packetList, sizeof(packetList), packet, timeStamp, nBytes, (const Byte *) &message->at( 0 ) ); + packet = MIDIPacketListAdd( &packetList, sizeof(packetList), packet, timeStamp, nBytes, (const Byte *) &message.at( 0 ) ); if ( !packet ) { errorString_ = "MidiOutCore::sendMessage: could not allocate packet list"; error( Error::DRIVER_ERROR, errorString_ ); @@ -1099,8 +2051,8 @@ namespace rtmidi { } // Send to any destinations that may have connected to us. - if ( data->endpoint ) { - result = MIDIReceived( data->endpoint, &packetList ); + if ( data->localEndpoint ) { + result = MIDIReceived( data->localEndpoint, &packetList ); if ( result != noErr ) { errorString_ = "MidiOutCore::sendMessage: error sending MIDI to virtual destinations."; error( Error::WARNING, errorString_ ); @@ -1109,7 +2061,7 @@ namespace rtmidi { // And send to an explicit destination port if we're connected. if ( connected_ ) { - result = MIDISend( data->port, data->destinationId, &packetList ); + result = MIDISend( data->localPort, data->getEndpoint(), &packetList ); if ( result != noErr ) { errorString_ = "MidiOutCore::sendMessage: error sending MIDI message to port."; error( Error::WARNING, errorString_ ); diff --git a/RtMidi.h b/RtMidi.h index f49cbb89..bafcc178 100644 --- a/RtMidi.h +++ b/RtMidi.h @@ -1012,7 +1012,7 @@ namespace rtmidi { public: MidiInCore( const std::string clientName, unsigned int queueSizeLimit ); ~MidiInCore( void ); - ApiType getCurrentApi( void ) { return MACOSX_CORE; }; + ApiType getCurrentApi( void ) throw() { return MACOSX_CORE; }; void openPort( unsigned int portNumber, const std::string & portName ); void openVirtualPort( const std::string portName ); void openPort( const PortDescriptor & port, const std::string & portName); @@ -1031,7 +1031,7 @@ namespace rtmidi { public: MidiOutCore( const std::string clientName ); ~MidiOutCore( void ); - ApiType getCurrentApi( void ) { return MACOSX_CORE; }; + ApiType getCurrentApi( void ) throw() { return MACOSX_CORE; }; void openPort( unsigned int portNumber, const std::string & portName ); void openVirtualPort( const std::string portName ); void openPort( const PortDescriptor & port, const std::string & portName); From cdbdab6eca7f196481884d63de209f65ee2516dc Mon Sep 17 00:00:00 2001 From: Tobias Schlemmer Date: Thu, 1 May 2014 22:01:49 +0200 Subject: [PATCH 41/45] Fix destructors of some sequencer classes. --- RtMidi.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/RtMidi.cpp b/RtMidi.cpp index ef2ae052..cdcfd2c8 100644 --- a/RtMidi.cpp +++ b/RtMidi.cpp @@ -2138,6 +2138,11 @@ namespace rtmidi { ~AlsaSequencer() { + if (seq) { + scoped_lock lock(mutex); + snd_seq_close(seq); + seq = 0; + } if (locking) { pthread_mutex_destroy(&mutex); } @@ -5099,6 +5104,7 @@ namespace rtmidi { jack_deactivate (client); // the latter doesn't flush the queue jack_client_close (client); + client = 0; } } if (locking) { From aa68f7434a7a390e78390be43e2f19ae7e49ce99 Mon Sep 17 00:00:00 2001 From: Tobias Schlemmer Date: Fri, 2 May 2014 07:59:23 +0200 Subject: [PATCH 42/45] Fix getPortName(PortDescriptor) for Core MIDI. --- RtMidi.cpp | 85 +++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 62 insertions(+), 23 deletions(-) diff --git a/RtMidi.cpp b/RtMidi.cpp index cdcfd2c8..03488a75 100644 --- a/RtMidi.cpp +++ b/RtMidi.cpp @@ -398,13 +398,31 @@ namespace rtmidi { { } - // *************************************************** // - // - // OS/API-specific methods. - // - // *************************************************** // + // trim from start + static inline std::string <rim(std::string &s) { + s.erase(s.begin(), std::find_if(s.begin(), s.end(), std::not1(std::ptr_fun(std::isspace)))); + return s; + } + + // trim from end + static inline std::string &rtrim(std::string &s) { + s.erase(std::find_if(s.rbegin(), s.rend(), std::not1(std::ptr_fun(std::isspace))).base(), s.end()); + return s; + } + + // trim from both ends + static inline std::string &trim(std::string &s) { + return ltrim(rtrim(s)); + } } + +// *************************************************** // +// +// OS/API-specific methods. +// +// *************************************************** // + #if defined(__MACOSX_CORE__) // The CoreMIDI API is based on the use of a callback function for @@ -619,7 +637,7 @@ namespace rtmidi { retval.size()-1, &len); retval.resize(len); - return retval; + return trim(retval); } @@ -822,14 +840,15 @@ namespace rtmidi { } static std::string getPortName(MIDIEndpointRef port, int flags) { - std::string clientname; +// std::string clientname; std::string devicename; std::string portname; std::string entityname; - std::string externaldevicename; +// std::string externaldevicename; std::string connections; std::string recommendedname; // bool isVirtual; + bool hasManyEntities = false; bool hasManyEndpoints = false; CFStringRef nameRef; MIDIObjectGetStringProperty(port, @@ -854,12 +873,16 @@ namespace rtmidi { entityname = str(nameRef); CFRelease(nameRef); } + hasManyEndpoints = + MIDIEntityGetNumberOfSources(entity) >= 2 || + MIDIEntityGetNumberOfDestinations(entity) + >= 2; // now consider the device's name MIDIDeviceRef device = NULL; MIDIEntityGetDevice(entity, &device); if (device != NULL) { - hasManyEndpoints = MIDIDeviceGetNumberOfEntities(device) >= 2; + hasManyEntities = MIDIDeviceGetNumberOfEntities(device) >= 2; MIDIObjectGetStringProperty(device, kMIDIPropertyName, &nameRef); @@ -880,6 +903,7 @@ namespace rtmidi { int naming = flags & PortDescriptor::NAMING_MASK; std::ostringstream os; + bool needcolon; switch (naming) { case PortDescriptor::SESSION_PATH: if (flags & PortDescriptor::INCLUDE_API) @@ -889,25 +913,34 @@ namespace rtmidi { case PortDescriptor::STORAGE_PATH: if (flags & PortDescriptor::INCLUDE_API) os << "CORE:"; - os << clientname; - os << ":" << devicename; + // os << clientname; + os << devicename; os << ":" << portname; os << ":" << entityname; - os << ":" << externaldevicename; +// os << ":" << externaldevicename; os << ":" << connections; - os << ":" << recommendedname; +// os << ":" << recommendedname; if (flags & PortDescriptor::UNIQUE_NAME) os << ";" << port; break; case PortDescriptor::LONG_NAME: + needcolon = !devicename.empty(); os << devicename; - if (hasManyEndpoints) { - if (!portname.empty()) { - os << ": "; - os << portname; - } else { - os << ": "; + if (hasManyEndpoints || + hasManyEntities || + devicename.empty()) { + if (!entityname.empty()) { + if (needcolon) + os << ": "; os << entityname; + needcolon = true; + } + if ((hasManyEndpoints + || entityname.empty()) + && !portname.empty()) { + if (needcolon) + os << ": "; + os << portname; } } if (!connections.empty()) { @@ -934,16 +967,22 @@ namespace rtmidi { default: if (!recommendedname.empty()) { os << recommendedname; - } else if (!connections.empty()) { + } else + if (!connections.empty()) { os << connections; } else { os << devicename; - if (hasManyEndpoints) { + if (hasManyEntities || + hasManyEndpoints || + devicename.empty()) { + if (!devicename.empty()) + os << " "; if (!portname.empty()) { os << portname; - } else { + } else if (!entityname.empty()) { os << entityname; - } + } else + os << "???"; } } if (flags & From 4d37c0dbfbe828bab285ba782a0e8068458f59d7 Mon Sep 17 00:00:00 2001 From: Tobias Schlemmer Date: Fri, 2 May 2014 08:00:10 +0200 Subject: [PATCH 43/45] Use "RtMidi virtual port" as default for virtual ports. --- RtMidi.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/RtMidi.h b/RtMidi.h index bafcc178..3bace5ab 100644 --- a/RtMidi.h +++ b/RtMidi.h @@ -359,7 +359,7 @@ namespace rtmidi { \param portName An optional name for the applicaction port that is used to connect to portId can be specified. */ - virtual void openVirtualPort( const std::string portName = std::string( "RtMidi" ) ) = 0; + virtual void openVirtualPort( const std::string portName = std::string( "RtMidi virtual port" ) ) = 0; //! Pure virtual function to open a MIDI connection given by enumeration number. /*! \param portNumber An optional port number greater than 0 @@ -617,7 +617,7 @@ namespace rtmidi { \param portName An optional name for the applicaction port that is used to connect to portId can be specified. */ - void openVirtualPort( const std::string portName = std::string( "RtMidi" ) ) + void openVirtualPort( const std::string portName = std::string( "RtMidi virtual port" ) ) { if (rtapi_) rtapi_->openVirtualPort(portName); } From 8623c322433420a4abf68b7bf6298eda0099ea0c Mon Sep 17 00:00:00 2001 From: Tobias Schlemmer Date: Fri, 2 May 2014 08:00:49 +0200 Subject: [PATCH 44/45] Make everything dependent on RtMidi.h --- tests/Makefile.in | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/Makefile.in b/tests/Makefile.in index bc8a728a..8498dfdd 100644 --- a/tests/Makefile.in +++ b/tests/Makefile.in @@ -21,6 +21,7 @@ LIBRARY = @LIBS@ all : $(PROGRAMS) +RtMidi.o: $(SRC_PATH)/RtMidi.cpp $(SRC_PATH)/RtMidi.h midiprobe : midiprobe.cpp $(OBJECTS) $(CC) $(CFLAGS) $(DEFS) -o midiprobe midiprobe.cpp $(OBJECT_PATH)/RtMidi.o $(LIBRARY) From b2ad3407b6f396bfde98cca5089dae964a7fa5fb Mon Sep 17 00:00:00 2001 From: Tobias Schlemmer Date: Fri, 2 May 2014 08:01:45 +0200 Subject: [PATCH 45/45] Improve the identification of virtual ports using Core MIDI. --- tests/cmidiin2.cpp | 2 +- tests/midiout2.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/cmidiin2.cpp b/tests/cmidiin2.cpp index 0d16eea9..cfd90942 100644 --- a/tests/cmidiin2.cpp +++ b/tests/cmidiin2.cpp @@ -71,7 +71,7 @@ bool chooseMidiPort( RtMidiIn &midi ) std::string keyHit; std::getline( std::cin, keyHit ); if ( keyHit == "y" ) { - midi.openVirtualPort(); + midi.openVirtualPort("RtMidi virtual input"); return true; } diff --git a/tests/midiout2.cpp b/tests/midiout2.cpp index 068e7cb2..af8a57a7 100644 --- a/tests/midiout2.cpp +++ b/tests/midiout2.cpp @@ -113,7 +113,7 @@ bool chooseMidiPort( RtMidiOut &midi ) std::string keyHit; std::getline( std::cin, keyHit ); if ( keyHit == "y" ) { - midi.openVirtualPort(); + midi.openVirtualPort("RtMidi virtual output"); std::cout << "Press return to start the transmission." << std::endl; std::getline( std::cin, keyHit );