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

audio_test.c
Go to the documentation of this file.
00001 #define _UNICODE
00002 #define UNICODE
00003 #define WIN32_NO_STATUS
00004 #define _KSDDK_
00005 
00006 #include <windows.h>
00007 #include <stdio.h>
00008 #include <math.h>
00009 #include <setupapi.h>
00010 #include <ndk/umtypes.h>
00011 #include <ksmedia.h>
00012 #include "interface.h"
00013 
00014 #define _2pi                6.283185307179586476925286766559
00015 
00016 GUID CategoryGuid = {STATIC_KSCATEGORY_AUDIO};
00017 
00018 const GUID KSPROPSETID_Pin                     = {0x8C134960L, 0x51AD, 0x11CF, {0x87, 0x8A, 0x94, 0xF8, 0x01, 0xC1, 0x00, 0x00}};
00019 const GUID KSPROPSETID_Connection               = {0x1D58C920L, 0xAC9B, 0x11CF, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}};
00020 const GUID KSPROPSETID_Sysaudio                 = {0xCBE3FAA0L, 0xCC75, 0x11D0, {0xB4, 0x65, 0x00, 0x00, 0x1A, 0x18, 0x18, 0xE6}};
00021 const GUID KSPROPSETID_General                  = {0x1464EDA5L, 0x6A8F, 0x11D1, {0x9A, 0xA7, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}};
00022 const GUID KSINTERFACESETID_Standard            = {0x1A8766A0L, 0x62CE, 0x11CF, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}};
00023 const GUID KSMEDIUMSETID_Standard               = {0x4747B320L, 0x62CE, 0x11CF, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}};
00024 const GUID KSDATAFORMAT_TYPE_AUDIO              = {0x73647561L, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}};
00025 const GUID KSDATAFORMAT_SUBTYPE_PCM             = {0x00000001L, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}};
00026 const GUID KSDATAFORMAT_SPECIFIER_WAVEFORMATEX  = {0x05589f81L, 0xc356, 0x11ce, {0xbf, 0x01, 0x00, 0xaa, 0x00, 0x55, 0x59, 0x5a}};
00027 
00028 VOID
00029 TestKs()
00030 {
00031     SP_DEVICE_INTERFACE_DATA InterfaceData;
00032     SP_DEVINFO_DATA DeviceData;
00033     PSP_DEVICE_INTERFACE_DETAIL_DATA DetailData;
00034     HDEVINFO DeviceHandle;
00035     PKSDATAFORMAT_WAVEFORMATEX DataFormat;
00036     PKSPIN_CONNECT PinConnect;
00037     PKSSTREAM_HEADER Packet;
00038     PKSPROPERTY Property;
00039     KSSTATE State;
00040     DWORD Length;
00041     HANDLE FilterHandle; 
00042     HANDLE PinHandle;
00043     PSHORT SoundBuffer;
00044     UINT i = 0;
00045     BOOL Result;
00046     NTSTATUS Status;
00047 
00048   //
00049     // Get a handle to KS Audio Interfaces
00050     //
00051     DeviceHandle = SetupDiGetClassDevs(&CategoryGuid,
00052                                        NULL,
00053                                        NULL,
00054                                        DIGCF_DEVICEINTERFACE); //DIGCF_PRESENT
00055 
00056    printf("DeviceHandle %p\n", DeviceHandle);
00057 
00058     //
00059     // Enumerate the first interface
00060     //
00061     InterfaceData.cbSize = sizeof(InterfaceData);
00062     InterfaceData.Reserved = 0;
00063     Result = SetupDiEnumDeviceInterfaces(DeviceHandle,
00064                                 NULL,
00065                                 &CategoryGuid,
00066                                 1,
00067                                 &InterfaceData);
00068 
00069    printf("SetupDiEnumDeviceInterfaces %u Error %ld\n", Result, GetLastError());
00070 
00071     //
00072     // Get the interface details (namely the device path)
00073     //
00074     Length = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA) + MAX_PATH * sizeof(WCHAR);
00075     DetailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)HeapAlloc(GetProcessHeap(),
00076                                                              0,
00077                                                              Length);
00078     DetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
00079     DeviceData.cbSize = sizeof(DeviceData);
00080     DeviceData.Reserved = 0;
00081     Result = SetupDiGetDeviceInterfaceDetail(DeviceHandle,
00082                                     &InterfaceData,
00083                                     DetailData,
00084                                     Length,
00085                                     NULL,
00086                                     &DeviceData);
00087 
00088     wprintf(L"SetupDiGetDeviceInterfaceDetail %u Path DetailData %s\n", Result, (LPWSTR)&DetailData->DevicePath[0]);
00089 
00090     //
00091     // Open a handle to the device
00092     //
00093     FilterHandle = CreateFile(DetailData->DevicePath,
00094                               GENERIC_READ | GENERIC_WRITE,
00095                               0,
00096                               NULL,
00097                               OPEN_EXISTING,
00098                               FILE_ATTRIBUTE_NORMAL,
00099                               NULL);
00100 
00101     printf("Handle %p\n", FilterHandle);
00102 
00103     //
00104     // Close the interface handle and clean up
00105     //
00106     SetupDiDestroyDeviceInfoList(DeviceHandle);
00107 
00108     //
00109     // Allocate a KS Pin Connection Request Structure
00110     //
00111     Length = sizeof(KSPIN_CONNECT) + sizeof(KSDATAFORMAT_WAVEFORMATEX);
00112     printf("Length %ld KSPIN %u DATAFORMAT %u\n", Length, sizeof(KSPIN_CONNECT), sizeof(KSDATAFORMAT_WAVEFORMATEX));
00113     PinConnect = (PKSPIN_CONNECT)HeapAlloc(GetProcessHeap(), 0, Length);
00114     DataFormat = (PKSDATAFORMAT_WAVEFORMATEX)(PinConnect + 1);
00115 
00116     //
00117     // Setup the KS Pin Data
00118     //
00119     PinConnect->Interface.Set = KSINTERFACESETID_Standard;
00120     PinConnect->Interface.Id = KSINTERFACE_STANDARD_STREAMING;
00121     PinConnect->Interface.Flags = 0;
00122     PinConnect->Medium.Set = KSMEDIUMSETID_Standard;
00123     PinConnect->Medium.Id = KSMEDIUM_TYPE_ANYINSTANCE;
00124     PinConnect->Medium.Flags = 0;
00125     PinConnect->PinId = 0;
00126     PinConnect->PinToHandle = NULL;
00127     PinConnect->Priority.PriorityClass = KSPRIORITY_NORMAL;
00128     PinConnect->Priority.PrioritySubClass = 1;
00129 
00130     //
00131     // Setup the KS Data Format Information
00132     //
00133     DataFormat->WaveFormatEx.wFormatTag = WAVE_FORMAT_PCM;
00134     DataFormat->WaveFormatEx.nChannels = 2;
00135     DataFormat->WaveFormatEx.nSamplesPerSec = 48000;
00136     DataFormat->WaveFormatEx.nBlockAlign = 4;
00137     DataFormat->WaveFormatEx.nAvgBytesPerSec = 48000 * 4;
00138     DataFormat->WaveFormatEx.wBitsPerSample = 16;
00139     DataFormat->WaveFormatEx.cbSize = 0;
00140     DataFormat->DataFormat.FormatSize = sizeof(KSDATAFORMAT) +
00141                                         sizeof(WAVEFORMATEX);
00142     DataFormat->DataFormat.Flags = KSDATAFORMAT_ATTRIBUTES;
00143     DataFormat->DataFormat.Reserved = 0;
00144     DataFormat->DataFormat.MajorFormat = KSDATAFORMAT_TYPE_AUDIO;
00145     DataFormat->DataFormat.SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
00146     DataFormat->DataFormat.Specifier = KSDATAFORMAT_SPECIFIER_WAVEFORMATEX;
00147     DataFormat->DataFormat.SampleSize = 4;
00148 
00149     //
00150     // Create the pin
00151     //
00152     Status = KsCreatePin(FilterHandle, PinConnect, GENERIC_WRITE, &PinHandle);
00153 
00154     printf("PinHandle %p Status %lx\n", PinHandle, Status);
00155 
00156     //
00157     // Allocate a buffer for 1 second
00158     //
00159     Length = 48000 * 4;
00160     SoundBuffer = (PSHORT)HeapAlloc(GetProcessHeap(), 0, Length);
00161 
00162     //
00163     // Fill the buffer with a 500 Hz sine tone
00164     //
00165     while (i < Length / 2)
00166     {
00167         //
00168         // Generate the wave for each channel:
00169         // Amplitude * sin( Sample * Frequency * 2PI / SamplesPerSecond )
00170         //
00171         SoundBuffer[i] = 0x7FFF * sin(0.5 * (i - 1) * 500 * _2pi / 48000);
00172         i++;
00173         SoundBuffer[i] = 0x7FFF * sin((0.5 * i - 2) * 500 * _2pi / 48000);
00174         i++;
00175     }
00176 
00177     //
00178     // Create and fill out the KS Stream Packet
00179     //
00180     Packet = (PKSSTREAM_HEADER)HeapAlloc(GetProcessHeap(),
00181                                          HEAP_ZERO_MEMORY,
00182                                          sizeof(KSSTREAM_HEADER));
00183     Packet->Data = SoundBuffer;
00184     Packet->FrameExtent = Length;
00185     Packet->DataUsed = Length;
00186     Packet->Size = sizeof(KSSTREAM_HEADER);
00187     Packet->PresentationTime.Numerator = 1;
00188     Packet->PresentationTime.Denominator = 1;
00189 
00190     //
00191     // Setup a KS Property to change the state
00192     //
00193     Property = (PKSPROPERTY)HeapAlloc(GetProcessHeap(), 0, sizeof(KSPROPERTY));
00194     Property->Set = KSPROPSETID_Connection;
00195     Property->Id = KSPROPERTY_CONNECTION_STATE;
00196     Property->Flags = KSPROPERTY_TYPE_SET;
00197 
00198     //
00199     // Change the state to run
00200     //
00201     State = KSSTATE_RUN;
00202     DeviceIoControl(PinHandle,
00203                     IOCTL_KS_PROPERTY,
00204                     Property,
00205                     sizeof(KSPROPERTY),
00206                     &State,
00207                     sizeof(State),
00208                     &Length,
00209                     NULL);
00210 
00211     //
00212     // Play our 1-second buffer
00213     //
00214     DeviceIoControl(PinHandle,
00215                     IOCTL_KS_WRITE_STREAM,
00216                     NULL,
00217                     0,
00218                     Packet,
00219                     Packet->Size,
00220                     &Length,
00221                     NULL);
00222 
00223     //
00224     // Change the state to stop
00225     //
00226     State = KSSTATE_STOP;
00227     DeviceIoControl(PinHandle,
00228                     IOCTL_KS_PROPERTY,
00229                     Property,
00230                     sizeof(KSPROPERTY),
00231                     &State,
00232                     sizeof(State),
00233                     &Length,
00234                     NULL);
00235 
00236     CloseHandle(PinHandle);
00237     CloseHandle(FilterHandle);
00238 }
00239 
00240 int
00241 __cdecl
00242 main(int argc, char* argv[])
00243 {
00244     ULONG Length;
00245     PSHORT SoundBuffer;
00246     ULONG i = 0;
00247     BOOL Status;
00248     OVERLAPPED Overlapped;
00249     DWORD BytesReturned;
00250     HANDLE hWdmAud;
00251     WDMAUD_DEVICE_INFO DeviceInfo;
00252 
00253     TestKs();
00254     return 0;
00255 
00256     hWdmAud = CreateFileW(L"\\\\.\\wdmaud",
00257                           GENERIC_READ | GENERIC_WRITE,
00258                           0,
00259                           NULL,
00260                           OPEN_EXISTING,
00261                           FILE_FLAG_OVERLAPPED,
00262                           NULL);
00263      if (!hWdmAud)
00264      {
00265          printf("Failed to open wdmaud with %lx\n", GetLastError());
00266          return -1;
00267      }
00268 
00269      printf("WDMAUD: opened\n");
00270 
00271      /* clear device info */
00272      RtlZeroMemory(&DeviceInfo, sizeof(WDMAUD_DEVICE_INFO));
00273 
00274      ZeroMemory(&Overlapped, sizeof(OVERLAPPED));
00275      Overlapped.hEvent = CreateEventW(NULL, FALSE, FALSE, NULL);
00276 
00277      DeviceInfo.DeviceType = WAVE_OUT_DEVICE_TYPE;
00278 
00279 
00280      Status = DeviceIoControl(hWdmAud, IOCTL_GETNUMDEVS_TYPE, (LPVOID)&DeviceInfo, sizeof(WDMAUD_DEVICE_INFO), (LPVOID)&DeviceInfo, sizeof(WDMAUD_DEVICE_INFO), &BytesReturned, &Overlapped);
00281 
00282      if (!Status)
00283      {
00284          if (WaitForSingleObject(&Overlapped.hEvent, 5000) != WAIT_OBJECT_0)
00285          {
00286             printf("Failed to get num of wave out devices with %lx\n", GetLastError());
00287             CloseHandle(hWdmAud);
00288             return -1;
00289          }
00290      }
00291 
00292      printf("WDMAUD: Num Devices %lu\n", DeviceInfo.DeviceCount);
00293 
00294      if (!DeviceInfo.DeviceCount)
00295      {
00296         CloseHandle(hWdmAud);
00297         return 0;
00298     }
00299 
00300     Status = DeviceIoControl(hWdmAud, IOCTL_GETCAPABILITIES, (LPVOID)&DeviceInfo, sizeof(WDMAUD_DEVICE_INFO), (LPVOID)&DeviceInfo, sizeof(WDMAUD_DEVICE_INFO), &BytesReturned, &Overlapped);
00301 
00302     if (!Status)
00303     {
00304         if (WaitForSingleObject(&Overlapped.hEvent, 5000) != WAIT_OBJECT_0)
00305         {
00306            printf("Failed to get iocaps %lx\n", GetLastError());
00307         }
00308     }
00309     printf("WDMAUD: Capabilites NumChannels %x dwFormats %lx\n", DeviceInfo.u.WaveOutCaps.wChannels, DeviceInfo.u.WaveOutCaps.dwFormats);
00310 
00311     DeviceInfo.u.WaveFormatEx.cbSize = sizeof(WAVEFORMATEX);
00312     DeviceInfo.u.WaveFormatEx.wFormatTag = WAVE_FORMAT_PCM;
00313     DeviceInfo.u.WaveFormatEx.nChannels = 2;
00314     DeviceInfo.u.WaveFormatEx.nSamplesPerSec = 48000;
00315     DeviceInfo.u.WaveFormatEx.nBlockAlign = 4;
00316     DeviceInfo.u.WaveFormatEx.nAvgBytesPerSec = 48000 * 4;
00317     DeviceInfo.u.WaveFormatEx.wBitsPerSample = 16;
00318 
00319 
00320 
00321      Status = DeviceIoControl(hWdmAud, IOCTL_OPEN_WDMAUD, (LPVOID)&DeviceInfo, sizeof(WDMAUD_DEVICE_INFO), &DeviceInfo, sizeof(WDMAUD_DEVICE_INFO), &BytesReturned, &Overlapped);
00322      if (!Status)
00323      {
00324          if (WaitForSingleObject(&Overlapped.hEvent, 5000) != WAIT_OBJECT_0)
00325          {
00326              printf("Failed to open device with %lx\n", GetLastError());
00327              CloseHandle(hWdmAud);
00328              return -1;
00329          }
00330      }
00331 
00332      printf("WDMAUD: opened device\n");
00333 
00334     //
00335     // Allocate a buffer for 1 second
00336     //
00337     Length = 48000 * 4;
00338     SoundBuffer = (PSHORT)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, Length);
00339 
00340     //
00341     // Fill the buffer with a 500 Hz sine tone
00342     //
00343     while (i < Length / 2)
00344     {
00345         //
00346         // Generate the wave for each channel:
00347         // Amplitude * sin( Sample * Frequency * 2PI / SamplesPerSecond )
00348         //
00349         SoundBuffer[i] = 0x7FFF * sin(0.5 * (i - 1) * 500 * _2pi / 48000);
00350         i++;
00351         SoundBuffer[i] = 0x7FFF * sin((0.5 * i - 2) * 500 * _2pi / 48000);
00352         i++;
00353     }
00354 
00355     DeviceInfo.u.State = KSSTATE_RUN;
00356     Status = DeviceIoControl(hWdmAud, IOCTL_SETDEVICE_STATE, (LPVOID)&DeviceInfo, sizeof(WDMAUD_DEVICE_INFO), &DeviceInfo, sizeof(WDMAUD_DEVICE_INFO), &BytesReturned, &Overlapped);
00357     if (!Status)
00358     {
00359          if (WaitForSingleObject(&Overlapped.hEvent, 5000) != WAIT_OBJECT_0)
00360          {
00361              printf("Failed to set device into run state %lx\n", GetLastError());
00362              CloseHandle(hWdmAud);
00363              return -1;
00364          }
00365     }
00366     
00367     //
00368     // Play our 1-second buffer
00369     //
00370     DeviceInfo.Header.Data = (PUCHAR)SoundBuffer;
00371     DeviceInfo.Header.DataUsed = DeviceInfo.Header.FrameExtent = Length;
00372     Status = DeviceIoControl(hWdmAud, IOCTL_WRITEDATA, (LPVOID)&DeviceInfo, sizeof(WDMAUD_DEVICE_INFO), &DeviceInfo, sizeof(WDMAUD_DEVICE_INFO), &BytesReturned, &Overlapped);
00373     if (!Status)
00374     {
00375          if (WaitForSingleObject(&Overlapped.hEvent, 5000) != WAIT_OBJECT_0)
00376          {
00377              printf("Failed to play buffer %lx\n", GetLastError());
00378              CloseHandle(hWdmAud);
00379              return -1;
00380          }
00381     }
00382 
00383     printf("WDMAUD:  Played buffer\n");
00384 
00385     DeviceInfo.u.State = KSSTATE_STOP;
00386     Status = DeviceIoControl(hWdmAud, IOCTL_SETDEVICE_STATE, (LPVOID)&DeviceInfo, sizeof(WDMAUD_DEVICE_INFO), &DeviceInfo, sizeof(WDMAUD_DEVICE_INFO), &BytesReturned, &Overlapped);
00387     if (!Status)
00388     {
00389          if (WaitForSingleObject(&Overlapped.hEvent, 5000) != WAIT_OBJECT_0)
00390          {
00391              printf("Failed to set device into stop state %lx\n", GetLastError());
00392              CloseHandle(hWdmAud);
00393             return -1;
00394          }
00395     }
00396     printf("WDMAUD:  STOPPED\n");
00397     CloseHandle(&Overlapped.hEvent);
00398     CloseHandle(hWdmAud);
00399     printf("WDMAUD:  COMPLETE\n");
00400     return 0;
00401 }

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