Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenmidi.c
Go to the documentation of this file.
00001 /* 00002 * COPYRIGHT: See COPYING in the top level directory 00003 * PROJECT: ReactOS Kernel Streaming 00004 * FILE: lib/drivers/sound/mmixer/midi.c 00005 * PURPOSE: Midi Support Functions 00006 * PROGRAMMER: Johannes Anderwald 00007 */ 00008 00009 #include "priv.h" 00010 00011 MIXER_STATUS 00012 MMixerGetPinDataFlowAndCommunication( 00013 IN PMIXER_CONTEXT MixerContext, 00014 IN HANDLE hDevice, 00015 IN ULONG PinId, 00016 OUT PKSPIN_DATAFLOW DataFlow, 00017 OUT PKSPIN_COMMUNICATION Communication) 00018 { 00019 KSP_PIN Pin; 00020 ULONG BytesReturned; 00021 MIXER_STATUS Status; 00022 00023 /* setup request */ 00024 Pin.PinId = PinId; 00025 Pin.Reserved = 0; 00026 Pin.Property.Flags = KSPROPERTY_TYPE_GET; 00027 Pin.Property.Id = KSPROPERTY_PIN_DATAFLOW; 00028 Pin.Property.Set = KSPROPSETID_Pin; 00029 00030 /* get pin dataflow */ 00031 Status = MixerContext->Control(hDevice, IOCTL_KS_PROPERTY, (PVOID)&Pin, sizeof(KSP_PIN), (PVOID)DataFlow, sizeof(KSPIN_DATAFLOW), &BytesReturned); 00032 if (Status != MM_STATUS_SUCCESS) 00033 { 00034 /* failed to retrieve dataflow */ 00035 return Status; 00036 } 00037 00038 /* setup communication request */ 00039 Pin.Property.Id = KSPROPERTY_PIN_COMMUNICATION; 00040 00041 /* get pin communication */ 00042 Status = MixerContext->Control(hDevice, IOCTL_KS_PROPERTY, (PVOID)&Pin, sizeof(KSP_PIN), (PVOID)Communication, sizeof(KSPIN_COMMUNICATION), &BytesReturned); 00043 00044 return Status; 00045 } 00046 00047 MIXER_STATUS 00048 MMixerAddMidiPin( 00049 IN PMIXER_CONTEXT MixerContext, 00050 IN PMIXER_LIST MixerList, 00051 IN ULONG DeviceId, 00052 IN ULONG PinId, 00053 IN ULONG bInput, 00054 IN LPWSTR DeviceName) 00055 { 00056 LPMIDI_INFO MidiInfo; 00057 00058 /* allocate midi info */ 00059 MidiInfo = MixerContext->Alloc(sizeof(MIDI_INFO)); 00060 00061 if (!MidiInfo) 00062 { 00063 /* no memory */ 00064 return MM_STATUS_NO_MEMORY; 00065 } 00066 00067 /* initialize midi info */ 00068 MidiInfo->DeviceId = DeviceId; 00069 MidiInfo->PinId = PinId; 00070 00071 /* sanity check */ 00072 ASSERT(wcslen(DeviceName) + 1 < MAXPNAMELEN); 00073 00074 /* copy device name */ 00075 if (bInput && DeviceName) 00076 { 00077 wcscpy(MidiInfo->u.InCaps.szPname, DeviceName); 00078 } 00079 else if (!bInput && DeviceName) 00080 { 00081 wcscpy(MidiInfo->u.OutCaps.szPname, DeviceName); 00082 } 00083 00084 /* FIXME determine manufacturer / product id */ 00085 if (bInput) 00086 { 00087 MidiInfo->u.InCaps.dwSupport = 0; 00088 MidiInfo->u.InCaps.wMid = MM_MICROSOFT; 00089 MidiInfo->u.InCaps.wPid = MM_PID_UNMAPPED; 00090 MidiInfo->u.InCaps.vDriverVersion = 1; 00091 } 00092 else 00093 { 00094 MidiInfo->u.OutCaps.dwSupport = 0; 00095 MidiInfo->u.OutCaps.wMid = MM_MICROSOFT; 00096 MidiInfo->u.OutCaps.wPid = MM_PID_UNMAPPED; 00097 MidiInfo->u.OutCaps.vDriverVersion = 1; 00098 } 00099 00100 if (bInput) 00101 { 00102 /* insert into list */ 00103 InsertTailList(&MixerList->MidiInList, &MidiInfo->Entry); 00104 MixerList->MidiInListCount++; 00105 } 00106 else 00107 { 00108 /* insert into list */ 00109 InsertTailList(&MixerList->MidiOutList, &MidiInfo->Entry); 00110 MixerList->MidiOutListCount++; 00111 } 00112 00113 return MM_STATUS_SUCCESS; 00114 } 00115 00116 VOID 00117 MMixerCheckFilterPinMidiSupport( 00118 IN PMIXER_CONTEXT MixerContext, 00119 IN PMIXER_LIST MixerList, 00120 IN LPMIXER_DATA MixerData, 00121 IN ULONG PinId, 00122 IN PKSMULTIPLE_ITEM MultipleItem, 00123 IN LPWSTR szPname) 00124 { 00125 ULONG Index; 00126 PKSDATARANGE DataRange; 00127 KSPIN_COMMUNICATION Communication; 00128 KSPIN_DATAFLOW DataFlow; 00129 00130 /* get first datarange */ 00131 DataRange = (PKSDATARANGE)(MultipleItem + 1); 00132 00133 /* alignment assert */ 00134 ASSERT(((ULONG_PTR)DataRange & 0x7) == 0); 00135 00136 /* iterate through all data ranges */ 00137 for(Index = 0; Index < MultipleItem->Count; Index++) 00138 { 00139 if (IsEqualGUIDAligned(&DataRange->MajorFormat, &KSDATAFORMAT_TYPE_MUSIC) && 00140 IsEqualGUIDAligned(&DataRange->SubFormat, &KSDATAFORMAT_SUBTYPE_MIDI) && 00141 IsEqualGUIDAligned(&DataRange->Specifier, &KSDATAFORMAT_SPECIFIER_NONE)) 00142 { 00143 /* pin supports midi datarange */ 00144 if (MMixerGetPinDataFlowAndCommunication(MixerContext, MixerData->hDevice, PinId, &DataFlow, &Communication) == MM_STATUS_SUCCESS) 00145 { 00146 if (DataFlow == KSPIN_DATAFLOW_IN && Communication == KSPIN_COMMUNICATION_SINK) 00147 { 00148 MMixerAddMidiPin(MixerContext, MixerList, MixerData->DeviceId, PinId, FALSE, szPname); 00149 } 00150 else if (DataFlow == KSPIN_DATAFLOW_OUT && Communication == KSPIN_COMMUNICATION_SOURCE) 00151 { 00152 MMixerAddMidiPin(MixerContext, MixerList, MixerData->DeviceId, PinId, TRUE, szPname); 00153 } 00154 } 00155 } 00156 00157 /* move to next datarange */ 00158 DataRange = (PKSDATARANGE)((ULONG_PTR)DataRange + DataRange->FormatSize); 00159 00160 /* alignment assert */ 00161 ASSERT(((ULONG_PTR)DataRange & 0x7) == 0); 00162 00163 /* data ranges are 64-bit aligned */ 00164 DataRange = (PVOID)(((ULONG_PTR)DataRange + 0x7) & ~0x7); 00165 } 00166 } 00167 00168 VOID 00169 MMixerInitializeMidiForFilter( 00170 IN PMIXER_CONTEXT MixerContext, 00171 IN PMIXER_LIST MixerList, 00172 IN LPMIXER_DATA MixerData, 00173 IN PTOPOLOGY Topology) 00174 { 00175 ULONG PinCount, Index; 00176 MIXER_STATUS Status; 00177 PKSMULTIPLE_ITEM MultipleItem; 00178 WCHAR szPname[MAXPNAMELEN]; 00179 00180 /* get filter pin count */ 00181 MMixerGetTopologyPinCount(Topology, &PinCount); 00182 00183 /* get mixer name */ 00184 if (MMixerGetDeviceName(MixerContext, szPname, MixerData->hDeviceInterfaceKey) != MM_STATUS_SUCCESS) 00185 { 00186 /* clear name */ 00187 szPname[0] = 0; 00188 } 00189 00190 /* iterate all pins and check for KSDATARANGE_MUSIC support */ 00191 for(Index = 0; Index < PinCount; Index++) 00192 { 00193 /* get audio pin data ranges */ 00194 Status = MMixerGetAudioPinDataRanges(MixerContext, MixerData->hDevice, Index, &MultipleItem); 00195 00196 /* check for success */ 00197 if (Status == MM_STATUS_SUCCESS) 00198 { 00199 /* check if there is support KSDATARANGE_MUSIC */ 00200 MMixerCheckFilterPinMidiSupport(MixerContext, MixerList, MixerData, Index, MultipleItem, szPname); 00201 } 00202 } 00203 } 00204 00205 MIXER_STATUS 00206 MMixerOpenMidiPin( 00207 IN PMIXER_CONTEXT MixerContext, 00208 IN PMIXER_LIST MixerList, 00209 IN ULONG DeviceId, 00210 IN ULONG PinId, 00211 IN ACCESS_MASK DesiredAccess, 00212 IN PIN_CREATE_CALLBACK CreateCallback, 00213 IN PVOID Context, 00214 OUT PHANDLE PinHandle) 00215 { 00216 PKSPIN_CONNECT PinConnect; 00217 PKSDATAFORMAT DataFormat; 00218 LPMIXER_DATA MixerData; 00219 NTSTATUS Status; 00220 MIXER_STATUS MixerStatus; 00221 00222 MixerData = MMixerGetDataByDeviceId(MixerList, DeviceId); 00223 if (!MixerData) 00224 return MM_STATUS_INVALID_PARAMETER; 00225 00226 /* allocate pin connect */ 00227 PinConnect = MMixerAllocatePinConnect(MixerContext, sizeof(KSDATAFORMAT)); 00228 if (!PinConnect) 00229 { 00230 /* no memory */ 00231 return MM_STATUS_NO_MEMORY; 00232 } 00233 00234 /* initialize pin connect struct */ 00235 MMixerInitializePinConnect(PinConnect, PinId); 00236 00237 /* get offset to dataformat */ 00238 DataFormat = (PKSDATAFORMAT) (PinConnect + 1); 00239 00240 /* initialize data format */ 00241 RtlMoveMemory(&DataFormat->MajorFormat, &KSDATAFORMAT_TYPE_MUSIC, sizeof(GUID)); 00242 RtlMoveMemory(&DataFormat->SubFormat, &KSDATAFORMAT_SUBTYPE_MIDI, sizeof(GUID)); 00243 RtlMoveMemory(&DataFormat->Specifier, &KSDATAFORMAT_SPECIFIER_NONE, sizeof(GUID)); 00244 00245 if (CreateCallback) 00246 { 00247 /* let the callback handle the creation */ 00248 MixerStatus = CreateCallback(Context, DeviceId, PinId, MixerData->hDevice, PinConnect, DesiredAccess, PinHandle); 00249 } 00250 else 00251 { 00252 /* now create the pin */ 00253 Status = KsCreatePin(MixerData->hDevice, PinConnect, DesiredAccess, PinHandle); 00254 00255 /* normalize status */ 00256 if (Status == STATUS_SUCCESS) 00257 MixerStatus = MM_STATUS_SUCCESS; 00258 else 00259 MixerStatus = MM_STATUS_UNSUCCESSFUL; 00260 } 00261 00262 /* free create info */ 00263 MixerContext->Free(PinConnect); 00264 00265 /* done */ 00266 return MixerStatus; 00267 } 00268 00269 MIXER_STATUS 00270 MMixerGetMidiInfoByIndexAndType( 00271 IN PMIXER_LIST MixerList, 00272 IN ULONG DeviceIndex, 00273 IN ULONG bMidiInputType, 00274 OUT LPMIDI_INFO *OutMidiInfo) 00275 { 00276 ULONG Index = 0; 00277 PLIST_ENTRY Entry, ListHead; 00278 LPMIDI_INFO MidiInfo; 00279 00280 if (bMidiInputType) 00281 ListHead = &MixerList->MidiInList; 00282 else 00283 ListHead = &MixerList->MidiOutList; 00284 00285 /* get first entry */ 00286 Entry = ListHead->Flink; 00287 00288 while(Entry != ListHead) 00289 { 00290 MidiInfo = (LPMIDI_INFO)CONTAINING_RECORD(Entry, MIDI_INFO, Entry); 00291 00292 if (Index == DeviceIndex) 00293 { 00294 *OutMidiInfo = MidiInfo; 00295 return MM_STATUS_SUCCESS; 00296 } 00297 Index++; 00298 Entry = Entry->Flink; 00299 } 00300 00301 return MM_STATUS_INVALID_PARAMETER; 00302 } 00303 00304 MIXER_STATUS 00305 MMixerMidiOutCapabilities( 00306 IN PMIXER_CONTEXT MixerContext, 00307 IN ULONG DeviceIndex, 00308 OUT LPMIDIOUTCAPSW Caps) 00309 { 00310 PMIXER_LIST MixerList; 00311 MIXER_STATUS Status; 00312 LPMIDI_INFO MidiInfo; 00313 00314 /* verify mixer context */ 00315 Status = MMixerVerifyContext(MixerContext); 00316 00317 if (Status != MM_STATUS_SUCCESS) 00318 { 00319 /* invalid context passed */ 00320 return Status; 00321 } 00322 00323 /* grab mixer list */ 00324 MixerList = (PMIXER_LIST)MixerContext->MixerContext; 00325 00326 /* find destination midi */ 00327 Status = MMixerGetMidiInfoByIndexAndType(MixerList, DeviceIndex, FALSE, &MidiInfo); 00328 if (Status != MM_STATUS_SUCCESS) 00329 { 00330 /* failed to find midi info */ 00331 return MM_STATUS_UNSUCCESSFUL; 00332 } 00333 00334 /* copy capabilities */ 00335 MixerContext->Copy(Caps, &MidiInfo->u.OutCaps, sizeof(MIDIOUTCAPSW)); 00336 00337 return MM_STATUS_SUCCESS; 00338 } 00339 00340 MIXER_STATUS 00341 MMixerMidiInCapabilities( 00342 IN PMIXER_CONTEXT MixerContext, 00343 IN ULONG DeviceIndex, 00344 OUT LPMIDIINCAPSW Caps) 00345 { 00346 PMIXER_LIST MixerList; 00347 MIXER_STATUS Status; 00348 LPMIDI_INFO MidiInfo; 00349 00350 /* verify mixer context */ 00351 Status = MMixerVerifyContext(MixerContext); 00352 00353 if (Status != MM_STATUS_SUCCESS) 00354 { 00355 /* invalid context passed */ 00356 return Status; 00357 } 00358 00359 /* grab mixer list */ 00360 MixerList = (PMIXER_LIST)MixerContext->MixerContext; 00361 00362 /* find destination midi */ 00363 Status = MMixerGetMidiInfoByIndexAndType(MixerList, DeviceIndex, TRUE, &MidiInfo); 00364 if (Status != MM_STATUS_SUCCESS) 00365 { 00366 /* failed to find midi info */ 00367 return MM_STATUS_UNSUCCESSFUL; 00368 } 00369 00370 /* copy capabilities */ 00371 MixerContext->Copy(Caps, &MidiInfo->u.InCaps, sizeof(MIDIINCAPSW)); 00372 00373 return MM_STATUS_SUCCESS; 00374 } 00375 00376 MIXER_STATUS 00377 MMixerGetMidiDevicePath( 00378 IN PMIXER_CONTEXT MixerContext, 00379 IN ULONG bMidiIn, 00380 IN ULONG DeviceId, 00381 OUT LPWSTR * DevicePath) 00382 { 00383 PMIXER_LIST MixerList; 00384 LPMIXER_DATA MixerData; 00385 LPMIDI_INFO MidiInfo; 00386 ULONG Length; 00387 MIXER_STATUS Status; 00388 00389 /* verify mixer context */ 00390 Status = MMixerVerifyContext(MixerContext); 00391 00392 if (Status != MM_STATUS_SUCCESS) 00393 { 00394 /* invalid context passed */ 00395 return Status; 00396 } 00397 00398 /* grab mixer list */ 00399 MixerList = (PMIXER_LIST)MixerContext->MixerContext; 00400 00401 /* find destination midi */ 00402 Status = MMixerGetMidiInfoByIndexAndType(MixerList, DeviceId, bMidiIn, &MidiInfo); 00403 if (Status != MM_STATUS_SUCCESS) 00404 { 00405 /* failed to find midi info */ 00406 return MM_STATUS_INVALID_PARAMETER; 00407 } 00408 00409 /* get associated device id */ 00410 MixerData = MMixerGetDataByDeviceId(MixerList, MidiInfo->DeviceId); 00411 if (!MixerData) 00412 return MM_STATUS_INVALID_PARAMETER; 00413 00414 /* calculate length */ 00415 Length = wcslen(MixerData->DeviceName)+1; 00416 00417 /* allocate destination buffer */ 00418 *DevicePath = MixerContext->Alloc(Length * sizeof(WCHAR)); 00419 00420 if (!*DevicePath) 00421 { 00422 /* no memory */ 00423 return MM_STATUS_NO_MEMORY; 00424 } 00425 00426 /* copy device path */ 00427 MixerContext->Copy(*DevicePath, MixerData->DeviceName, Length * sizeof(WCHAR)); 00428 00429 /* done */ 00430 return MM_STATUS_SUCCESS; 00431 } 00432 00433 MIXER_STATUS 00434 MMixerSetMidiStatus( 00435 IN PMIXER_CONTEXT MixerContext, 00436 IN HANDLE PinHandle, 00437 IN KSSTATE State) 00438 { 00439 KSPROPERTY Property; 00440 ULONG Length; 00441 00442 /* setup property request */ 00443 Property.Set = KSPROPSETID_Connection; 00444 Property.Id = KSPROPERTY_CONNECTION_STATE; 00445 Property.Flags = KSPROPERTY_TYPE_SET; 00446 00447 return MixerContext->Control(PinHandle, IOCTL_KS_PROPERTY, &Property, sizeof(KSPROPERTY), &State, sizeof(KSSTATE), &Length); 00448 } 00449 00450 MIXER_STATUS 00451 MMixerOpenMidi( 00452 IN PMIXER_CONTEXT MixerContext, 00453 IN ULONG DeviceIndex, 00454 IN ULONG bMidiIn, 00455 IN PIN_CREATE_CALLBACK CreateCallback, 00456 IN PVOID Context, 00457 OUT PHANDLE PinHandle) 00458 { 00459 PMIXER_LIST MixerList; 00460 MIXER_STATUS Status; 00461 LPMIDI_INFO MidiInfo; 00462 ACCESS_MASK DesiredAccess = 0; 00463 00464 /* verify mixer context */ 00465 Status = MMixerVerifyContext(MixerContext); 00466 00467 if (Status != MM_STATUS_SUCCESS) 00468 { 00469 /* invalid context passed */ 00470 return Status; 00471 } 00472 00473 /* grab mixer list */ 00474 MixerList = (PMIXER_LIST)MixerContext->MixerContext; 00475 00476 /* find destination midi */ 00477 Status = MMixerGetMidiInfoByIndexAndType(MixerList, DeviceIndex, bMidiIn, &MidiInfo); 00478 if (Status != MM_STATUS_SUCCESS) 00479 { 00480 /* failed to find midi info */ 00481 return MM_STATUS_INVALID_PARAMETER; 00482 } 00483 00484 /* get desired access */ 00485 if (bMidiIn) 00486 { 00487 DesiredAccess |= GENERIC_READ; 00488 } 00489 else 00490 { 00491 DesiredAccess |= GENERIC_WRITE; 00492 } 00493 00494 /* now try open the pin */ 00495 return MMixerOpenMidiPin(MixerContext, MixerList, MidiInfo->DeviceId, MidiInfo->PinId, DesiredAccess, CreateCallback, Context, PinHandle); 00496 } 00497 00498 ULONG 00499 MMixerGetMidiInCount( 00500 IN PMIXER_CONTEXT MixerContext) 00501 { 00502 PMIXER_LIST MixerList; 00503 MIXER_STATUS Status; 00504 00505 /* verify mixer context */ 00506 Status = MMixerVerifyContext(MixerContext); 00507 00508 if (Status != MM_STATUS_SUCCESS) 00509 { 00510 /* invalid context passed */ 00511 return Status; 00512 } 00513 00514 /* grab mixer list */ 00515 MixerList = (PMIXER_LIST)MixerContext->MixerContext; 00516 00517 return MixerList->MidiInListCount; 00518 } 00519 00520 ULONG 00521 MMixerGetMidiOutCount( 00522 IN PMIXER_CONTEXT MixerContext) 00523 { 00524 PMIXER_LIST MixerList; 00525 MIXER_STATUS Status; 00526 00527 /* verify mixer context */ 00528 Status = MMixerVerifyContext(MixerContext); 00529 00530 if (Status != MM_STATUS_SUCCESS) 00531 { 00532 /* invalid context passed */ 00533 return Status; 00534 } 00535 00536 /* grab mixer list */ 00537 MixerList = (PMIXER_LIST)MixerContext->MixerContext; 00538 00539 return MixerList->MidiOutListCount; 00540 } Generated on Sun May 27 2012 04:24:42 for ReactOS by
1.7.6.1
|