Hi, You will never see interrupts, and you will not implement an ISR. thank god!^^ Can you see and instantiate the device in graphedt or ksstudio? No, I can only see the MIDI ports of my other MIDI devices, what do you mean by instantiate in this context? I had some odd behaviour on my virtual testing machine, whenever I change the name property of the AddService directive in my inf file, devcon and my own installer wouldn't install the driver anymore. Accordingly to MSDN, the name property can be chosen randomly, and it worked again after I have reverted my VM to an earlier state, but after that I couldn't change it again. Is that a sign for a problem with the driver? I have also attached the Filter Factory code for my driver, it should be here were something goes wrong. I have configured the Pins and dataranges accordingly to MSDN so they SHOULD be detected as MIDI pins and be visible to midiIn/Out functions. Regards, Max Date: Mon, 10 Jun 2013 10:33:49 -0700 From: timr@xxxxxxxxx To: wdmaudiodev@xxxxxxxxxxxxx Subject: [wdmaudiodev] Re: StartDevice Empty Resource List? Max K wrote: Over the last days, I have made huge progress in understanding KS and especially PortCls. I still can't however create a MIDI port that can be found using midiInGetDevCaps. I am probably missing something very important in correct startup of the driver. Can you see and instantiate the device in graphedt or ksstudio? Apparently, you don't necessarily need to have interfaces defined in your inf files. I looked at a couple of inf files of my midi keyboards here and none of them defines any interfaces (except one driver, which specifies his topology interface). That's true. KsInitializeDriver and KsCreateFilterFactory will both register the interfaces for you, based on the information you provide in your KSFILTER_DESCRIPTOR. I wonder, when a Midi Stream in the miniport is supposed to be created and by who. Will the OS call the newStream function when the driver is completely loaded or when a client connects to the midi port? Or do I need to create it in some kind of ISR? The system will do this when some client opens a MIDI port. I haven't worried too much about the Interrupts as it wasn't well documented in the audio section (the only thing I found there was how to notify the Port that a hardware interrupt was triggered) and the sample didn't seem to do very much in the ISRs. You are a virtual driver. There is no hardware. You will never see interrupts, and you will not implement an ISR. -- Tim Roberts, timr@xxxxxxxxx Providenza & Boekelheide, Inc.
#pragma code_seg("PAGE") /***************************************************************************** * PinDataRangesStreamLegacy * PinDataRangesStreamDMusic ***************************************************************************** * Structures indicating range of valid format values for live pins. */ static KSDATARANGE_MUSIC PinDataRangesStreamLegacy = { { sizeof(KSDATARANGE_MUSIC), 0, 0, 0, STATICGUIDOF(KSDATAFORMAT_TYPE_MUSIC), STATICGUIDOF(KSDATAFORMAT_SUBTYPE_MIDI), STATICGUIDOF(KSDATAFORMAT_SPECIFIER_NONE) }, STATICGUIDOF(KSMUSIC_TECHNOLOGY_PORT), 0, 0, 0xFFFF }; /***************************************************************************** * PinDataRangePointersStreamLegacy ***************************************************************************** * List of pointers to structures indicating range of valid format values * for live pins. */ static PKSDATARANGE PinDataRangePointersStreamLegacy[] = { PKSDATARANGE(&PinDataRangesStreamLegacy) }; /***************************************************************************** * SynthProperties ***************************************************************************** * List of properties in the Synth set. */ static PCPROPERTY_ITEM SynthProperties[] = { // Global: S/Get synthesizer caps { &KSPROPSETID_Synth, KSPROPERTY_SYNTH_CAPS, KSPROPERTY_TYPE_GET | KSPROPERTY_TYPE_BASICSUPPORT, PropertyHandler_Synth }, // Global: S/Get port parameters { &KSPROPSETID_Synth, KSPROPERTY_SYNTH_PORTPARAMETERS, KSPROPERTY_TYPE_GET | KSPROPERTY_TYPE_BASICSUPPORT, PropertyHandler_Synth }, // Per stream: S/Get channel groups { &KSPROPSETID_Synth, KSPROPERTY_SYNTH_CHANNELGROUPS, KSPROPERTY_TYPE_SET | KSPROPERTY_TYPE_GET | KSPROPERTY_TYPE_BASICSUPPORT, PropertyHandler_Synth }, // Per stream: Get current latency time { &KSPROPSETID_Synth, KSPROPERTY_SYNTH_LATENCYCLOCK, KSPROPERTY_TYPE_GET | KSPROPERTY_TYPE_BASICSUPPORT, PropertyHandler_Synth } }; DEFINE_PCAUTOMATION_TABLE_PROP(AutomationSynth, SynthProperties); #define kMaxNumCaptureStreams 1 #define kMaxNumLegacyRenderStreams 1 #define kMaxNumDMusicRenderStreams 1 /***************************************************************************** * MiniportPins ***************************************************************************** * List of pins. */ static PCPIN_DESCRIPTOR MiniportPins[] = { { kMaxNumLegacyRenderStreams,kMaxNumLegacyRenderStreams,0, // InstanceCount NULL, // AutomationTable { // KsPinDescriptor 0, // InterfacesCount NULL, // Interfaces 0, // MediumsCount NULL, // Mediums SIZEOF_ARRAY(PinDataRangePointersStreamLegacy), // DataRangesCount PinDataRangePointersStreamLegacy, // DataRanges KSPIN_DATAFLOW_IN, // DataFlow KSPIN_COMMUNICATION_SINK, // Communication (GUID *) &KSCATEGORY_AUDIO, // Category &KSAUDFNAME_DMUSIC_MPU_IN, // Name 0 // Reserved } }, { kMaxNumCaptureStreams,kMaxNumCaptureStreams,0, // InstanceCount NULL, // AutomationTable { // KsPinDescriptor 0, // InterfacesCount NULL, // Interfaces 0, // MediumsCount NULL, // Mediums SIZEOF_ARRAY(PinDataRangePointersStreamLegacy), // DataRangesCount PinDataRangePointersStreamLegacy, // DataRanges KSPIN_DATAFLOW_OUT, // DataFlow KSPIN_COMMUNICATION_SINK, // Communication (GUID *) &KSCATEGORY_AUDIO, // Category &KSAUDFNAME_DMUSIC_MPU_OUT, // Name 0 // Reserved } } }; /***************************************************************************** * MiniportNodes ***************************************************************************** * List of nodes. */ #define CONST_PCNODE_DESCRIPTOR(n) { 0, NULL, &n, NULL } #define CONST_PCNODE_DESCRIPTOR_AUTO(n,a) { 0, &a, &n, NULL } static PCNODE_DESCRIPTOR MiniportNodes[] = { CONST_PCNODE_DESCRIPTOR_AUTO(KSNODETYPE_SYNTHESIZER, AutomationSynth) }; /***************************************************************************** * MiniportConnections ***************************************************************************** * List of connections. */ enum { LegacyInputPin = 0, DmusInputPin, OutputPin }; static PCCONNECTION_DESCRIPTOR MiniportConnections[] = { { PCFILTER_NODE, LegacyInputPin, eSynthNode, KSNODEPIN_STANDARD_IN }, { eSynthNode, KSNODEPIN_STANDARD_OUT, PCFILTER_NODE, OutputPin } }; /***************************************************************************** * MiniportCategories ***************************************************************************** * List of categories. */ static GUID MiniportCategories[] = { STATICGUIDOF(KSCATEGORY_AUDIO), STATICGUIDOF(KSCATEGORY_RENDER), STATICGUIDOF(KSCATEGORY_CAPTURE) }; /***************************************************************************** * MiniportFilterDescriptor ***************************************************************************** * Complete miniport filter description. */ static PCFILTER_DESCRIPTOR MiniportFilterDescriptor = { 0, // Version NULL, // AutomationTable sizeof(PCPIN_DESCRIPTOR), // PinSize SIZEOF_ARRAY(MiniportPins), // PinCount MiniportPins, // Pins sizeof(PCNODE_DESCRIPTOR), // NodeSize SIZEOF_ARRAY(MiniportNodes), // NodeCount MiniportNodes, // Nodes SIZEOF_ARRAY(MiniportConnections), // ConnectionCount MiniportConnections, // Connections SIZEOF_ARRAY(MiniportCategories), // CategoryCount MiniportCategories // Categories };