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

mixer.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/mmixer.c
00005  * PURPOSE:         Mixer Handling Functions
00006  * PROGRAMMER:      Johannes Anderwald
00007  */
00008 
00009 
00010 
00011 #include "priv.h"
00012 
00013 ULONG
00014 MMixerGetCount(
00015     IN PMIXER_CONTEXT MixerContext)
00016 {
00017     PMIXER_LIST MixerList;
00018     MIXER_STATUS Status;
00019 
00020     /* verify mixer context */
00021     Status = MMixerVerifyContext(MixerContext);
00022 
00023     if (Status != MM_STATUS_SUCCESS)
00024     {
00025         /* invalid context passed */
00026         return Status;
00027     }
00028 
00029     /* grab mixer list */
00030     MixerList = (PMIXER_LIST)MixerContext->MixerContext;
00031 
00032     // return number of mixers
00033     return MixerList->MixerListCount;
00034 }
00035 
00036 MIXER_STATUS
00037 MMixerGetCapabilities(
00038     IN PMIXER_CONTEXT MixerContext,
00039     IN ULONG MixerIndex,
00040     OUT LPMIXERCAPSW MixerCaps)
00041 {
00042     MIXER_STATUS Status;
00043     LPMIXER_INFO MixerInfo;
00044 
00045     /* verify mixer context */
00046     Status = MMixerVerifyContext(MixerContext);
00047 
00048     if (Status != MM_STATUS_SUCCESS)
00049     {
00050         /* invalid context passed */
00051         return Status;
00052     }
00053 
00054     /* get mixer info */
00055     MixerInfo = MMixerGetMixerInfoByIndex(MixerContext, MixerIndex);
00056 
00057     if (!MixerInfo)
00058     {
00059         // invalid device index
00060         return MM_STATUS_INVALID_PARAMETER;
00061     }
00062 
00063     MixerCaps->wMid = MixerInfo->MixCaps.wMid;
00064     MixerCaps->wPid = MixerInfo->MixCaps.wPid;
00065     MixerCaps->vDriverVersion = MixerInfo->MixCaps.vDriverVersion;
00066     MixerCaps->fdwSupport = MixerInfo->MixCaps.fdwSupport;
00067     MixerCaps->cDestinations = MixerInfo->MixCaps.cDestinations;
00068 
00069     ASSERT(MixerInfo->MixCaps.szPname[MAXPNAMELEN-1] == 0);
00070     wcscpy(MixerCaps->szPname, MixerInfo->MixCaps.szPname);
00071 
00072     return MM_STATUS_SUCCESS;
00073 }
00074 
00075 MIXER_STATUS
00076 MMixerOpen(
00077     IN PMIXER_CONTEXT MixerContext,
00078     IN ULONG MixerId,
00079     IN PVOID MixerEventContext,
00080     IN PMIXER_EVENT MixerEventRoutine,
00081     OUT PHANDLE MixerHandle)
00082 {
00083     MIXER_STATUS Status;
00084     LPMIXER_INFO MixerInfo;
00085 
00086     /* verify mixer context */
00087     Status = MMixerVerifyContext(MixerContext);
00088 
00089     if (Status != MM_STATUS_SUCCESS)
00090     {
00091         /* invalid context passed */
00092         DPRINT1("invalid context\n");
00093         return Status;
00094     }
00095 
00096     /* get mixer info */
00097     MixerInfo = (LPMIXER_INFO)MMixerGetMixerInfoByIndex(MixerContext, MixerId);
00098     if (!MixerInfo)
00099     {
00100         /* invalid mixer id */
00101         DPRINT1("invalid mixer id %lu\n", MixerId);
00102         return MM_STATUS_INVALID_PARAMETER;
00103     }
00104 
00105     /* add the event */
00106     Status = MMixerAddEvent(MixerContext, MixerInfo, MixerEventContext, MixerEventRoutine);
00107 
00108 
00109     /* store result */
00110     *MixerHandle = (HANDLE)MixerInfo;
00111     return MM_STATUS_SUCCESS;
00112 }
00113 
00114 MIXER_STATUS
00115 MMixerGetLineInfo(
00116     IN PMIXER_CONTEXT MixerContext,
00117     IN HANDLE MixerHandle,
00118     IN ULONG MixerId,
00119     IN ULONG Flags,
00120     OUT LPMIXERLINEW MixerLine)
00121 {
00122     MIXER_STATUS Status;
00123     LPMIXER_INFO MixerInfo;
00124     LPMIXERLINE_EXT MixerLineSrc;
00125     ULONG DestinationLineID;
00126 
00127     /* verify mixer context */
00128     Status = MMixerVerifyContext(MixerContext);
00129 
00130     if (Status != MM_STATUS_SUCCESS)
00131     {
00132         /* invalid context passed */
00133         return Status;
00134     }
00135     if ((Flags & (MIXER_OBJECTF_MIXER | MIXER_OBJECTF_HMIXER)) == MIXER_OBJECTF_MIXER)
00136     {
00137         /* caller passed mixer id */
00138         MixerHandle = (HANDLE)MMixerGetMixerInfoByIndex(MixerContext, MixerId);
00139 
00140         if (!MixerHandle)
00141         {
00142             /* invalid parameter */
00143             return MM_STATUS_INVALID_PARAMETER;
00144         }
00145     }
00146 
00147     if (MixerLine->cbStruct != sizeof(MIXERLINEW))
00148     {
00149         DPRINT1("MixerLine Expected %lu but got %lu\n", sizeof(MIXERLINEW), MixerLine->cbStruct);
00150         return MM_STATUS_INVALID_PARAMETER;
00151     }
00152 
00153     /* clear hmixer from flags */
00154     Flags &=~MIXER_OBJECTF_HMIXER;
00155 
00156     DPRINT("MMixerGetLineInfo MixerId %lu Flags %lu\n", MixerId, Flags);
00157 
00158     if (Flags == MIXER_GETLINEINFOF_DESTINATION)
00159     {
00160         /* cast to mixer info */
00161         MixerInfo = (LPMIXER_INFO)MixerHandle;
00162 
00163         /* calculate destination line id */
00164         DestinationLineID = (MixerLine->dwDestination + DESTINATION_LINE);
00165 
00166         /* get destination line */
00167         MixerLineSrc = MMixerGetSourceMixerLineByLineId(MixerInfo, DestinationLineID);
00168 
00169         if (MixerLineSrc == NULL)
00170         {
00171             DPRINT1("MixerCaps Name %S DestinationLineCount %lu dwDestination %lu not found\n", MixerInfo->MixCaps.szPname, MixerInfo->MixCaps.cDestinations, MixerLine->dwDestination);
00172             return MM_STATUS_UNSUCCESSFUL;
00173         }
00174         /* copy mixer line */
00175         MixerContext->Copy(MixerLine, &MixerLineSrc->Line, sizeof(MIXERLINEW));
00176 
00177         /* make sure it is null terminated */
00178         MixerLine->szName[MIXER_LONG_NAME_CHARS-1] = L'\0';
00179         MixerLine->szShortName[MIXER_SHORT_NAME_CHARS-1] = L'\0';
00180         MixerLine->Target.szPname[MAXPNAMELEN-1] = L'\0';
00181 
00182         /* done */
00183         return MM_STATUS_SUCCESS;
00184     }
00185     else if (Flags == MIXER_GETLINEINFOF_SOURCE)
00186     {
00187         /* cast to mixer info */
00188         MixerInfo = (LPMIXER_INFO)MixerHandle;
00189 
00190         /* calculate destination line id */
00191         DestinationLineID = (MixerLine->dwDestination + DESTINATION_LINE);
00192 
00193         /* get destination line */
00194         MixerLineSrc = MMixerGetSourceMixerLineByLineId(MixerInfo, DestinationLineID);
00195 
00196         if (MixerLineSrc == NULL)
00197         {
00198             DPRINT1("MixerCaps Name %S DestinationLineCount %lu dwDestination %lu not found\n", MixerInfo->MixCaps.szPname, MixerInfo->MixCaps.cDestinations, MixerLine->dwDestination);
00199             return MM_STATUS_UNSUCCESSFUL;
00200         }
00201 
00202         /* check if dwSource is out of bounds */
00203         if (MixerLine->dwSource >= MixerLineSrc->Line.cConnections)
00204         {
00205             DPRINT1("MixerCaps Name %S MixerLineName %S Connections %lu dwSource %lu not found\n", MixerInfo->MixCaps.szPname, MixerLineSrc->Line.szName, MixerLineSrc->Line.cConnections, MixerLine->dwSource);
00206             return MM_STATUS_UNSUCCESSFUL;
00207         }
00208 
00209         /* calculate destination line id */
00210         DestinationLineID = (MixerLine->dwSource * SOURCE_LINE) + MixerLine->dwDestination;
00211 
00212         DPRINT("MixerName %S cDestinations %lu MixerLineName %S cConnections %lu dwSource %lu dwDestination %lu ID %lx\n", MixerInfo->MixCaps.szPname, MixerInfo->MixCaps.cDestinations,
00213                                                                                                                             MixerLineSrc->Line.szName, MixerLineSrc->Line.cConnections,
00214                                                                                                                             MixerLine->dwSource, MixerLine->dwDestination,
00215                                                                                                                             DestinationLineID);
00216         /* get target destination line id */
00217         MixerLineSrc = MMixerGetSourceMixerLineByLineId(MixerInfo, DestinationLineID);
00218 
00219         /* sanity check */
00220         ASSERT(MixerLineSrc);
00221 
00222         DPRINT("Line %u Name %S\n", MixerLineSrc->Line.dwSource, MixerLineSrc->Line.szName);
00223 
00224         /* copy mixer line */
00225         MixerContext->Copy(MixerLine, &MixerLineSrc->Line, sizeof(MIXERLINEW));
00226 
00227         /* make sure it is null terminated */
00228         MixerLine->szName[MIXER_LONG_NAME_CHARS-1] = L'\0';
00229         MixerLine->szShortName[MIXER_SHORT_NAME_CHARS-1] = L'\0';
00230         MixerLine->Target.szPname[MAXPNAMELEN-1] = L'\0';
00231 
00232         /* done */
00233         return MM_STATUS_SUCCESS;
00234     }
00235     else if (Flags == MIXER_GETLINEINFOF_LINEID)
00236     {
00237         /* cast to mixer info */
00238         MixerInfo = (LPMIXER_INFO)MixerHandle;
00239 
00240         /* try to find line */
00241         MixerLineSrc = MMixerGetSourceMixerLineByLineId(MixerInfo, MixerLine->dwLineID);
00242         if (!MixerLineSrc)
00243         {
00244             /* invalid parameter */
00245             DPRINT1("MMixerGetLineInfo: MixerName %S Line not found 0x%lx\n", MixerInfo->MixCaps.szPname, MixerLine->dwLineID);
00246             return MM_STATUS_INVALID_PARAMETER;
00247         }
00248 
00249         DPRINT("Line %u Name %S\n", MixerLineSrc->Line.dwSource, MixerLineSrc->Line.szName);
00250 
00251         /* copy mixer line*/
00252         MixerContext->Copy(MixerLine, &MixerLineSrc->Line, sizeof(MIXERLINEW));
00253 
00254         /* make sure it is null terminated */
00255         MixerLine->szName[MIXER_LONG_NAME_CHARS-1] = L'\0';
00256         MixerLine->szShortName[MIXER_SHORT_NAME_CHARS-1] = L'\0';
00257         MixerLine->Target.szPname[MAXPNAMELEN-1] = L'\0';
00258 
00259         return MM_STATUS_SUCCESS;
00260     }
00261     else if (Flags == MIXER_GETLINEINFOF_COMPONENTTYPE)
00262     {
00263         /* cast to mixer info */
00264         MixerInfo = (LPMIXER_INFO)MixerHandle;
00265 
00266         /* find mixer line by component type */
00267         MixerLineSrc = MMixerGetSourceMixerLineByComponentType(MixerInfo, MixerLine->dwComponentType);
00268         if (!MixerLineSrc)
00269         {
00270             DPRINT1("Failed to find component type %x\n", MixerLine->dwComponentType);
00271             return MM_STATUS_UNSUCCESSFUL;
00272         }
00273 
00274         /* copy mixer line */
00275         MixerContext->Copy(MixerLine, &MixerLineSrc->Line, sizeof(MIXERLINEW));
00276 
00277         /* make sure it is null terminated */
00278         MixerLine->szName[MIXER_LONG_NAME_CHARS-1] = L'\0';
00279         MixerLine->szShortName[MIXER_SHORT_NAME_CHARS-1] = L'\0';
00280         MixerLine->Target.szPname[MAXPNAMELEN-1] = L'\0';
00281 
00282         /* done */
00283         return MM_STATUS_SUCCESS;
00284     }
00285     else if (Flags == MIXER_GETLINEINFOF_TARGETTYPE)
00286     {
00287         DPRINT1("MIXER_GETLINEINFOF_TARGETTYPE handling is unimplemented\n");
00288     }
00289     else
00290     {
00291         DPRINT1("Unknown Flags %lx handling is unimplemented\n", Flags);
00292     }
00293 
00294     return MM_STATUS_NOT_IMPLEMENTED;
00295 }
00296 
00297 MIXER_STATUS
00298 MMixerGetLineControls(
00299     IN PMIXER_CONTEXT MixerContext,
00300     IN HANDLE MixerHandle,
00301     IN ULONG MixerId,
00302     IN ULONG Flags,
00303     OUT LPMIXERLINECONTROLSW MixerLineControls)
00304 {
00305     LPMIXER_INFO MixerInfo;
00306     LPMIXERLINE_EXT MixerLineSrc;
00307     LPMIXERCONTROL_EXT MixerControl;
00308     MIXER_STATUS Status;
00309     PLIST_ENTRY Entry;
00310     ULONG Index;
00311 
00312     /* verify mixer context */
00313     Status = MMixerVerifyContext(MixerContext);
00314 
00315     if (Status != MM_STATUS_SUCCESS)
00316     {
00317         /* invalid context passed */
00318         return Status;
00319     }
00320 
00321     if (MixerLineControls->cbStruct != sizeof(MIXERLINECONTROLSW))
00322     {
00323         DPRINT1("Invalid MixerLineControls cbStruct passed %lu expected %lu\n", MixerLineControls->cbStruct, sizeof(MIXERLINECONTROLSW));
00324         /* invalid parameter */
00325         return MM_STATUS_INVALID_PARAMETER;
00326     }
00327 
00328     if (MixerLineControls->cbmxctrl != sizeof(MIXERCONTROLW))
00329     {
00330         DPRINT1("Invalid MixerLineControls cbmxctrl passed %lu expected %lu\n", MixerLineControls->cbStruct, sizeof(MIXERLINECONTROLSW));
00331         /* invalid parameter */
00332         return MM_STATUS_INVALID_PARAMETER;
00333     }
00334 
00335     if ((Flags & (MIXER_OBJECTF_MIXER | MIXER_OBJECTF_HMIXER)) == MIXER_OBJECTF_MIXER)
00336     {
00337         /* caller passed mixer id */
00338         MixerHandle = (HANDLE)MMixerGetMixerInfoByIndex(MixerContext, MixerId);
00339 
00340         if (!MixerHandle)
00341         {
00342             /* invalid parameter */
00343             return MM_STATUS_INVALID_PARAMETER;
00344         }
00345     }
00346 
00347     Flags &= ~MIXER_OBJECTF_HMIXER;
00348 
00349     DPRINT("MMixerGetLineControls MixerId %lu Flags %lu\n", MixerId, Flags);
00350 
00351     if (Flags == MIXER_GETLINECONTROLSF_ALL)
00352     {
00353         /* cast to mixer info */
00354         MixerInfo = (LPMIXER_INFO)MixerHandle;
00355 
00356         /* get mixer line */
00357         MixerLineSrc = MMixerGetSourceMixerLineByLineId(MixerInfo, MixerLineControls->dwLineID);
00358 
00359         if (!MixerLineSrc)
00360         {
00361             /* invalid line id */
00362             DPRINT("MMixerGetLineControls Line not found %lx\n", MixerLineControls->dwLineID);
00363             return MM_STATUS_INVALID_PARAMETER;
00364         }
00365 
00366         if (MixerLineSrc->Line.cControls != MixerLineControls->cControls)
00367         {
00368             /* invalid parameter */
00369             DPRINT1("Invalid control count %lu expected %lu\n", MixerLineControls->cControls, MixerLineSrc->Line.cControls);
00370             return MM_STATUS_INVALID_PARAMETER;
00371         }
00372 
00373         /* copy line control(s) */
00374         Entry = MixerLineSrc->ControlsList.Flink;
00375         Index = 0;
00376         while(Entry != &MixerLineSrc->ControlsList)
00377         {
00378             /* get mixer control */
00379             MixerControl = (LPMIXERCONTROL_EXT)CONTAINING_RECORD(Entry, MIXERCONTROL_EXT, Entry);
00380 
00381             /* copy mixer control */
00382             MixerContext->Copy(&MixerLineControls->pamxctrl[Index], &MixerControl->Control, sizeof(MIXERCONTROLW));
00383 
00384             /* move to next */
00385             Entry = Entry->Flink;
00386 
00387             /* increment mixer control offset */
00388             Index++;
00389         }
00390         return MM_STATUS_SUCCESS;
00391     }
00392     else if (Flags == MIXER_GETLINECONTROLSF_ONEBYTYPE)
00393     {
00394         /* cast to mixer info */
00395         MixerInfo = (LPMIXER_INFO)MixerHandle;
00396 
00397         /* get mixer line */
00398         MixerLineSrc = MMixerGetSourceMixerLineByLineId(MixerInfo, MixerLineControls->dwLineID);
00399 
00400         if (!MixerLineSrc)
00401         {
00402             /* invalid line id */
00403             DPRINT1("MMixerGetLineControls Line not found %lx\n", MixerLineControls->dwLineID);
00404             return MM_STATUS_INVALID_PARAMETER;
00405         }
00406 
00407         /* sanity checks */
00408         ASSERT(MixerLineControls->cControls == 1);
00409         ASSERT(MixerLineControls->cbmxctrl == sizeof(MIXERCONTROLW));
00410         ASSERT(MixerLineControls->pamxctrl != NULL);
00411 
00412         Entry = MixerLineSrc->ControlsList.Flink;
00413         while(Entry != &MixerLineSrc->ControlsList)
00414         {
00415             MixerControl = (LPMIXERCONTROL_EXT)CONTAINING_RECORD(Entry, MIXERCONTROL_EXT, Entry);
00416             if (MixerLineControls->dwControlType == MixerControl->Control.dwControlType)
00417             {
00418                 /* found a control with that type */
00419                 MixerContext->Copy(MixerLineControls->pamxctrl, &MixerControl->Control, sizeof(MIXERCONTROLW));
00420                 return MM_STATUS_SUCCESS;
00421             }
00422 
00423             /* move to next entry */
00424             Entry = Entry->Flink;
00425          }
00426 
00427          DPRINT("DeviceInfo->u.MixControls.dwControlType %x not found in Line %x cControls %u \n", MixerLineControls->dwControlType, MixerLineControls->dwLineID, MixerLineSrc->Line.cControls);
00428          return MM_STATUS_UNSUCCESSFUL;
00429     }
00430     else if (Flags == MIXER_GETLINECONTROLSF_ONEBYID)
00431     {
00432         /* cast to mixer info */
00433         MixerInfo = (LPMIXER_INFO)MixerHandle;
00434 
00435         Status = MMixerGetMixerControlById(MixerInfo, MixerLineControls->dwControlID, NULL, &MixerControl, NULL);
00436 
00437         if (Status != MM_STATUS_SUCCESS)
00438         {
00439             /* invalid parameter */
00440             DPRINT("MMixerGetLineControls ControlID not found %lx\n", MixerLineControls->dwLineID);
00441             return MM_STATUS_INVALID_PARAMETER;
00442         }
00443 
00444         ASSERT(MixerLineControls->cControls == 1);
00445         ASSERT(MixerLineControls->cbmxctrl == sizeof(MIXERCONTROLW));
00446         ASSERT(MixerLineControls->pamxctrl != NULL);
00447 
00448        DPRINT("MMixerGetLineControls ControlID %lx ControlType %lx Name %S\n", MixerControl->Control.dwControlID, MixerControl->Control.dwControlType, MixerControl->Control.szName);
00449 
00450         /* copy the controls */
00451         MixerContext->Copy(MixerLineControls->pamxctrl, &MixerControl->Control, sizeof(MIXERCONTROLW));
00452         MixerLineControls->pamxctrl->szName[MIXER_LONG_NAME_CHARS-1] = L'\0';
00453         MixerLineControls->pamxctrl->szShortName[MIXER_SHORT_NAME_CHARS-1] = L'\0';
00454 
00455         return MM_STATUS_SUCCESS;
00456     }
00457     UNIMPLEMENTED
00458     return MM_STATUS_NOT_IMPLEMENTED;
00459 }
00460 
00461 MIXER_STATUS
00462 MMixerSetControlDetails(
00463     IN PMIXER_CONTEXT MixerContext,
00464     IN HANDLE MixerHandle,
00465     IN ULONG MixerId,
00466     IN ULONG Flags,
00467     OUT LPMIXERCONTROLDETAILS MixerControlDetails)
00468 {
00469     MIXER_STATUS Status;
00470     ULONG NodeId;
00471     LPMIXER_INFO MixerInfo;
00472     LPMIXERLINE_EXT MixerLine;
00473     LPMIXERCONTROL_EXT MixerControl;
00474 
00475     /* verify mixer context */
00476     Status = MMixerVerifyContext(MixerContext);
00477 
00478     if (Status != MM_STATUS_SUCCESS)
00479     {
00480         /* invalid context passed */
00481         DPRINT1("invalid context\n");
00482         return Status;
00483     }
00484 
00485     if ((Flags & (MIXER_OBJECTF_MIXER | MIXER_OBJECTF_HMIXER)) == MIXER_OBJECTF_MIXER)
00486     {
00487         /* caller passed mixer id */
00488         MixerHandle = (HANDLE)MMixerGetMixerInfoByIndex(MixerContext, MixerId);
00489 
00490         if (!MixerHandle)
00491         {
00492             /* invalid parameter */
00493             DPRINT1("invalid handle\n");
00494             return MM_STATUS_INVALID_PARAMETER;
00495         }
00496     }
00497 
00498     /* get mixer info */
00499     MixerInfo = (LPMIXER_INFO)MixerHandle;
00500 
00501     /* get mixer control */
00502      Status = MMixerGetMixerControlById(MixerInfo, MixerControlDetails->dwControlID, &MixerLine, &MixerControl, &NodeId);
00503 
00504     /* check for success */
00505     if (Status != MM_STATUS_SUCCESS)
00506     {
00507         /* failed to find control id */
00508         DPRINT1("invalid control id %lu\n", MixerControlDetails->dwControlID);
00509         return MM_STATUS_INVALID_PARAMETER;
00510     }
00511 
00512     DPRINT("MMixerSetControlDetails ControlType %lx MixerControlName %S MixerLineName %S NodeID %lu\n", MixerControl->Control.dwControlType, MixerControl->Control.szName, MixerLine->Line.szName, NodeId);
00513     switch(MixerControl->Control.dwControlType)
00514     {
00515         case MIXERCONTROL_CONTROLTYPE_MUTE:
00516             Status = MMixerSetGetMuteControlDetails(MixerContext, MixerInfo, MixerControl, MixerLine->Line.dwLineID, MixerControlDetails, TRUE);
00517             break;
00518         case MIXERCONTROL_CONTROLTYPE_VOLUME:
00519             Status = MMixerSetGetVolumeControlDetails(MixerContext, MixerInfo, NodeId, TRUE, MixerControl, MixerControlDetails, MixerLine);
00520             break;
00521         case MIXERCONTROL_CONTROLTYPE_MUX:
00522             Status = MMixerSetGetMuxControlDetails(MixerContext, MixerInfo, NodeId, TRUE, Flags, MixerControl, MixerControlDetails, MixerLine);
00523             break;
00524         default:
00525             Status = MM_STATUS_NOT_IMPLEMENTED;
00526     }
00527 
00528     return Status;
00529 }
00530 
00531 MIXER_STATUS
00532 MMixerGetControlDetails(
00533     IN PMIXER_CONTEXT MixerContext,
00534     IN HANDLE MixerHandle,
00535     IN ULONG MixerId,
00536     IN ULONG Flags,
00537     OUT LPMIXERCONTROLDETAILS MixerControlDetails)
00538 {
00539     MIXER_STATUS Status;
00540     ULONG NodeId;
00541     LPMIXER_INFO MixerInfo;
00542     LPMIXERLINE_EXT MixerLine;
00543     LPMIXERCONTROL_EXT MixerControl;
00544 
00545     /* verify mixer context */
00546     Status = MMixerVerifyContext(MixerContext);
00547 
00548     if (Status != MM_STATUS_SUCCESS)
00549     {
00550         /* invalid context passed */
00551         return Status;
00552     }
00553 
00554     if ((Flags & (MIXER_OBJECTF_MIXER | MIXER_OBJECTF_HMIXER)) == MIXER_OBJECTF_MIXER)
00555     {
00556         /* caller passed mixer id */
00557         MixerHandle = (HANDLE)MMixerGetMixerInfoByIndex(MixerContext, MixerId);
00558 
00559         if (!MixerHandle)
00560         {
00561             /* invalid parameter */
00562             return MM_STATUS_INVALID_PARAMETER;
00563         }
00564     }
00565 
00566     /* get mixer info */
00567     MixerInfo = (LPMIXER_INFO)MixerHandle;
00568 
00569     /* get mixer control */
00570      Status = MMixerGetMixerControlById(MixerInfo, MixerControlDetails->dwControlID, &MixerLine, &MixerControl, &NodeId);
00571 
00572     /* check for success */
00573     if (Status != MM_STATUS_SUCCESS)
00574     {
00575         /* failed to find control id */
00576         return MM_STATUS_INVALID_PARAMETER;
00577     }
00578 
00579     switch(MixerControl->Control.dwControlType)
00580     {
00581         case MIXERCONTROL_CONTROLTYPE_MUTE:
00582             Status = MMixerSetGetMuteControlDetails(MixerContext, MixerInfo, MixerControl, MixerLine->Line.dwLineID, MixerControlDetails, FALSE);
00583             break;
00584         case MIXERCONTROL_CONTROLTYPE_VOLUME:
00585             Status = MMixerSetGetVolumeControlDetails(MixerContext, MixerInfo, NodeId, FALSE, MixerControl, MixerControlDetails, MixerLine);
00586             break;
00587         case MIXERCONTROL_CONTROLTYPE_ONOFF:
00588             DPRINT1("Not Implemented MIXERCONTROL_CONTROLTYPE_ONOFF\n");
00589             break;
00590         case MIXERCONTROL_CONTROLTYPE_MUX:
00591             Status = MMixerSetGetMuxControlDetails(MixerContext, MixerInfo, NodeId, FALSE, Flags, MixerControl, MixerControlDetails, MixerLine);
00592             break;
00593 
00594         default:
00595             Status = MM_STATUS_NOT_IMPLEMENTED;
00596             DPRINT1("ControlType %lx not implemented\n", MixerControl->Control.dwControlType);
00597     }
00598 
00599     return Status;
00600 }
00601 
00602 VOID
00603 MMixerPrintMixerLineControls(
00604     IN LPMIXERLINE_EXT MixerLine)
00605 {
00606     PLIST_ENTRY Entry;
00607     LPMIXERCONTROL_EXT MixerControl;
00608     ULONG Index = 0;
00609 
00610     Entry = MixerLine->ControlsList.Flink;
00611     while(Entry != &MixerLine->ControlsList)
00612     {
00613         MixerControl = (LPMIXERCONTROL_EXT)CONTAINING_RECORD(Entry, MIXERCONTROL_EXT, Entry);
00614 
00615         DPRINT1("\n");
00616         DPRINT1("Control Index: %lu\n", Index);
00617         DPRINT("\n");
00618         DPRINT1("cbStruct %u\n", MixerControl->Control.cbStruct);
00619         DPRINT1("dwControlID %lu\n", MixerControl->Control.dwControlID);
00620         DPRINT1("dwControlType %lx\n", MixerControl->Control.dwControlType);
00621         DPRINT1("fdwControl %lu\n", MixerControl->Control.fdwControl);
00622         DPRINT1("cMultipleItems %lu\n", MixerControl->Control.cMultipleItems);
00623         DPRINT1("szShortName %S\n", MixerControl->Control.szShortName);
00624         DPRINT1("szName %S\n", MixerControl->Control.szName);
00625         DPRINT1("Bounds.dwMinimum %lu\n", MixerControl->Control.Bounds.dwMinimum);
00626         DPRINT1("Bounds.dwMaximum %lu\n", MixerControl->Control.Bounds.dwMaximum);
00627 
00628         DPRINT1("Metrics.Reserved[0] %lu\n", MixerControl->Control.Metrics.dwReserved[0]);
00629         DPRINT1("Metrics.Reserved[1] %lu\n", MixerControl->Control.Metrics.dwReserved[1]);
00630         DPRINT1("Metrics.Reserved[2] %lu\n", MixerControl->Control.Metrics.dwReserved[2]);
00631         DPRINT1("Metrics.Reserved[3] %lu\n", MixerControl->Control.Metrics.dwReserved[3]);
00632         DPRINT1("Metrics.Reserved[4] %lu\n", MixerControl->Control.Metrics.dwReserved[4]);
00633         DPRINT1("Metrics.Reserved[5] %lu\n", MixerControl->Control.Metrics.dwReserved[5]);
00634 
00635         Entry = Entry->Flink;
00636         Index++;
00637     }
00638 }
00639 
00640 VOID
00641 MMixerPrintMixers(
00642     IN PMIXER_CONTEXT MixerContext,
00643     IN PMIXER_LIST MixerList)
00644 {
00645     ULONG Index, SubIndex, DestinationLineID, SrcIndex;
00646     LPMIXER_INFO MixerInfo;
00647     LPMIXERLINE_EXT DstMixerLine, SrcMixerLine;
00648 
00649     DPRINT1("MixerList %p\n", MixerList);
00650     DPRINT1("MidiInCount %lu\n", MixerList->MidiInListCount);
00651     DPRINT1("MidiOutCount %lu\n", MixerList->MidiOutListCount);
00652     DPRINT1("WaveInCount %lu\n", MixerList->WaveInListCount);
00653     DPRINT1("WaveOutCount %lu\n", MixerList->WaveOutListCount);
00654     DPRINT1("MixerCount %p\n", MixerList->MixerListCount);
00655 
00656 
00657     for(Index = 0; Index < MixerList->MixerListCount; Index++)
00658     {
00659         /* get mixer info */
00660         MixerInfo = MMixerGetMixerInfoByIndex(MixerContext, Index);
00661 
00662         ASSERT(MixerInfo);
00663         DPRINT1("\n");
00664         DPRINT1("Name :%S\n", MixerInfo->MixCaps.szPname);
00665         DPRINT1("cDestinations: %lu\n", MixerInfo->MixCaps.cDestinations);
00666         DPRINT1("fdwSupport %lu\n", MixerInfo->MixCaps.fdwSupport);
00667         DPRINT1("vDriverVersion %lx\n", MixerInfo->MixCaps.vDriverVersion);
00668         DPRINT1("wMid %lx\n", MixerInfo->MixCaps.wMid);
00669         DPRINT1("wPid %lx\n", MixerInfo->MixCaps.wPid);
00670 
00671         for(SubIndex = 0; SubIndex < MixerInfo->MixCaps.cDestinations; SubIndex++)
00672         {
00673             /* calculate destination line id */
00674             DestinationLineID = (SubIndex + DESTINATION_LINE);
00675 
00676             /* get destination line */
00677             DstMixerLine = MMixerGetSourceMixerLineByLineId(MixerInfo, DestinationLineID);
00678             DPRINT1("//----------------------------------------------------------------------------------------------\n");
00679             DPRINT1("\n");
00680             DPRINT1("Destination Index %lu\n", SubIndex);
00681             DPRINT1("\n");
00682             DPRINT1("cChannels %lu\n", DstMixerLine->Line.cChannels);
00683             DPRINT1("cConnections %lu\n", DstMixerLine->Line.cConnections);
00684             DPRINT1("cControls %lu\n", DstMixerLine->Line.cControls);
00685             DPRINT1("dwComponentType %lx\n", DstMixerLine->Line.dwComponentType);
00686             DPRINT1("dwDestination %lu\n", DstMixerLine->Line.dwDestination);
00687             DPRINT1("dwLineID %lx\n", DstMixerLine->Line.dwLineID);
00688             DPRINT1("dwSource %lx\n", DstMixerLine->Line.dwSource);
00689             DPRINT1("dwUser %lu\n", DstMixerLine->Line.dwUser);
00690             DPRINT1("fdwLine %lu\n", DstMixerLine->Line.fdwLine);
00691             DPRINT1("szName %S\n", DstMixerLine->Line.szName);
00692             DPRINT1("szShortName %S\n", DstMixerLine->Line.szShortName);
00693             DPRINT1("Target.dwDeviceId %lu\n", DstMixerLine->Line.Target.dwDeviceID);
00694             DPRINT1("Target.dwType %lu\n", DstMixerLine->Line.Target.dwType);
00695             DPRINT1("Target.szName %S\n", DstMixerLine->Line.Target.szPname);
00696             DPRINT1("Target.vDriverVersion %lx\n", DstMixerLine->Line.Target.vDriverVersion);
00697             DPRINT1("Target.wMid %lx\n", DstMixerLine->Line.Target.wMid );
00698             DPRINT1("Target.wPid %lx\n", DstMixerLine->Line.Target.wPid);
00699             MMixerPrintMixerLineControls(DstMixerLine);
00700 
00701             for(SrcIndex = 0; SrcIndex < DstMixerLine->Line.cConnections; SrcIndex++)
00702             {
00703                 /* calculate destination line id */
00704                 DestinationLineID = (SOURCE_LINE * SrcIndex) + SubIndex;
00705 
00706                 /* get source line */
00707                 SrcMixerLine = MMixerGetSourceMixerLineByLineId(MixerInfo, DestinationLineID);
00708                 DPRINT1("//==============================================================================================\n");
00709                 DPRINT1("\n");
00710                 DPRINT1("SrcLineIndex : %lu\n", SrcIndex);
00711                 DPRINT1("\n");
00712                 DPRINT1("cChannels %lu\n", SrcMixerLine->Line.cChannels);
00713                 DPRINT1("cConnections %lu\n", SrcMixerLine->Line.cConnections);
00714                 DPRINT1("cControls %lu\n", SrcMixerLine->Line.cControls);
00715                 DPRINT1("dwComponentType %lx\n", SrcMixerLine->Line.dwComponentType);
00716                 DPRINT1("dwDestination %lu\n", SrcMixerLine->Line.dwDestination);
00717                 DPRINT1("dwLineID %lx\n", SrcMixerLine->Line.dwLineID);
00718                 DPRINT1("dwSource %lx\n", SrcMixerLine->Line.dwSource);
00719                 DPRINT1("dwUser %lu\n", SrcMixerLine->Line.dwUser);
00720                 DPRINT1("fdwLine %lu\n", SrcMixerLine->Line.fdwLine);
00721                 DPRINT1("szName %S\n", SrcMixerLine->Line.szName);
00722                 DPRINT1("szShortName %S\n", SrcMixerLine->Line.szShortName);
00723                 DPRINT1("Target.dwDeviceId %lu\n", SrcMixerLine->Line.Target.dwDeviceID);
00724                 DPRINT1("Target.dwType %lu\n", SrcMixerLine->Line.Target.dwType);
00725                 DPRINT1("Target.szName %S\n", SrcMixerLine->Line.Target.szPname);
00726                 DPRINT1("Target.vDriverVersion %lx\n", SrcMixerLine->Line.Target.vDriverVersion);
00727                 DPRINT1("Target.wMid %lx\n", SrcMixerLine->Line.Target.wMid );
00728                 DPRINT1("Target.wPid %lx\n", SrcMixerLine->Line.Target.wPid);
00729                 MMixerPrintMixerLineControls(SrcMixerLine);
00730             }
00731         }
00732     }
00733 }
00734 
00735 MIXER_STATUS
00736 MMixerInitialize(
00737     IN PMIXER_CONTEXT MixerContext,
00738     IN PMIXER_ENUM EnumFunction,
00739     IN PVOID EnumContext)
00740 {
00741     MIXER_STATUS Status;
00742     HANDLE hMixer, hKey;
00743     ULONG DeviceIndex, Count;
00744     LPWSTR DeviceName;
00745     LPMIXER_DATA MixerData;
00746     PMIXER_LIST MixerList;
00747     PLIST_ENTRY Entry;
00748 
00749     if (!MixerContext || !EnumFunction || !EnumContext)
00750     {
00751         /* invalid parameter */
00752         return MM_STATUS_INVALID_PARAMETER;
00753     }
00754 
00755     if (!MixerContext->Alloc || !MixerContext->Control || !MixerContext->Free || !MixerContext->Open ||
00756         !MixerContext->AllocEventData || !MixerContext->FreeEventData ||
00757         !MixerContext->Close || !MixerContext->OpenKey || !MixerContext->QueryKeyValue || !MixerContext->CloseKey)
00758     {
00759         /* invalid parameter */
00760         return MM_STATUS_INVALID_PARAMETER;
00761     }
00762 
00763     /* allocate a mixer list */
00764     MixerList = (PMIXER_LIST)MixerContext->Alloc(sizeof(MIXER_LIST));
00765     if (!MixerList)
00766     {
00767         /* no memory */
00768         return MM_STATUS_NO_MEMORY;
00769     }
00770 
00771      /* initialize mixer list */
00772      MixerList->MixerListCount = 0;
00773      MixerList->MixerDataCount = 0;
00774      MixerList->WaveInListCount = 0;
00775      MixerList->WaveOutListCount = 0;
00776      MixerList->MidiInListCount = 0;
00777      MixerList->MidiOutListCount = 0;
00778      InitializeListHead(&MixerList->MixerList);
00779      InitializeListHead(&MixerList->MixerData);
00780      InitializeListHead(&MixerList->WaveInList);
00781      InitializeListHead(&MixerList->WaveOutList);
00782      InitializeListHead(&MixerList->MidiInList);
00783      InitializeListHead(&MixerList->MidiOutList);
00784 
00785      /* store mixer list */
00786      MixerContext->MixerContext = (PVOID)MixerList;
00787 
00788     /* start enumerating all available devices */
00789     Count = 0;
00790     DeviceIndex = 0;
00791 
00792     do
00793     {
00794         /* enumerate a device */
00795         Status = EnumFunction(EnumContext, DeviceIndex, &DeviceName, &hMixer, &hKey);
00796 
00797         if (Status != MM_STATUS_SUCCESS)
00798         {
00799             /* check error code */
00800             if (Status == MM_STATUS_NO_MORE_DEVICES)
00801             {
00802                 /* enumeration has finished */
00803                 break;
00804             }
00805             else
00806             {
00807                 DPRINT1("Failed to enumerate device %lu\n", DeviceIndex);
00808 
00809                 /* TODO cleanup */
00810                 return Status;
00811             }
00812         }
00813         else
00814         {
00815             /* create a mixer data entry */
00816             Status = MMixerCreateMixerData(MixerContext, MixerList, DeviceIndex, DeviceName, hMixer, hKey);
00817             if (Status != MM_STATUS_SUCCESS)
00818                 break;
00819         }
00820 
00821         /* increment device index */
00822         DeviceIndex++;
00823     }while(TRUE);
00824 
00825     /* now all filters have been pre-opened
00826      * lets enumerate the filters
00827      */
00828     Entry = MixerList->MixerData.Flink;
00829     while(Entry != &MixerList->MixerData)
00830     {
00831         MixerData = (LPMIXER_DATA)CONTAINING_RECORD(Entry, MIXER_DATA, Entry);
00832         MMixerSetupFilter(MixerContext, MixerList, MixerData, &Count);
00833         Entry = Entry->Flink;
00834     }
00835 
00836     Entry = MixerList->MixerData.Flink;
00837     while(Entry != &MixerList->MixerData)
00838     {
00839         MixerData = (LPMIXER_DATA)CONTAINING_RECORD(Entry, MIXER_DATA, Entry);
00840 
00841         /* now handle alternative mixer types */
00842         MMixerHandleAlternativeMixers(MixerContext, MixerList, MixerData, MixerData->Topology);
00843         Entry = Entry->Flink;
00844     }
00845 
00846     //MMixerPrintMixers(MixerContext, MixerList);
00847 
00848     /* done */
00849     return MM_STATUS_SUCCESS;
00850 }

Generated on Sun May 27 2012 04:17:44 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.