ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

midi.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.