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

wave.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/wave.c
00005  * PURPOSE:         Wave Handling Functions
00006  * PROGRAMMER:      Johannes Anderwald
00007  */
00008 
00009 #include "priv.h"
00010 
00011 const GUID KSPROPSETID_Connection               = {0x1D58C920L, 0xAC9B, 0x11CF, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}};
00012 const GUID KSDATAFORMAT_SPECIFIER_WAVEFORMATEX  = {0x05589f81L, 0xc356, 0x11ce, {0xbf, 0x01, 0x00, 0xaa, 0x00, 0x55, 0x59, 0x5a}};
00013 const GUID KSDATAFORMAT_SUBTYPE_PCM             = {0x00000001L, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}};
00014 const GUID KSDATAFORMAT_TYPE_AUDIO              = {0x73647561L, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}};
00015 const GUID KSINTERFACESETID_Standard            = {0x1A8766A0L, 0x62CE, 0x11CF, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}};
00016 const GUID KSMEDIUMSETID_Standard               = {0x4747B320L, 0x62CE, 0x11CF, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}};
00017 
00018 typedef struct
00019 {
00020     ULONG SampleRate;
00021     ULONG Bit8Mono;
00022     ULONG Bit8Stereo;
00023     ULONG Bit16Mono;
00024     ULONG Bit16Stereo;
00025 }AUDIO_RANGE;
00026 
00027 #define AUDIO_TEST_RANGE (5)
00028 
00029 static AUDIO_RANGE TestRange[AUDIO_TEST_RANGE] =
00030 {
00031     {
00032         11025,
00033         WAVE_FORMAT_1M08,
00034         WAVE_FORMAT_1S08,
00035         WAVE_FORMAT_1M16,
00036         WAVE_FORMAT_1S16
00037     },
00038     {
00039         22050,
00040         WAVE_FORMAT_2M08,
00041         WAVE_FORMAT_2S08,
00042         WAVE_FORMAT_2M16,
00043         WAVE_FORMAT_2S16
00044     },
00045     {
00046         44100,
00047         WAVE_FORMAT_4M08,
00048         WAVE_FORMAT_4S08,
00049         WAVE_FORMAT_4M16,
00050         WAVE_FORMAT_4S16
00051     },
00052     {
00053         48000,
00054         WAVE_FORMAT_48M08,
00055         WAVE_FORMAT_48S08,
00056         WAVE_FORMAT_48M16,
00057         WAVE_FORMAT_48S16
00058     },
00059     {
00060         96000,
00061         WAVE_FORMAT_96M08,
00062         WAVE_FORMAT_96S08,
00063         WAVE_FORMAT_96M16,
00064         WAVE_FORMAT_96S16
00065     }
00066 };
00067 
00068 PKSPIN_CONNECT
00069 MMixerAllocatePinConnect(
00070     IN PMIXER_CONTEXT MixerContext,
00071     ULONG DataFormatSize)
00072 {
00073     return MixerContext->Alloc(sizeof(KSPIN_CONNECT) + DataFormatSize);
00074 }
00075 
00076 MIXER_STATUS
00077 MMixerGetWaveInfoByIndexAndType(
00078     IN  PMIXER_LIST MixerList,
00079     IN  ULONG DeviceIndex,
00080     IN  ULONG bWaveInType,
00081     OUT LPWAVE_INFO *OutWaveInfo)
00082 {
00083     ULONG Index = 0;
00084     PLIST_ENTRY Entry, ListHead;
00085     LPWAVE_INFO WaveInfo;
00086 
00087     if (bWaveInType)
00088         ListHead = &MixerList->WaveInList;
00089     else
00090         ListHead = &MixerList->WaveOutList;
00091 
00092     /* get first entry */
00093     Entry = ListHead->Flink;
00094 
00095     while(Entry != ListHead)
00096     {
00097         WaveInfo = (LPWAVE_INFO)CONTAINING_RECORD(Entry, WAVE_INFO, Entry);
00098 
00099         if (Index == DeviceIndex)
00100         {
00101             *OutWaveInfo = WaveInfo;
00102             return MM_STATUS_SUCCESS;
00103         }
00104         Index++;
00105         Entry = Entry->Flink;
00106     }
00107 
00108     return MM_STATUS_INVALID_PARAMETER;
00109 }
00110 
00111 
00112 
00113 
00114 VOID
00115 MMixerInitializeDataFormat(
00116     IN PKSDATAFORMAT_WAVEFORMATEX DataFormat,
00117     LPWAVEFORMATEX WaveFormatEx)
00118 {
00119 
00120     DataFormat->WaveFormatEx.wFormatTag = WaveFormatEx->wFormatTag;
00121     DataFormat->WaveFormatEx.nChannels = WaveFormatEx->nChannels;
00122     DataFormat->WaveFormatEx.nSamplesPerSec = WaveFormatEx->nSamplesPerSec;
00123     DataFormat->WaveFormatEx.nBlockAlign = WaveFormatEx->nBlockAlign;
00124     DataFormat->WaveFormatEx.nAvgBytesPerSec = WaveFormatEx->nAvgBytesPerSec;
00125     DataFormat->WaveFormatEx.wBitsPerSample = WaveFormatEx->wBitsPerSample;
00126     DataFormat->WaveFormatEx.cbSize = 0;
00127     DataFormat->DataFormat.FormatSize = sizeof(KSDATAFORMAT) + sizeof(WAVEFORMATEX);
00128     DataFormat->DataFormat.Flags = 0;
00129     DataFormat->DataFormat.Reserved = 0;
00130     DataFormat->DataFormat.MajorFormat = KSDATAFORMAT_TYPE_AUDIO;
00131 
00132     DataFormat->DataFormat.SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
00133     DataFormat->DataFormat.Specifier = KSDATAFORMAT_SPECIFIER_WAVEFORMATEX;
00134     DataFormat->DataFormat.SampleSize = 4;
00135 }
00136 
00137 
00138 MIXER_STATUS
00139 MMixerGetAudioPinDataRanges(
00140     IN PMIXER_CONTEXT MixerContext,
00141     IN HANDLE hDevice,
00142     IN ULONG PinId,
00143     IN OUT PKSMULTIPLE_ITEM * OutMultipleItem)
00144 {
00145     KSP_PIN PinProperty;
00146     ULONG BytesReturned = 0;
00147     MIXER_STATUS Status;
00148     PKSMULTIPLE_ITEM MultipleItem;
00149 
00150     /* retrieve size of data ranges buffer */
00151     PinProperty.Reserved = 0;
00152     PinProperty.PinId = PinId;
00153     PinProperty.Property.Set = KSPROPSETID_Pin;
00154     PinProperty.Property.Id = KSPROPERTY_PIN_DATARANGES;
00155     PinProperty.Property.Flags = KSPROPERTY_TYPE_GET;
00156 
00157     Status = MixerContext->Control(hDevice, IOCTL_KS_PROPERTY, (PVOID)&PinProperty, sizeof(KSP_PIN), (PVOID)NULL, 0, &BytesReturned);
00158     if (Status != MM_STATUS_MORE_ENTRIES)
00159     {
00160         return Status;
00161     }
00162 
00163     MultipleItem = MixerContext->Alloc(BytesReturned);
00164     if (!MultipleItem)
00165     {
00166         /* not enough memory */
00167         return MM_STATUS_NO_MEMORY;
00168     }
00169 
00170     Status = MixerContext->Control(hDevice, IOCTL_KS_PROPERTY, (PVOID)&PinProperty, sizeof(KSP_PIN), (PVOID)MultipleItem, BytesReturned, &BytesReturned);
00171     if (Status != MM_STATUS_SUCCESS)
00172     {
00173         /* failed */
00174         MixerContext->Free(MultipleItem);
00175         return Status;
00176     }
00177 
00178     /* save result */
00179     *OutMultipleItem = MultipleItem;
00180     return Status;
00181 }
00182 
00183 MIXER_STATUS
00184 MMixerFindAudioDataRange(
00185     PKSMULTIPLE_ITEM MultipleItem,
00186     PKSDATARANGE_AUDIO * OutDataRangeAudio)
00187 {
00188     ULONG Index;
00189     PKSDATARANGE_AUDIO DataRangeAudio;
00190     PKSDATARANGE DataRange;
00191 
00192     DataRange = (PKSDATARANGE) (MultipleItem + 1);
00193     for(Index = 0; Index < MultipleItem->Count; Index++)
00194     {
00195         if (DataRange->FormatSize == sizeof(KSDATARANGE_AUDIO))
00196         {
00197             DataRangeAudio = (PKSDATARANGE_AUDIO)DataRange;
00198             if (IsEqualGUIDAligned(&DataRangeAudio->DataRange.MajorFormat, &KSDATAFORMAT_TYPE_AUDIO) &&
00199                 IsEqualGUIDAligned(&DataRangeAudio->DataRange.SubFormat, &KSDATAFORMAT_SUBTYPE_PCM) &&
00200                 IsEqualGUIDAligned(&DataRangeAudio->DataRange.Specifier, &KSDATAFORMAT_SPECIFIER_WAVEFORMATEX))
00201             {
00202                 DPRINT("Min Sample %u Max Sample %u Min Bits %u Max Bits %u Max Channel %u\n", DataRangeAudio->MinimumSampleFrequency, DataRangeAudio->MaximumSampleFrequency,
00203                                                          DataRangeAudio->MinimumBitsPerSample, DataRangeAudio->MaximumBitsPerSample, DataRangeAudio->MaximumChannels);
00204                 *OutDataRangeAudio = DataRangeAudio;
00205                 return MM_STATUS_SUCCESS;
00206             }
00207         }
00208         DataRange = (PKSDATARANGE)((ULONG_PTR)DataRange + DataRange->FormatSize);
00209     }
00210     return MM_STATUS_UNSUCCESSFUL;
00211 }
00212 
00213 MIXER_STATUS
00214 MMixerOpenWavePin(
00215     IN PMIXER_CONTEXT MixerContext,
00216     IN PMIXER_LIST MixerList,
00217     IN ULONG DeviceId,
00218     IN ULONG PinId,
00219     IN LPWAVEFORMATEX WaveFormatEx,
00220     IN ACCESS_MASK DesiredAccess,
00221     IN PIN_CREATE_CALLBACK CreateCallback,
00222     IN PVOID Context,
00223     OUT PHANDLE PinHandle)
00224 {
00225     PKSPIN_CONNECT PinConnect;
00226     PKSDATAFORMAT_WAVEFORMATEX DataFormat;
00227     LPMIXER_DATA MixerData;
00228     NTSTATUS Status;
00229     MIXER_STATUS MixerStatus;
00230 
00231     MixerData = MMixerGetDataByDeviceId(MixerList, DeviceId);
00232     if (!MixerData)
00233         return MM_STATUS_INVALID_PARAMETER;
00234 
00235     /* allocate pin connect */
00236     PinConnect = MMixerAllocatePinConnect(MixerContext, sizeof(KSDATAFORMAT_WAVEFORMATEX));
00237     if (!PinConnect)
00238     {
00239         /* no memory */
00240         return MM_STATUS_NO_MEMORY;
00241     }
00242 
00243     /* initialize pin connect struct */
00244     MMixerInitializePinConnect(PinConnect, PinId);
00245 
00246     /* get offset to dataformat */
00247     DataFormat = (PKSDATAFORMAT_WAVEFORMATEX) (PinConnect + 1);
00248     /* initialize with requested wave format */
00249     MMixerInitializeDataFormat(DataFormat, WaveFormatEx);
00250 
00251     if (CreateCallback)
00252     {
00253         /* let the callback handle the creation */
00254         MixerStatus = CreateCallback(Context, DeviceId, PinId, MixerData->hDevice, PinConnect, DesiredAccess, PinHandle);
00255     }
00256     else
00257     {
00258         /* now create the pin */
00259         Status = KsCreatePin(MixerData->hDevice, PinConnect, DesiredAccess, PinHandle);
00260 
00261         /* normalize status */
00262         if (Status == STATUS_SUCCESS)
00263             MixerStatus = MM_STATUS_SUCCESS;
00264         else
00265             MixerStatus = MM_STATUS_UNSUCCESSFUL;
00266     }
00267 
00268     /* free create info */
00269     MixerContext->Free(PinConnect);
00270 
00271     /* done */
00272     return MixerStatus;
00273 }
00274 
00275 VOID
00276 MMixerCheckFormat(
00277     IN PKSDATARANGE_AUDIO DataRangeAudio,
00278     IN LPWAVE_INFO WaveInfo,
00279     IN ULONG bInput)
00280 {
00281     ULONG Index, SampleFrequency;
00282     ULONG Result = 0;
00283 
00284     for(Index = 0; Index < AUDIO_TEST_RANGE; Index++)
00285     {
00286         SampleFrequency = TestRange[Index].SampleRate;
00287 
00288         if (DataRangeAudio->MinimumSampleFrequency <= SampleFrequency && DataRangeAudio->MaximumSampleFrequency >= SampleFrequency)
00289         {
00290             /* the audio adapter supports the sample frequency */
00291             if (DataRangeAudio->MinimumBitsPerSample <= 8 && DataRangeAudio->MaximumBitsPerSample >= 8)
00292             {
00293                 Result |= TestRange[Index].Bit8Mono;
00294 
00295                 if (DataRangeAudio->MaximumChannels > 1)
00296                 {
00297                     /* check if pin supports the sample rate in 8-Bit Stereo */
00298                     Result |= TestRange[Index].Bit8Stereo;
00299                 }
00300             }
00301 
00302             if (DataRangeAudio->MinimumBitsPerSample <= 16 && DataRangeAudio->MaximumBitsPerSample >= 16)
00303             {
00304                 /* check if pin supports the sample rate in 16-Bit Mono */
00305                 Result |= TestRange[Index].Bit16Mono;
00306 
00307 
00308                 if (DataRangeAudio->MaximumChannels > 1)
00309                 {
00310                     /* check if pin supports the sample rate in 16-Bit Stereo */
00311                     Result |= TestRange[Index].Bit16Stereo;
00312                 }
00313             }
00314         }
00315     }
00316 
00317 
00318     if (bInput)
00319         WaveInfo->u.InCaps.dwFormats = Result;
00320     else
00321         WaveInfo->u.OutCaps.dwFormats = Result;
00322 
00323     DPRINT("Format %lx bInput %u\n", Result, bInput);
00324 }
00325 
00326 MIXER_STATUS
00327 MMixerInitializeWaveInfo(
00328     IN PMIXER_CONTEXT MixerContext,
00329     IN PMIXER_LIST MixerList,
00330     IN LPMIXER_DATA MixerData,
00331     IN LPWSTR DeviceName,
00332     IN ULONG bWaveIn,
00333     IN ULONG PinCount,
00334     IN PULONG Pins)
00335 {
00336     MIXER_STATUS Status;
00337     PKSMULTIPLE_ITEM MultipleItem;
00338     PKSDATARANGE_AUDIO DataRangeAudio;
00339     LPWAVE_INFO WaveInfo;
00340 
00341     WaveInfo = (LPWAVE_INFO)MixerContext->Alloc(sizeof(WAVE_INFO));
00342     if (!WaveInfo)
00343         return MM_STATUS_NO_MEMORY;
00344 
00345     if (PinCount > 1)
00346     {
00347         /* FIXME support multiple pins for wave device */
00348         DPRINT1("Implement support for multiple pins\n");
00349         //ASSERT(PinCount == 1);
00350     }
00351 
00352     /* initialize wave info */
00353     WaveInfo->DeviceId = MixerData->DeviceId;
00354     WaveInfo->PinId = Pins[0];
00355 
00356     /* sanity check */
00357     ASSERT(wcslen(DeviceName) + 1 < MAXPNAMELEN);
00358 
00359     /* copy device name */
00360     if (bWaveIn)
00361     {
00362         wcscpy(WaveInfo->u.InCaps.szPname, DeviceName);
00363     }
00364     else
00365     {
00366         wcscpy(WaveInfo->u.OutCaps.szPname, DeviceName);
00367     }
00368 
00369     /* FIXME determine manufacturer / product id */
00370     if (bWaveIn)
00371     {
00372         WaveInfo->u.InCaps.wMid = MM_MICROSOFT;
00373         WaveInfo->u.InCaps.wPid = MM_PID_UNMAPPED;
00374         WaveInfo->u.InCaps.vDriverVersion = 1;
00375     }
00376     else
00377     {
00378         WaveInfo->u.OutCaps.wMid = MM_MICROSOFT;
00379         WaveInfo->u.OutCaps.wPid = MM_PID_UNMAPPED;
00380         WaveInfo->u.OutCaps.vDriverVersion = 1;
00381     }
00382 
00383     /* get audio pin data ranges */
00384     Status = MMixerGetAudioPinDataRanges(MixerContext, MixerData->hDevice, Pins[0], &MultipleItem);
00385     if (Status != MM_STATUS_SUCCESS)
00386     {
00387         /* failed to get audio pin data ranges */
00388         MixerContext->Free(WaveInfo);
00389         return MM_STATUS_UNSUCCESSFUL;
00390     }
00391 
00392     /* find an KSDATARANGE_AUDIO range */
00393     Status = MMixerFindAudioDataRange(MultipleItem, &DataRangeAudio);
00394     if (Status != MM_STATUS_SUCCESS)
00395     {
00396         /* failed to find audio pin data range */
00397         MixerContext->Free(MultipleItem);
00398         MixerContext->Free(WaveInfo);
00399         return MM_STATUS_UNSUCCESSFUL;
00400     }
00401 
00402     /* store channel count */
00403     if (bWaveIn)
00404     {
00405         WaveInfo->u.InCaps.wChannels = DataRangeAudio->MaximumChannels;
00406     }
00407     else
00408     {
00409        WaveInfo->u.OutCaps.wChannels = DataRangeAudio->MaximumChannels;
00410     }
00411 
00412     /* get all supported formats */
00413     MMixerCheckFormat(DataRangeAudio, WaveInfo, bWaveIn);
00414 
00415     /* free dataranges buffer */
00416     MixerContext->Free(MultipleItem);
00417 
00418     if (bWaveIn)
00419     {
00420         InsertTailList(&MixerList->WaveInList, &WaveInfo->Entry);
00421         MixerList->WaveInListCount++;
00422     }
00423     else
00424     {
00425         InsertTailList(&MixerList->WaveOutList, &WaveInfo->Entry);
00426         MixerList->WaveOutListCount++;
00427     }
00428 
00429     return MM_STATUS_SUCCESS;
00430 }
00431 
00432 MIXER_STATUS
00433 MMixerOpenWave(
00434     IN PMIXER_CONTEXT MixerContext,
00435     IN ULONG DeviceIndex,
00436     IN ULONG bWaveIn,
00437     IN LPWAVEFORMATEX WaveFormat,
00438     IN PIN_CREATE_CALLBACK CreateCallback,
00439     IN PVOID Context,
00440     OUT PHANDLE PinHandle)
00441 {
00442     PMIXER_LIST MixerList;
00443     MIXER_STATUS Status;
00444     LPWAVE_INFO WaveInfo;
00445     ACCESS_MASK DesiredAccess = 0;
00446 
00447     /* verify mixer context */
00448     Status = MMixerVerifyContext(MixerContext);
00449 
00450     if (Status != MM_STATUS_SUCCESS)
00451     {
00452         /* invalid context passed */
00453         return Status;
00454     }
00455 
00456     /* grab mixer list */
00457     MixerList = (PMIXER_LIST)MixerContext->MixerContext;
00458 
00459     if (WaveFormat->wFormatTag != WAVE_FORMAT_PCM)
00460     {
00461         /* not implemented */
00462         return MM_STATUS_NOT_IMPLEMENTED;
00463     }
00464 
00465     /* find destination wave */
00466     Status = MMixerGetWaveInfoByIndexAndType(MixerList, DeviceIndex, bWaveIn, &WaveInfo);
00467     if (Status != MM_STATUS_SUCCESS)
00468     {
00469         /* failed to find wave info */
00470         return MM_STATUS_INVALID_PARAMETER;
00471     }
00472 
00473     /* get desired access */
00474     if (bWaveIn)
00475     {
00476         DesiredAccess |= GENERIC_READ;
00477     }
00478      else
00479     {
00480         DesiredAccess |= GENERIC_WRITE;
00481     }
00482 
00483     /* now try open the pin */
00484     return MMixerOpenWavePin(MixerContext, MixerList, WaveInfo->DeviceId, WaveInfo->PinId, WaveFormat, DesiredAccess, CreateCallback, Context, PinHandle);
00485 }
00486 
00487 MIXER_STATUS
00488 MMixerWaveInCapabilities(
00489     IN PMIXER_CONTEXT MixerContext,
00490     IN ULONG DeviceIndex,
00491     OUT LPWAVEINCAPSW Caps)
00492 {
00493     PMIXER_LIST MixerList;
00494     MIXER_STATUS Status;
00495     LPWAVE_INFO WaveInfo;
00496 
00497     /* verify mixer context */
00498     Status = MMixerVerifyContext(MixerContext);
00499 
00500     if (Status != MM_STATUS_SUCCESS)
00501     {
00502         /* invalid context passed */
00503         return Status;
00504     }
00505 
00506     /* grab mixer list */
00507     MixerList = (PMIXER_LIST)MixerContext->MixerContext;
00508 
00509     /* find destination wave */
00510     Status = MMixerGetWaveInfoByIndexAndType(MixerList, DeviceIndex, TRUE, &WaveInfo);
00511     if (Status != MM_STATUS_SUCCESS)
00512     {
00513         /* failed to find wave info */
00514         return MM_STATUS_UNSUCCESSFUL;
00515     }
00516 
00517     /* copy capabilities */
00518     MixerContext->Copy(Caps, &WaveInfo->u.InCaps, sizeof(WAVEINCAPSW));
00519 
00520     return MM_STATUS_SUCCESS;
00521 }
00522 
00523 MIXER_STATUS
00524 MMixerWaveOutCapabilities(
00525     IN PMIXER_CONTEXT MixerContext,
00526     IN ULONG DeviceIndex,
00527     OUT LPWAVEOUTCAPSW Caps)
00528 {
00529     PMIXER_LIST MixerList;
00530     MIXER_STATUS Status;
00531     LPWAVE_INFO WaveInfo;
00532 
00533     /* verify mixer context */
00534     Status = MMixerVerifyContext(MixerContext);
00535 
00536     if (Status != MM_STATUS_SUCCESS)
00537     {
00538         /* invalid context passed */
00539         return Status;
00540     }
00541 
00542     /* grab mixer list */
00543     MixerList = (PMIXER_LIST)MixerContext->MixerContext;
00544 
00545     /* find destination wave */
00546     Status = MMixerGetWaveInfoByIndexAndType(MixerList, DeviceIndex, FALSE, &WaveInfo);
00547     if (Status != MM_STATUS_SUCCESS)
00548     {
00549         /* failed to find wave info */
00550         return MM_STATUS_UNSUCCESSFUL;
00551     }
00552 
00553     /* copy capabilities */
00554     MixerContext->Copy(Caps, &WaveInfo->u.OutCaps, sizeof(WAVEOUTCAPSW));
00555 
00556     return MM_STATUS_SUCCESS;
00557 }
00558 
00559 ULONG
00560 MMixerGetWaveInCount(
00561     IN PMIXER_CONTEXT MixerContext)
00562 {
00563     PMIXER_LIST MixerList;
00564     MIXER_STATUS Status;
00565 
00566      /* verify mixer context */
00567     Status = MMixerVerifyContext(MixerContext);
00568 
00569     if (Status != MM_STATUS_SUCCESS)
00570     {
00571         /* invalid context passed */
00572         return Status;
00573     }
00574 
00575     /* grab mixer list */
00576     MixerList = (PMIXER_LIST)MixerContext->MixerContext;
00577 
00578     return MixerList->WaveInListCount;
00579 }
00580 
00581 ULONG
00582 MMixerGetWaveOutCount(
00583     IN PMIXER_CONTEXT MixerContext)
00584 {
00585     PMIXER_LIST MixerList;
00586     MIXER_STATUS Status;
00587 
00588     /* verify mixer context */
00589     Status = MMixerVerifyContext(MixerContext);
00590 
00591     if (Status != MM_STATUS_SUCCESS)
00592     {
00593         /* invalid context passed */
00594         return Status;
00595     }
00596 
00597     /* grab mixer list */
00598     MixerList = (PMIXER_LIST)MixerContext->MixerContext;
00599 
00600     return MixerList->WaveOutListCount;
00601 }
00602 
00603 MIXER_STATUS
00604 MMixerSetWaveStatus(
00605     IN PMIXER_CONTEXT MixerContext,
00606     IN HANDLE PinHandle,
00607     IN KSSTATE State)
00608 {
00609     KSPROPERTY Property;
00610     ULONG Length;
00611     MIXER_STATUS Status;
00612 
00613     /* verify mixer context */
00614     Status = MMixerVerifyContext(MixerContext);
00615 
00616     if (Status != MM_STATUS_SUCCESS)
00617     {
00618         /* invalid context passed */
00619         return Status;
00620     }
00621 
00622     /* setup property request */
00623     Property.Set = KSPROPSETID_Connection;
00624     Property.Id = KSPROPERTY_CONNECTION_STATE;
00625     Property.Flags = KSPROPERTY_TYPE_SET;
00626 
00627     return MixerContext->Control(PinHandle, IOCTL_KS_PROPERTY, &Property, sizeof(KSPROPERTY), &State, sizeof(KSSTATE), &Length);
00628 }
00629 
00630 MIXER_STATUS
00631 MMixerSetWaveResetState(
00632     IN PMIXER_CONTEXT MixerContext,
00633     IN HANDLE PinHandle,
00634     IN ULONG bBegin)
00635 {
00636     ULONG Length;
00637     MIXER_STATUS Status;
00638     KSRESET Reset;
00639 
00640     /* verify mixer context */
00641     Status = MMixerVerifyContext(MixerContext);
00642 
00643     if (Status != MM_STATUS_SUCCESS)
00644     {
00645         /* invalid context passed */
00646         return Status;
00647     }
00648 
00649     /* begin / stop reset */
00650     Reset = (bBegin ? KSRESET_BEGIN : KSRESET_END);
00651 
00652     return MixerContext->Control(PinHandle, IOCTL_KS_RESET_STATE, &Reset, sizeof(KSRESET), NULL, 0, &Length);
00653 }
00654 
00655 MIXER_STATUS
00656 MMixerGetWaveDevicePath(
00657     IN PMIXER_CONTEXT MixerContext,
00658     IN ULONG bWaveIn,
00659     IN ULONG DeviceId,
00660     OUT LPWSTR * DevicePath)
00661 {
00662     PMIXER_LIST MixerList;
00663     LPMIXER_DATA MixerData;
00664     LPWAVE_INFO WaveInfo;
00665     ULONG Length;
00666     MIXER_STATUS Status;
00667 
00668     /* verify mixer context */
00669     Status = MMixerVerifyContext(MixerContext);
00670 
00671     if (Status != MM_STATUS_SUCCESS)
00672     {
00673         /* invalid context passed */
00674         return Status;
00675     }
00676 
00677     /* grab mixer list */
00678     MixerList = (PMIXER_LIST)MixerContext->MixerContext;
00679 
00680     /* find destination wave */
00681     Status = MMixerGetWaveInfoByIndexAndType(MixerList, DeviceId, bWaveIn, &WaveInfo);
00682     if (Status != MM_STATUS_SUCCESS)
00683     {
00684         /* failed to find wave info */
00685         return MM_STATUS_INVALID_PARAMETER;
00686     }
00687 
00688     /* get associated device id */
00689     MixerData = MMixerGetDataByDeviceId(MixerList, WaveInfo->DeviceId);
00690     if (!MixerData)
00691         return MM_STATUS_INVALID_PARAMETER;
00692 
00693     /* calculate length */
00694     Length = wcslen(MixerData->DeviceName)+1;
00695 
00696     /* allocate destination buffer */
00697     *DevicePath = MixerContext->Alloc(Length * sizeof(WCHAR));
00698 
00699     if (!*DevicePath)
00700     {
00701         /* no memory */
00702         return MM_STATUS_NO_MEMORY;
00703     }
00704 
00705     /* copy device path */
00706     MixerContext->Copy(*DevicePath, MixerData->DeviceName, Length * sizeof(WCHAR));
00707 
00708     /* done */
00709     return MM_STATUS_SUCCESS;
00710 }
00711 

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