mirror of
https://github.com/reactos/reactos.git
synced 2024-12-27 17:44:45 +00:00
*Major soundcard support update*
ReactOS remains silent for now, but for anyone wishing to further work on the Sound Blaster driver and/or mmdrv.dll, this should help immensely :) - Imported midimap from WINE - Imported wavemap from WINE - Imported msacm from WINE (32-bit only) - Minor changes to mpu401 - Basic IRP_MJ_WRITE dispatch routine for sndblst.sys (receives buffers, does nothing else.) - Added various WINE headers to include\wine svn path=/trunk/; revision=8620
This commit is contained in:
parent
69208dc611
commit
a306af21c2
63 changed files with 8517 additions and 31 deletions
|
@ -31,8 +31,8 @@ HKLM,"SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList","ProfilesDirecto
|
|||
;HKLM,"SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList","AllUsersProfile",0x00000000,"All Users.REACTOS"
|
||||
;HKLM,"SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList","DefaultUserProfile",0x00000000,"Default User.REACTOS"
|
||||
|
||||
;HKLM,"SOFTWARE\ReactOS\Windows NT\CurrentVersion\Winlogon","Shell",0x00020000,"%SystemRoot%\system32\cmd.exe"
|
||||
HKLM,"SOFTWARE\ReactOS\Windows NT\CurrentVersion\Winlogon","Shell",0x00020000,"%SystemRoot%\explorer.exe"
|
||||
HKLM,"SOFTWARE\ReactOS\Windows NT\CurrentVersion\Winlogon","Shell",0x00020000,"%SystemRoot%\system32\cmd.exe"
|
||||
;HKLM,"SOFTWARE\ReactOS\Windows NT\CurrentVersion\Winlogon","Shell",0x00020000,"%SystemRoot%\explorer.exe"
|
||||
HKLM,"SOFTWARE\ReactOS\Windows NT\CurrentVersion\Winlogon","StartServices",0x00010001,0x00000001
|
||||
HKLM,"SOFTWARE\ReactOS\Windows NT\CurrentVersion\Winlogon","StartGUI",0x00010001,0x00000000
|
||||
HKLM,"SOFTWARE\ReactOS\Windows NT\CurrentVersion\Winlogon","Userinit",0x00020000,"%SystemRoot%\system32\userinit.exe"
|
||||
|
|
|
@ -238,6 +238,59 @@ HKLM,"SYSTEM\CurrentControlSet\Services\Keyboard","ImagePath",0x00020000,"system
|
|||
HKLM,"SYSTEM\CurrentControlSet\Services\Keyboard","Start",0x00010001,0x00000001
|
||||
HKLM,"SYSTEM\CurrentControlSet\Services\Keyboard","Type",0x00010001,0x00000001
|
||||
|
||||
; SB16 driver
|
||||
;HKLM,"SYSTEM\CurrentControlSet\Services\sb16snd","Group",0x00000000,"Base"
|
||||
;HKLM,"SYSTEM\CurrentControlSet\Services\sb16snd","ServiceType",0x00010001,0x00000001
|
||||
;HKLM,"SYSTEM\CurrentControlSet\Services\sb16snd","Type",0x00010001,0x00000001
|
||||
;HKLM,"SYSTEM\CurrentControlSet\Services\sb16snd","Start",0x00010001,0x00000001
|
||||
;HKLM,"SYSTEM\CurrentControlSet\Services\sb16snd","ErrorControl",0x00010001,0x00000001
|
||||
;HKLM,"SYSTEM\CurrentControlSet\Services\sb16snd","ImagePath",0x00020000,"system32\drivers\sb16snd.sys"
|
||||
;HKLM,"SYSTEM\CurrentControlSet\Services\sb16snd\Parameters\Device0","DmaChannel",0x00010001,0x00000001
|
||||
;HKLM,"SYSTEM\CurrentControlSet\Services\sb16snd\Parameters\Device0","DmaChannel16",0x00010001,0x00000005
|
||||
;HKLM,"SYSTEM\CurrentControlSet\Services\sb16snd\Parameters\Device0","Port",0x00010001,0x00000220
|
||||
;HKLM,"SYSTEM\CurrentControlSet\Services\sb16snd\Parameters\Device0","Interrupt",0x00010001,0x00000005
|
||||
;HKLM,"SYSTEM\CurrentControlSet\Services\sb16snd\Parameters\Device0","DSP Version",0x00010001,0x00000401
|
||||
;HKLM,"SYSTEM\CurrentControlSet\Services\sb16snd\Parameters\Device0\Devices","SBWaveIn0",0x00010001,0x00000001
|
||||
;HKLM,"SYSTEM\CurrentControlSet\Services\sb16snd\Parameters\Device0\Devices","SBWaveOut0",0x00010001,0x00000002
|
||||
|
||||
|
||||
HKLM,"SYSTEM\CurrentControlSet\Services\sb16snd","Group",0x00000000,"Base"
|
||||
HKLM,"SYSTEM\CurrentControlSet\Services\sb16snd","ServiceType",0x00010001,0x00000001
|
||||
HKLM,"SYSTEM\CurrentControlSet\Services\sb16snd","Type",0x00010001,0x00000001
|
||||
HKLM,"SYSTEM\CurrentControlSet\Services\sb16snd","Start",0x00010001,0x00000001
|
||||
HKLM,"SYSTEM\CurrentControlSet\Services\sb16snd","ErrorControl",0x00010001,0x00000001
|
||||
HKLM,"SYSTEM\CurrentControlSet\Services\sb16snd","ImagePath",0x00020000,"system32\drivers\sndblst.sys"
|
||||
|
||||
|
||||
HKLM,"SYSTEM\CurrentControlSet\Services\es137140","Group",0x00000000,"Base"
|
||||
HKLM,"SYSTEM\CurrentControlSet\Services\es137140","ServiceType",0x00010001,0x00000001
|
||||
HKLM,"SYSTEM\CurrentControlSet\Services\es137140","Type",0x00010001,0x00000001
|
||||
HKLM,"SYSTEM\CurrentControlSet\Services\es137140","Start",0x00010001,0x00000001
|
||||
HKLM,"SYSTEM\CurrentControlSet\Services\es137140","ErrorControl",0x00010001,0x00000001
|
||||
HKLM,"SYSTEM\CurrentControlSet\Services\es137140","ImagePath",0x00020000,"system32\drivers\es137140.sys"
|
||||
HKLM,"SYSTEM\CurrentControlSet\Services\es137140","DisplayName",0x00020000,"ENSONIQ AudioPCI"
|
||||
HKLM,"SYSTEM\CurrentControlSet\Services\es137140\Parameters\Device0","Configuration Error",0x00010001,0xffffffff
|
||||
HKLM,"SYSTEM\CurrentControlSet\Services\es137140\Parameters\Device0","Joystick",0x00010001,0x00000001
|
||||
HKLM,"SYSTEM\CurrentControlSet\Services\es137140\Parameters\Device0","Port",0x00010001,0x00001080
|
||||
HKLM,"SYSTEM\CurrentControlSet\Services\es137140\Parameters\Device0","Interrupt",0x00010001,0x00000044
|
||||
HKLM,"SYSTEM\CurrentControlSet\Services\es137140\Parameters\Device0","RequestedSystemResources",0x00000001,88,00,00,00,05,00,00,00,00,00,00,00,11,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,01,00,00,00,01,00,01,00,03,00,00,00,00,02,03,00,00,00,00,00,44,00,00,00,44,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,01,01,01,00,01,00,00,00,40,00,00,00,40,00,00,00,80,10,00,00,00,00,00,00,bf,10,00,00,00,00,00,00,08,01,01,00,01,00,00,00,40,00,00,00,40,00,00,00,80,10,00,00,00,00,00,00,bf,10,00,00,00,00,00,00
|
||||
HKLM,"SYSTEM\CurrentControlSet\Services\es137140\Parameters\Device0\Devices","EAPWaveIn0",0x00010001,0x00000001
|
||||
HKLM,"SYSTEM\CurrentControlSet\Services\es137140\Parameters\Device0\Devices","EAPWaveOut0",0x00010001,0x00000002
|
||||
HKLM,"SYSTEM\CurrentControlSet\Services\es137140\Parameters\Device0\Devices","EAPMidiIn0",0x00010001,0x00000003
|
||||
HKLM,"SYSTEM\CurrentControlSet\Services\es137140\Parameters\Device0\Devices","EAPMidiOut0",0x00010001,0x00000004
|
||||
HKLM,"SYSTEM\CurrentControlSet\Services\es137140\Parameters\Device0\Devices","EAPMidiOut1",0x00010001,0x00000004
|
||||
HKLM,"SYSTEM\CurrentControlSet\Services\es137140\Parameters\Device0\Devices","EAPMixer0",0x00010001,0x00000006
|
||||
HKLM,"SYSTEM\CurrentControlSet\Services\es137140\Parameters\Device0\Devices","EAPAux0",0x00010001,0x00000005
|
||||
|
||||
|
||||
; MPU-401 MIDI driver
|
||||
HKLM,"SYSTEM\CurrentControlSet\Services\mpu401","Group",0x00000000,"Base"
|
||||
HKLM,"SYSTEM\CurrentControlSet\Services\mpu401","ServiceType",0x00010001,0x00000001
|
||||
HKLM,"SYSTEM\CurrentControlSet\Services\mpu401","Type",0x00010001,0x00000001
|
||||
HKLM,"SYSTEM\CurrentControlSet\Services\mpu401","Start",0x00010001,0x00000001
|
||||
HKLM,"SYSTEM\CurrentControlSet\Services\mpu401","ErrorControl",0x00010001,0x00000001
|
||||
HKLM,"SYSTEM\CurrentControlSet\Services\mpu401","ImagePath",0x00020000,"system32\drivers\mpu401.sys"
|
||||
|
||||
; Mouse driver
|
||||
HKLM,"SYSTEM\CurrentControlSet\Services\Mouse","ErrorControl",0x00010001,0x00000000
|
||||
HKLM,"SYSTEM\CurrentControlSet\Services\Mouse","Group",0x00000000,"Pointer Class"
|
||||
|
|
|
@ -150,12 +150,12 @@ MPU401Create(PDEVICE_OBJECT DeviceObject,
|
|||
|
||||
|
||||
// Play a note to say we're alive:
|
||||
/* WaitToSend(MPU401_PORT);
|
||||
WaitToSend(MPU401_PORT);
|
||||
MPU401_WRITE_DATA(MPU401_PORT, 0x90);
|
||||
WaitToSend(MPU401_PORT);
|
||||
MPU401_WRITE_DATA(MPU401_PORT, 0x50);
|
||||
WaitToSend(MPU401_PORT);
|
||||
MPU401_WRITE_DATA(MPU401_PORT, 0x7f);*/
|
||||
MPU401_WRITE_DATA(MPU401_PORT, 0x7f);
|
||||
|
||||
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||
Irp->IoStatus.Information = 0;
|
||||
|
@ -248,6 +248,9 @@ MPU401DeviceControl(PDEVICE_OBJECT DeviceObject,
|
|||
|
||||
DeviceExtension = DeviceObject->DeviceExtension;
|
||||
Stack = IoGetCurrentIrpStackLocation(Irp);
|
||||
|
||||
DPRINT("Control code %d [0x%x]\n", Stack->Parameters.DeviceIoControl.IoControlCode,
|
||||
Stack->Parameters.DeviceIoControl.IoControlCode);
|
||||
|
||||
switch(Stack->Parameters.DeviceIoControl.IoControlCode)
|
||||
{
|
||||
|
|
|
@ -12,6 +12,12 @@
|
|||
#ifndef __INCLUDES_MPU401_H__
|
||||
#define __INCLUDES_MPU401_H__
|
||||
|
||||
#include <windows.h>
|
||||
//#include <mmsystem.h>
|
||||
//#include <mmddk.h>
|
||||
//#include <winioctl.h>
|
||||
#include "../../../lib/mmdrv/mmdef.h"
|
||||
|
||||
#define DEFAULT_PORT 0x330
|
||||
#define DEFAULT_IRQ 9
|
||||
|
||||
|
@ -26,6 +32,7 @@
|
|||
|
||||
#define MPU401_TIMEOUT 10000
|
||||
|
||||
/* OBSOLETE - see mmdef.h instead:
|
||||
#define IOCTL_SOUND_BASE FILE_DEVICE_SOUND
|
||||
// wave base 0
|
||||
#define IOCTL_MIDI_BASE 0x0080
|
||||
|
@ -39,7 +46,7 @@
|
|||
#define IOCTL_MIDI_RECORD CTL_CODE(IOCTL_SOUND_BASE, IOCTL_MIDI_BASE + 0x0007, METHOD_BUFFERED, FILE_WRITE_ACCESS)
|
||||
#define IOCTL_MIDI_CACHE_PATCHES CTL_CODE(IOCTL_SOUND_BASE, IOCTL_MIDI_BASE + 0x0008, METHOD_BUFFERED, FILE_WRITE_ACCESS)
|
||||
#define IOCTL_MIDI_CACHE_DRUM_PATCHES CTL_CODE(IOCTL_SOUND_BASE, IOCTL_MIDI_BASE + 0x0009, METHOD_BUFFERED, FILE_WRITE_ACCESS)
|
||||
|
||||
*/
|
||||
|
||||
// The MPU-401 has 2 ports, usually 0x330 and 0x331, which are known as
|
||||
// "data" and "status/command", respectively. These macros deal with
|
||||
|
|
|
@ -35,8 +35,8 @@ NTSTATUS InitDevice(
|
|||
// PDEVICE_INSTANCE Instance = Context;
|
||||
PDEVICE_OBJECT DeviceObject; // = Context;
|
||||
PDEVICE_EXTENSION Parameters; // = DeviceObject->DeviceExtension;
|
||||
UNICODE_STRING DeviceName = ROS_STRING_INITIALIZER(L"\\Device\\WaveOut"); // CHANGE THESE!
|
||||
UNICODE_STRING SymlinkName = ROS_STRING_INITIALIZER(L"\\??\\WaveOut");
|
||||
UNICODE_STRING DeviceName = ROS_STRING_INITIALIZER(L"\\Device\\WaveOut0"); // CHANGE THESE?
|
||||
UNICODE_STRING SymlinkName = ROS_STRING_INITIALIZER(L"\\??\\WaveOut0");
|
||||
|
||||
// CONFIG Config;
|
||||
RTL_QUERY_REGISTRY_TABLE Table[2];
|
||||
|
@ -140,10 +140,10 @@ NTSTATUS InitDevice(
|
|||
if (! CreateDMA(DeviceObject))
|
||||
DPRINT("FAILURE!\n");
|
||||
|
||||
// TEMPORARY TESTING STUFF:
|
||||
// TEMPORARY TESTING STUFF: should be in BlasterCreate
|
||||
EnableSpeaker(Parameters->Port, TRUE);
|
||||
SetOutputSampleRate(Parameters->Port, 11025);
|
||||
BeginPlayback(Parameters->Port, 8, 1, Parameters->BufferSize);
|
||||
SetOutputSampleRate(Parameters->Port, 2205);
|
||||
BeginPlayback(Parameters->Port, 16, 2, Parameters->BufferSize);
|
||||
|
||||
DeviceCount ++;
|
||||
|
||||
|
@ -178,9 +178,14 @@ BlasterCreate(PDEVICE_OBJECT DeviceObject,
|
|||
|
||||
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||
Irp->IoStatus.Information = 0;
|
||||
|
||||
DPRINT("IoCompleteRequest()\n");
|
||||
|
||||
IoCompleteRequest(Irp,
|
||||
IO_NO_INCREMENT);
|
||||
|
||||
DPRINT("BlasterCreate() completed\n");
|
||||
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
|
@ -247,6 +252,39 @@ BlasterCleanup(PDEVICE_OBJECT DeviceObject,
|
|||
}
|
||||
|
||||
|
||||
static NTSTATUS STDCALL
|
||||
BlasterWrite(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||
{
|
||||
PIO_STACK_LOCATION Stack;
|
||||
PDEVICE_EXTENSION DeviceExtension;
|
||||
UINT ByteCount;
|
||||
PBYTE Data;
|
||||
|
||||
DPRINT("BlasterWrite() called!\n");
|
||||
|
||||
DeviceExtension = DeviceObject->DeviceExtension;
|
||||
Stack = IoGetCurrentIrpStackLocation(Irp);
|
||||
|
||||
DPRINT("%d bytes\n", Stack->Parameters.Write.Length);
|
||||
|
||||
Data = (PBYTE) Irp->AssociatedIrp.SystemBuffer;
|
||||
|
||||
for (ByteCount = 0; ByteCount < Stack->Parameters.Write.Length; ByteCount ++)
|
||||
{
|
||||
// DPRINT("0x%x ", Data[ByteCount]);
|
||||
|
||||
// MPU401_WRITE_BYTE(DeviceExtension->Port, Data[ByteCount]);
|
||||
}
|
||||
|
||||
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||
Irp->IoStatus.Information = 0;
|
||||
IoCompleteRequest(Irp,
|
||||
IO_NO_INCREMENT);
|
||||
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
static NTSTATUS STDCALL
|
||||
BlasterDeviceControl(PDEVICE_OBJECT DeviceObject,
|
||||
PIRP Irp)
|
||||
|
@ -392,7 +430,7 @@ DriverEntry(PDRIVER_OBJECT DriverObject,
|
|||
// Doesn't support multiple instances (yet ...)
|
||||
NTSTATUS Status;
|
||||
|
||||
DPRINT("Sound Blaster Device Driver 0.0.1\n");
|
||||
DPRINT("Sound Blaster Device Driver 0.0.2\n");
|
||||
|
||||
// Instance.DriverObject = DriverObject;
|
||||
// previous instance = NULL...
|
||||
|
@ -404,6 +442,7 @@ DriverEntry(PDRIVER_OBJECT DriverObject,
|
|||
DriverObject->MajorFunction[IRP_MJ_CLOSE] = BlasterClose;
|
||||
DriverObject->MajorFunction[IRP_MJ_CLEANUP] = BlasterCleanup;
|
||||
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = BlasterDeviceControl;
|
||||
DriverObject->MajorFunction[IRP_MJ_WRITE] = BlasterWrite;
|
||||
DriverObject->DriverUnload = BlasterUnload;
|
||||
|
||||
// Major hack to just get this damn thing working:
|
||||
|
|
|
@ -165,6 +165,7 @@ extern "C" {
|
|||
#define MF_USECHECKBITMAPS (0x200L)
|
||||
#define MF_RIGHTJUSTIFY MF_HELP
|
||||
|
||||
|
||||
/* Ternary Raster Operations - BitBlt */
|
||||
#define BLACKNESS 0x00000042
|
||||
#define NOTSRCERASE 0x001100A6
|
||||
|
@ -254,6 +255,13 @@ extern "C" {
|
|||
#define DISP_CHANGE_NOTUPDATED (-3)
|
||||
#define DISP_CHANGE_BADPARAM (-5)
|
||||
|
||||
/* ChangeMenu */
|
||||
#define MF_INSERT 0
|
||||
#define MF_CHANGE 128
|
||||
#define MF_APPEND 256
|
||||
#define MF_DELETE 512
|
||||
#define MF_REMOVE 4096
|
||||
|
||||
/* ChangeServiceConfig */
|
||||
#define SERVICE_NO_CHANGE (-1)
|
||||
#define SERVICE_KERNEL_DRIVER (1)
|
||||
|
|
408
reactos/include/wine/mmreg.h
Normal file
408
reactos/include/wine/mmreg.h
Normal file
|
@ -0,0 +1,408 @@
|
|||
/*
|
||||
* Declarations for MultiMedia-REGistration
|
||||
*
|
||||
* Copyright (C) 1999 Eric Pouech
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef __WINE_MMREG_H
|
||||
#define __WINE_MMREG_H
|
||||
|
||||
/***********************************************************************
|
||||
* Defines/Enums
|
||||
*/
|
||||
|
||||
#ifndef _ACM_WAVEFILTER
|
||||
#define _ACM_WAVEFILTER
|
||||
|
||||
#define WAVE_FILTER_UNKNOWN 0x0000
|
||||
#define WAVE_FILTER_DEVELOPMENT 0xFFFF
|
||||
|
||||
typedef struct _WAVEFILTER {
|
||||
DWORD cbStruct;
|
||||
DWORD dwFilterTag;
|
||||
DWORD fdwFilter;
|
||||
DWORD dwReserved[5];
|
||||
} WAVEFILTER, *PWAVEFILTER, *NPWAVEFILTER, *LPWAVEFILTER;
|
||||
#endif /* _ACM_WAVEFILTER */
|
||||
|
||||
#ifndef WAVE_FILTER_VOLUME
|
||||
#define WAVE_FILTER_VOLUME 0x0001
|
||||
|
||||
typedef struct _WAVEFILTER_VOLUME {
|
||||
WAVEFILTER wfltr;
|
||||
DWORD dwVolume;
|
||||
} VOLUMEWAVEFILTER, *PVOLUMEWAVEFILTER, *NPVOLUMEWAVEFILTER, *LPVOLUMEWAVEFILTER;
|
||||
#endif /* WAVE_FILTER_VOLUME */
|
||||
|
||||
#ifndef WAVE_FILTER_ECHO
|
||||
#define WAVE_FILTER_ECHO 0x0002
|
||||
|
||||
typedef struct WAVEFILTER_ECHO {
|
||||
WAVEFILTER wfltr;
|
||||
DWORD dwVolume;
|
||||
DWORD dwDelay;
|
||||
} ECHOWAVEFILTER, *PECHOWAVEFILTER, *NPECHOWAVEFILTER, *LPECHOWAVEFILTER;
|
||||
#endif /* WAVEFILTER_ECHO */
|
||||
|
||||
#ifndef _WAVEFORMATEX_
|
||||
#define _WAVEFORMATEX_
|
||||
typedef struct _WAVEFORMATEX {
|
||||
WORD wFormatTag;
|
||||
WORD nChannels;
|
||||
DWORD nSamplesPerSec;
|
||||
DWORD nAvgBytesPerSec;
|
||||
WORD nBlockAlign;
|
||||
WORD wBitsPerSample;
|
||||
WORD cbSize;
|
||||
} WAVEFORMATEX, *PWAVEFORMATEX, *NPWAVEFORMATEX, *LPWAVEFORMATEX;
|
||||
#endif /* _WAVEFORMATEX_ */
|
||||
|
||||
/* WAVE form wFormatTag IDs */
|
||||
#define WAVE_FORMAT_UNKNOWN 0x0000 /* Microsoft Corporation */
|
||||
#define WAVE_FORMAT_ADPCM 0x0002 /* Microsoft Corporation */
|
||||
#define WAVE_FORMAT_IBM_CVSD 0x0005 /* IBM Corporation */
|
||||
#define WAVE_FORMAT_ALAW 0x0006 /* Microsoft Corporation */
|
||||
#define WAVE_FORMAT_MULAW 0x0007 /* Microsoft Corporation */
|
||||
#define WAVE_FORMAT_OKI_ADPCM 0x0010 /* OKI */
|
||||
#define WAVE_FORMAT_DVI_ADPCM 0x0011 /* Intel Corporation */
|
||||
#define WAVE_FORMAT_IMA_ADPCM (WAVE_FORMAT_DVI_ADPCM) /* Intel Corporation */
|
||||
#define WAVE_FORMAT_MEDIASPACE_ADPCM 0x0012 /* Videologic */
|
||||
#define WAVE_FORMAT_SIERRA_ADPCM 0x0013 /* Sierra Semiconductor Corp */
|
||||
#define WAVE_FORMAT_G723_ADPCM 0x0014 /* Antex Electronics Corporation */
|
||||
#define WAVE_FORMAT_DIGISTD 0x0015 /* DSP Solutions, Inc. */
|
||||
#define WAVE_FORMAT_DIGIFIX 0x0016 /* DSP Solutions, Inc. */
|
||||
#define WAVE_FORMAT_DIALOGIC_OKI_ADPCM 0x0017 /* Dialogic Corporation */
|
||||
#define WAVE_FORMAT_YAMAHA_ADPCM 0x0020 /* Yamaha Corporation of America */
|
||||
#define WAVE_FORMAT_SONARC 0x0021 /* Speech Compression */
|
||||
#define WAVE_FORMAT_DSPGROUP_TRUESPEECH 0x0022 /* DSP Group, Inc */
|
||||
#define WAVE_FORMAT_ECHOSC1 0x0023 /* Echo Speech Corporation */
|
||||
#define WAVE_FORMAT_AUDIOFILE_AF36 0x0024 /* */
|
||||
#define WAVE_FORMAT_APTX 0x0025 /* Audio Processing Technology */
|
||||
#define WAVE_FORMAT_AUDIOFILE_AF10 0x0026 /* */
|
||||
#define WAVE_FORMAT_DOLBY_AC2 0x0030 /* Dolby Laboratories */
|
||||
#define WAVE_FORMAT_GSM610 0x0031 /* Microsoft Corporation */
|
||||
#define WAVE_FORMAT_ANTEX_ADPCME 0x0033 /* Antex Electronics Corporation */
|
||||
#define WAVE_FORMAT_CONTROL_RES_VQLPC 0x0034 /* Control Resources Limited */
|
||||
#define WAVE_FORMAT_DIGIREAL 0x0035 /* DSP Solutions, Inc. */
|
||||
#define WAVE_FORMAT_DIGIADPCM 0x0036 /* DSP Solutions, Inc. */
|
||||
#define WAVE_FORMAT_CONTROL_RES_CR10 0x0037 /* Control Resources Limited */
|
||||
#define WAVE_FORMAT_NMS_VBXADPCM 0x0038 /* Natural MicroSystems */
|
||||
#define WAVE_FORMAT_G721_ADPCM 0x0040 /* Antex Electronics Corporation */
|
||||
#define WAVE_FORMAT_MPEG 0x0050 /* Microsoft Corporation */
|
||||
#define WAVE_FORMAT_MPEGLAYER3 0x0055
|
||||
#define WAVE_FORMAT_CREATIVE_ADPCM 0x0200 /* Creative Labs, Inc */
|
||||
#define WAVE_FORMAT_CREATIVE_FASTSPEECH8 0x0202 /* Creative Labs, Inc */
|
||||
#define WAVE_FORMAT_CREATIVE_FASTSPEECH10 0x0203 /* Creative Labs, Inc */
|
||||
#define WAVE_FORMAT_FM_TOWNS_SND 0x0300 /* Fujitsu Corp. */
|
||||
#define WAVE_FORMAT_OLIGSM 0x1000 /* Ing C. Olivetti & C., S.p.A. */
|
||||
#define WAVE_FORMAT_OLIADPCM 0x1001 /* Ing C. Olivetti & C., S.p.A. */
|
||||
#define WAVE_FORMAT_OLICELP 0x1002 /* Ing C. Olivetti & C., S.p.A. */
|
||||
#define WAVE_FORMAT_OLISBC 0x1003 /* Ing C. Olivetti & C., S.p.A. */
|
||||
#define WAVE_FORMAT_OLIOPR 0x1004 /* Ing C. Olivetti & C., S.p.A. */
|
||||
|
||||
#define WAVE_FORMAT_DEVELOPMENT (0xFFFF)
|
||||
|
||||
typedef struct adpcmcoef_tag {
|
||||
short iCoef1;
|
||||
short iCoef2;
|
||||
} ADPCMCOEFSET;
|
||||
typedef ADPCMCOEFSET *PADPCMCOEFSET,
|
||||
*NPADPCMCOEFSET, *LPADPCMCOEFSET;
|
||||
|
||||
typedef struct adpcmwaveformat_tag {
|
||||
WAVEFORMATEX wfx;
|
||||
WORD wSamplesPerBlock;
|
||||
WORD wNumCoef;
|
||||
/* FIXME: this should be aCoef[0] */
|
||||
ADPCMCOEFSET aCoef[1];
|
||||
} ADPCMWAVEFORMAT;
|
||||
typedef ADPCMWAVEFORMAT *PADPCMWAVEFORMAT,
|
||||
*NPADPCMWAVEFORMAT, *LPADPCMWAVEFORMAT;
|
||||
|
||||
typedef struct dvi_adpcmwaveformat_tag {
|
||||
WAVEFORMATEX wfx;
|
||||
WORD wSamplesPerBlock;
|
||||
} DVIADPCMWAVEFORMAT;
|
||||
typedef DVIADPCMWAVEFORMAT *PDVIADPCMWAVEFORMAT,
|
||||
*NPDVIADPCMWAVEFORMAT, *LPDVIADPCMWAVEFORMAT;
|
||||
|
||||
typedef struct ima_adpcmwaveformat_tag {
|
||||
WAVEFORMATEX wfx;
|
||||
WORD wSamplesPerBlock;
|
||||
} IMAADPCMWAVEFORMAT;
|
||||
typedef IMAADPCMWAVEFORMAT *PIMAADPCMWAVEFORMAT, *NPIMAADPCMWAVEFORMAT,
|
||||
*LPIMAADPCMWAVEFORMAT;
|
||||
|
||||
typedef struct mediaspace_adpcmwaveformat_tag {
|
||||
WAVEFORMATEX wfx;
|
||||
WORD wRevision;
|
||||
} MEDIASPACEADPCMWAVEFORMAT;
|
||||
typedef MEDIASPACEADPCMWAVEFORMAT *PMEDIASPACEADPCMWAVEFORMAT,
|
||||
*NPMEDIASPACEADPCMWAVEFORMAT, *LPMEDIASPACEADPCMWAVEFORMAT;
|
||||
|
||||
typedef struct sierra_adpcmwaveformat_tag {
|
||||
WAVEFORMATEX wfx;
|
||||
WORD wRevision;
|
||||
} SIERRAADPCMWAVEFORMAT;
|
||||
typedef SIERRAADPCMWAVEFORMAT *PSIERRAADPCMWAVEFORMAT,
|
||||
*NPSIERRAADPCMWAVEFORMAT, *LPSIERRAADPCMWAVEFORMAT;
|
||||
|
||||
typedef struct g723_adpcmwaveformat_tag {
|
||||
WAVEFORMATEX wfx;
|
||||
WORD cbExtraSize;
|
||||
WORD nAuxBlockSize;
|
||||
} G723_ADPCMWAVEFORMAT;
|
||||
typedef G723_ADPCMWAVEFORMAT *PG723_ADPCMWAVEFORMAT,
|
||||
*NPG723_ADPCMWAVEFORMAT, *LPG723_ADPCMWAVEFORMAT;
|
||||
|
||||
typedef struct digistdwaveformat_tag {
|
||||
WAVEFORMATEX wfx;
|
||||
} DIGISTDWAVEFORMAT;
|
||||
typedef DIGISTDWAVEFORMAT *PDIGISTDWAVEFORMAT,
|
||||
*NPDIGISTDWAVEFORMAT, *LPDIGISTDWAVEFORMAT;
|
||||
|
||||
typedef struct digifixwaveformat_tag {
|
||||
WAVEFORMATEX wfx;
|
||||
} DIGIFIXWAVEFORMAT;
|
||||
typedef DIGIFIXWAVEFORMAT *PDIGIFIXWAVEFORMAT,
|
||||
*NPDIGIFIXWAVEFORMAT, *LPDIGIFIXWAVEFORMAT;
|
||||
|
||||
typedef struct creative_fastspeechformat_tag {
|
||||
WAVEFORMATEX ewf;
|
||||
} DIALOGICOKIADPCMWAVEFORMAT;
|
||||
typedef DIALOGICOKIADPCMWAVEFORMAT *PDIALOGICOKIADPCMWAVEFORMAT,
|
||||
*NPDIALOGICOKIADPCMWAVEFORMAT, *LPDIALOGICOKIADPCMWAVEFORMAT;
|
||||
|
||||
typedef struct yamaha_adpmcwaveformat_tag {
|
||||
WAVEFORMATEX wfx;
|
||||
} YAMAHA_ADPCMWAVEFORMAT;
|
||||
typedef YAMAHA_ADPCMWAVEFORMAT *PYAMAHA_ADPCMWAVEFORMAT,
|
||||
*NPYAMAHA_ADPCMWAVEFORMAT, *LPYAMAHA_ADPCMWAVEFORMAT;
|
||||
|
||||
typedef struct sonarcwaveformat_tag {
|
||||
WAVEFORMATEX wfx;
|
||||
WORD wCompType;
|
||||
} SONARCWAVEFORMAT;
|
||||
typedef SONARCWAVEFORMAT *PSONARCWAVEFORMAT,
|
||||
*NPSONARCWAVEFORMAT,*LPSONARCWAVEFORMAT;
|
||||
|
||||
typedef struct truespeechwaveformat_tag {
|
||||
WAVEFORMATEX wfx;
|
||||
WORD wRevision;
|
||||
WORD nSamplesPerBlock;
|
||||
BYTE abReserved[28];
|
||||
} TRUESPEECHWAVEFORMAT;
|
||||
typedef TRUESPEECHWAVEFORMAT *PTRUESPEECHWAVEFORMAT,
|
||||
*NPTRUESPEECHWAVEFORMAT, *LPTRUESPEECHWAVEFORMAT;
|
||||
|
||||
typedef struct echosc1waveformat_tag {
|
||||
WAVEFORMATEX wfx;
|
||||
} ECHOSC1WAVEFORMAT;
|
||||
typedef ECHOSC1WAVEFORMAT *PECHOSC1WAVEFORMAT,
|
||||
*NPECHOSC1WAVEFORMAT, *LPECHOSC1WAVEFORMAT;
|
||||
|
||||
typedef struct audiofile_af36waveformat_tag {
|
||||
WAVEFORMATEX wfx;
|
||||
} AUDIOFILE_AF36WAVEFORMAT;
|
||||
typedef AUDIOFILE_AF36WAVEFORMAT *PAUDIOFILE_AF36WAVEFORMAT,
|
||||
*NPAUDIOFILE_AF36WAVEFORMAT, *LPAUDIOFILE_AF36WAVEFORMAT;
|
||||
|
||||
typedef struct aptxwaveformat_tag {
|
||||
WAVEFORMATEX wfx;
|
||||
} APTXWAVEFORMAT;
|
||||
typedef APTXWAVEFORMAT *PAPTXWAVEFORMAT,
|
||||
*NPAPTXWAVEFORMAT, *LPAPTXWAVEFORMAT;
|
||||
|
||||
typedef struct audiofile_af10waveformat_tag {
|
||||
WAVEFORMATEX wfx;
|
||||
} AUDIOFILE_AF10WAVEFORMAT;
|
||||
typedef AUDIOFILE_AF10WAVEFORMAT *PAUDIOFILE_AF10WAVEFORMAT,
|
||||
*NPAUDIOFILE_AF10WAVEFORMAT, *LPAUDIOFILE_AF10WAVEFORMAT;
|
||||
|
||||
typedef struct dolbyac2waveformat_tag {
|
||||
WAVEFORMATEX wfx;
|
||||
WORD nAuxBitsCode;
|
||||
} DOLBYAC2WAVEFORMAT;
|
||||
|
||||
typedef struct gsm610waveformat_tag {
|
||||
WAVEFORMATEX wfx;
|
||||
WORD wSamplesPerBlock;
|
||||
} GSM610WAVEFORMAT;
|
||||
typedef GSM610WAVEFORMAT *PGSM610WAVEFORMAT,
|
||||
*NPGSM610WAVEFORMAT, *LPGSM610WAVEFORMAT;
|
||||
|
||||
typedef struct adpcmewaveformat_tag {
|
||||
WAVEFORMATEX wfx;
|
||||
WORD wSamplesPerBlock;
|
||||
} ADPCMEWAVEFORMAT;
|
||||
typedef ADPCMEWAVEFORMAT *PADPCMEWAVEFORMAT,
|
||||
*NPADPCMEWAVEFORMAT, *LPADPCMEWAVEFORMAT;
|
||||
|
||||
typedef struct contres_vqlpcwaveformat_tag {
|
||||
WAVEFORMATEX wfx;
|
||||
WORD wSamplesPerBlock;
|
||||
} CONTRESVQLPCWAVEFORMAT;
|
||||
typedef CONTRESVQLPCWAVEFORMAT *PCONTRESVQLPCWAVEFORMAT,
|
||||
*NPCONTRESVQLPCWAVEFORMAT, *LPCONTRESVQLPCWAVEFORMAT;
|
||||
|
||||
typedef struct digirealwaveformat_tag {
|
||||
WAVEFORMATEX wfx;
|
||||
WORD wSamplesPerBlock;
|
||||
} DIGIREALWAVEFORMAT;
|
||||
typedef DIGIREALWAVEFORMAT *PDIGIREALWAVEFORMAT,
|
||||
*NPDIGIREALWAVEFORMAT, *LPDIGIREALWAVEFORMAT;
|
||||
|
||||
typedef struct digiadpcmmwaveformat_tag {
|
||||
WAVEFORMATEX wfx;
|
||||
WORD wSamplesPerBlock;
|
||||
} DIGIADPCMWAVEFORMAT;
|
||||
typedef DIGIADPCMWAVEFORMAT *PDIGIADPCMWAVEFORMAT,
|
||||
*NPDIGIADPCMWAVEFORMAT, *LPDIGIADPCMWAVEFORMAT;
|
||||
|
||||
typedef struct contres_cr10waveformat_tag {
|
||||
WAVEFORMATEX wfx;
|
||||
WORD wSamplesPerBlock;
|
||||
} CONTRESCR10WAVEFORMAT;
|
||||
typedef CONTRESCR10WAVEFORMAT *PCONTRESCR10WAVEFORMAT,
|
||||
*NPCONTRESCR10WAVEFORMAT, *LPCONTRESCR10WAVEFORMAT;
|
||||
|
||||
typedef struct nms_vbxadpcmmwaveformat_tag {
|
||||
WAVEFORMATEX wfx;
|
||||
WORD wSamplesPerBlock;
|
||||
} NMS_VBXADPCMWAVEFORMAT;
|
||||
typedef NMS_VBXADPCMWAVEFORMAT *PNMS_VBXADPCMWAVEFORMAT,
|
||||
*NPNMS_VBXADPCMWAVEFORMAT, *LPNMS_VBXADPCMWAVEFORMAT;
|
||||
|
||||
typedef struct g721_adpcmwaveformat_tag {
|
||||
WAVEFORMATEX wfx;
|
||||
WORD nAuxBlockSize;
|
||||
} G721_ADPCMWAVEFORMAT;
|
||||
typedef G721_ADPCMWAVEFORMAT *PG721_ADPCMWAVEFORMAT,
|
||||
*NG721_ADPCMWAVEFORMAT, *LPG721_ADPCMWAVEFORMAT;
|
||||
|
||||
typedef struct creative_adpcmwaveformat_tag {
|
||||
WAVEFORMATEX wfx;
|
||||
WORD wRevision;
|
||||
} CREATIVEADPCMWAVEFORMAT;
|
||||
typedef CREATIVEADPCMWAVEFORMAT *PCREATIVEADPCMWAVEFORMAT,
|
||||
*NPCREATIVEADPCMWAVEFORMAT, *LPCREATIVEADPCMWAVEFORMAT;
|
||||
|
||||
typedef struct creative_fastspeech8format_tag {
|
||||
WAVEFORMATEX wfx;
|
||||
WORD wRevision;
|
||||
} CREATIVEFASTSPEECH8WAVEFORMAT;
|
||||
typedef CREATIVEFASTSPEECH8WAVEFORMAT *PCREATIVEFASTSPEECH8WAVEFORMAT,
|
||||
*NPCREATIVEFASTSPEECH8WAVEFORMAT, *LPCREATIVEFASTSPEECH8WAVEFORMAT;
|
||||
|
||||
typedef struct creative_fastspeech10format_tag {
|
||||
WAVEFORMATEX wfx;
|
||||
WORD wRevision;
|
||||
} CREATIVEFASTSPEECH10WAVEFORMAT;
|
||||
typedef CREATIVEFASTSPEECH10WAVEFORMAT *PCREATIVEFASTSPEECH10WAVEFORMAT,
|
||||
*NPCREATIVEFASTSPEECH10WAVEFORMAT, *LPCREATIVEFASTSPEECH10WAVEFORMAT;
|
||||
|
||||
typedef struct fmtowns_snd_waveformat_tag {
|
||||
WAVEFORMATEX wfx;
|
||||
WORD wRevision;
|
||||
} FMTOWNS_SND_WAVEFORMAT;
|
||||
typedef FMTOWNS_SND_WAVEFORMAT *PFMTOWNS_SND_WAVEFORMAT,
|
||||
*NPFMTOWNS_SND_WAVEFORMAT, *LPFMTOWNS_SND_WAVEFORMAT;
|
||||
|
||||
typedef struct oligsmwaveformat_tag {
|
||||
WAVEFORMATEX wfx;
|
||||
} OLIGSMWAVEFORMAT;
|
||||
typedef OLIGSMWAVEFORMAT *POLIGSMWAVEFORMAT,
|
||||
*NPOLIGSMWAVEFORMAT, *LPOLIGSMWAVEFORMAT;
|
||||
|
||||
typedef struct oliadpcmwaveformat_tag {
|
||||
WAVEFORMATEX wfx;
|
||||
} OLIADPCMWAVEFORMAT;
|
||||
typedef OLIADPCMWAVEFORMAT *POLIADPCMWAVEFORMAT,
|
||||
*NPOLIADPCMWAVEFORMAT, *LPOLIADPCMWAVEFORMAT;
|
||||
|
||||
typedef struct olicelpwaveformat_tag {
|
||||
WAVEFORMATEX wfx;
|
||||
} OLICELPWAVEFORMAT;
|
||||
typedef OLICELPWAVEFORMAT *POLICELPWAVEFORMAT,
|
||||
*NPOLICELPWAVEFORMAT, *LPOLICELPWAVEFORMAT;
|
||||
|
||||
typedef struct olisbcwaveformat_tag {
|
||||
WAVEFORMATEX wfx;
|
||||
} OLISBCWAVEFORMAT;
|
||||
typedef OLISBCWAVEFORMAT *POLISBCWAVEFORMAT,
|
||||
*NPOLISBCWAVEFORMAT, *LPOLISBCWAVEFORMAT;
|
||||
|
||||
typedef struct olioprwaveformat_tag {
|
||||
WAVEFORMATEX wfx;
|
||||
} OLIOPRWAVEFORMAT;
|
||||
typedef OLIOPRWAVEFORMAT *POLIOPRWAVEFORMAT,
|
||||
*NPOLIOPRWAVEFORMAT, *LPOLIOPRWAVEFORMAT;
|
||||
|
||||
typedef struct csimaadpcmwaveformat_tag {
|
||||
WAVEFORMATEX wfx;
|
||||
} CSIMAADPCMWAVEFORMAT;
|
||||
typedef CSIMAADPCMWAVEFORMAT *PCSIMAADPCMWAVEFORMAT,
|
||||
*NPCSIMAADPCMWAVEFORMAT, *LPCSIMAADPCMWAVEFORMAT;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
WAVEFORMATEX wfx;
|
||||
WORD fwHeadLayer;
|
||||
DWORD dwHeadBitrate;
|
||||
WORD fwHeadMode;
|
||||
WORD fwHeadModeExt;
|
||||
WORD wHeadEmphasis;
|
||||
WORD fwHeadFlags;
|
||||
DWORD dwPTSLow;
|
||||
DWORD dwPTSHigh;
|
||||
} MPEG1WAVEFORMAT,* PMPEG1WAVEFORMAT;
|
||||
|
||||
#define ACM_MPEG_LAYER1 0x0001
|
||||
#define ACM_MPEG_LAYER2 0x0002
|
||||
#define ACM_MPEG_LAYER3 0x0004
|
||||
|
||||
#define ACM_MPEG_STEREO 0x0001
|
||||
#define ACM_MPEG_JOINTSTEREO 0x0002
|
||||
#define ACM_MPEG_DUALCHANNEL 0x0004
|
||||
#define ACM_MPEG_SINGLECHANNEL 0x0008
|
||||
#define ACM_MPEG_PRIVATEBIT 0x0001
|
||||
#define ACM_MPEG_COPYRIGHT 0x0002
|
||||
#define ACM_MPEG_ORIGINALHOME 0x0004
|
||||
#define ACM_MPEG_PROTECTIONBIT 0x0008
|
||||
#define ACM_MPEG_ID_MPEG1 0x0010
|
||||
|
||||
typedef struct
|
||||
{
|
||||
WAVEFORMATEX wfx;
|
||||
WORD wID;
|
||||
DWORD fdwFlags;
|
||||
WORD nBlockSize;
|
||||
WORD nFramesPerBlock;
|
||||
WORD nCodecDelay;
|
||||
} MPEGLAYER3WAVEFORMAT;
|
||||
|
||||
#define MPEGLAYER3_WFX_EXTRA_BYTES 12
|
||||
|
||||
#define MPEGLAYER3_ID_UNKNOWN 0
|
||||
#define MPEGLAYER3_ID_MPEG 1
|
||||
#define MPEGLAYER3_ID_CONSTANTFRAMESIZE 2
|
||||
|
||||
#define MPEGLAYER3_FLAG_PADDING_ISO 0x00000000
|
||||
#define MPEGLAYER3_FLAG_PADDING_ON 0x00000001
|
||||
#define MPEGLAYER3_FLAG_PADDING_OFF 0x00000002
|
||||
|
||||
#endif /* __WINE_MMREG_H */
|
779
reactos/include/wine/msacm.h
Normal file
779
reactos/include/wine/msacm.h
Normal file
|
@ -0,0 +1,779 @@
|
|||
/*
|
||||
* Declarations for MSACM
|
||||
*
|
||||
* Copyright (C) the Wine project
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef __WINE_MSACM_H
|
||||
#define __WINE_MSACM_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* defined(__cplusplus) */
|
||||
|
||||
#define ACMAPI WINAPI
|
||||
|
||||
/***********************************************************************
|
||||
* Defines/Enums
|
||||
*/
|
||||
#define ACMERR_BASE 512
|
||||
#define ACMERR_NOTPOSSIBLE (ACMERR_BASE + 0)
|
||||
#define ACMERR_BUSY (ACMERR_BASE + 1)
|
||||
#define ACMERR_UNPREPARED (ACMERR_BASE + 2)
|
||||
#define ACMERR_CANCELED (ACMERR_BASE + 3)
|
||||
|
||||
#define MM_ACM_OPEN MM_STREAM_OPEN
|
||||
#define MM_ACM_CLOSE MM_STREAM_CLOSE
|
||||
#define MM_ACM_DONE MM_STREAM_DONE
|
||||
|
||||
#define ACM_DRIVERADDF_FUNCTION 0x00000003L
|
||||
#define ACM_DRIVERADDF_NOTIFYHWND 0x00000004L
|
||||
#define ACM_DRIVERADDF_TYPEMASK 0x00000007L
|
||||
#define ACM_DRIVERADDF_LOCAL 0x00000000L
|
||||
#define ACM_DRIVERADDF_GLOBAL 0x00000008L
|
||||
|
||||
#define ACMDRIVERDETAILS_SHORTNAME_CHARS 32
|
||||
#define ACMDRIVERDETAILS_LONGNAME_CHARS 128
|
||||
#define ACMDRIVERDETAILS_COPYRIGHT_CHARS 80
|
||||
#define ACMDRIVERDETAILS_LICENSING_CHARS 128
|
||||
#define ACMDRIVERDETAILS_FEATURES_CHARS 512
|
||||
|
||||
#define ACMDRIVERDETAILS_FCCTYPE_AUDIOCODEC mmioFOURCC('a', 'u', 'd', 'c')
|
||||
#define ACMDRIVERDETAILS_FCCCOMP_UNDEFINED mmioFOURCC('\0', '\0', '\0', '\0')
|
||||
|
||||
#define ACMDRIVERDETAILS_SUPPORTF_CODEC 0x00000001L
|
||||
#define ACMDRIVERDETAILS_SUPPORTF_CONVERTER 0x00000002L
|
||||
#define ACMDRIVERDETAILS_SUPPORTF_FILTER 0x00000004L
|
||||
#define ACMDRIVERDETAILS_SUPPORTF_HARDWARE 0x00000008L
|
||||
#define ACMDRIVERDETAILS_SUPPORTF_ASYNC 0x00000010L
|
||||
#define ACMDRIVERDETAILS_SUPPORTF_LOCAL 0x40000000L
|
||||
#define ACMDRIVERDETAILS_SUPPORTF_DISABLED 0x80000000L
|
||||
|
||||
#define ACM_DRIVERENUMF_NOLOCAL 0x40000000L
|
||||
#define ACM_DRIVERENUMF_DISABLED 0x80000000L
|
||||
|
||||
#define ACM_DRIVERPRIORITYF_ENABLE 0x00000001L
|
||||
#define ACM_DRIVERPRIORITYF_DISABLE 0x00000002L
|
||||
#define ACM_DRIVERPRIORITYF_ABLEMASK 0x00000003L
|
||||
#define ACM_DRIVERPRIORITYF_BEGIN 0x00010000L
|
||||
#define ACM_DRIVERPRIORITYF_END 0x00020000L
|
||||
#define ACM_DRIVERPRIORITYF_DEFERMASK 0x00030000L
|
||||
|
||||
#define MM_ACM_FILTERCHOOSE 0x8000
|
||||
|
||||
#define FILTERCHOOSE_MESSAGE 0
|
||||
#define FILTERCHOOSE_FILTERTAG_VERIFY (FILTERCHOOSE_MESSAGE+0)
|
||||
#define FILTERCHOOSE_FILTER_VERIFY (FILTERCHOOSE_MESSAGE+1)
|
||||
#define FILTERCHOOSE_CUSTOM_VERIFY (FILTERCHOOSE_MESSAGE+2)
|
||||
|
||||
#define ACMFILTERCHOOSE_STYLEF_SHOWHELP 0x00000004L
|
||||
#define ACMFILTERCHOOSE_STYLEF_ENABLEHOOK 0x00000008L
|
||||
#define ACMFILTERCHOOSE_STYLEF_ENABLETEMPLATE 0x00000010L
|
||||
#define ACMFILTERCHOOSE_STYLEF_ENABLETEMPLATEHANDLE 0x00000020L
|
||||
#define ACMFILTERCHOOSE_STYLEF_INITTOFILTERSTRUCT 0x00000040L
|
||||
#define ACMFILTERCHOOSE_STYLEF_CONTEXTHELP 0x00000080L
|
||||
|
||||
#define ACMFILTERDETAILS_FILTER_CHARS 128
|
||||
|
||||
#define ACM_FILTERDETAILSF_INDEX 0x00000000L
|
||||
#define ACM_FILTERDETAILSF_FILTER 0x00000001L
|
||||
#define ACM_FILTERDETAILSF_QUERYMASK 0x0000000FL
|
||||
|
||||
#define ACMFILTERTAGDETAILS_FILTERTAG_CHARS 48
|
||||
|
||||
#define ACM_FILTERTAGDETAILSF_INDEX 0x00000000L
|
||||
#define ACM_FILTERTAGDETAILSF_FILTERTAG 0x00000001L
|
||||
#define ACM_FILTERTAGDETAILSF_LARGESTSIZE 0x00000002L
|
||||
#define ACM_FILTERTAGDETAILSF_QUERYMASK 0x0000000FL
|
||||
|
||||
#define ACM_FILTERENUMF_DWFILTERTAG 0x00010000L
|
||||
|
||||
#define ACMHELPMSGSTRINGA "acmchoose_help"
|
||||
#if defined(__GNUC__)
|
||||
# define ACMHELPMSGSTRINGW (const WCHAR []){ 'a','c','m', \
|
||||
'c','h','o','o','s','e','_','h','e','l','p',0 }
|
||||
#elif defined(_MSC_VER)
|
||||
# define ACMHELPMSGSTRINGW L"acmchoose_help"
|
||||
#else
|
||||
static const WCHAR ACMHELPMSGSTRINGW[] = { 'a','c','m',
|
||||
'c','h','o','o','s','e','_','h','e','l','p',0 };
|
||||
#endif
|
||||
#define ACMHELPMSGSTRING WINELIB_NAME_AW(ACMHELPMSGSTRING)
|
||||
|
||||
#define ACMHELPMSGCONTEXTMENUA "acmchoose_contextmenu"
|
||||
#if defined(__GNUC__)
|
||||
# define ACMHELPMSGCONTEXTMENUW (const WCHAR []){ 'a','c','m', \
|
||||
'c','h','o','o','s','e','_','c','o','n','t','e','x','t','m','e','n','u',0 }
|
||||
#elif defined(_MSC_VER)
|
||||
# define ACMHELPMSGCONTEXTMENUW L"acmchoose_contextmenu"
|
||||
#else
|
||||
static const WCHAR ACMHELPMSGCONTEXTMENUW[] = { 'a','c','m',
|
||||
'c','h','o','o','s','e','_','c','o','n','t','e','x','t','m','e','n','u',0 };
|
||||
#endif
|
||||
#define ACMHELPMSGCONTEXTMENU WINELIB_NAME_AW(ACMHELPMSGCONTEXTMENU)
|
||||
|
||||
#define ACMHELPMSGCONTEXTHELPA "acmchoose_contexthelp"
|
||||
#if defined(__GNUC__)
|
||||
# define ACMHELPMSGCONTEXTHELPW (const WCHAR []){ 'a','c','m', \
|
||||
'c','h','o','o','s','e','_','c','o','n','t','e','x','t','h','e','l','p',0 }
|
||||
#elif defined(_MSC_VER)
|
||||
# define ACMHELPMSGCONTEXTHELPW L"acmchoose_contexthelp"
|
||||
#else
|
||||
static const WCHAR ACMHELPMSGCONTEXTHELPW[] = { 'a','c','m',
|
||||
'c','h','o','o','s','e','_','c','o','n','t','e','x','t','h','e','l','p',0 };
|
||||
#endif
|
||||
#define ACMHELPMSGCONTEXTHELP WINELIB_NAME_AW(ACMHELPMSGCONTEXTHELP)
|
||||
|
||||
#define MM_ACM_FORMATCHOOSE 0x8000
|
||||
|
||||
#define FORMATCHOOSE_MESSAGE 0
|
||||
#define FORMATCHOOSE_FORMATTAG_VERIFY (FORMATCHOOSE_MESSAGE+0)
|
||||
#define FORMATCHOOSE_FORMAT_VERIFY (FORMATCHOOSE_MESSAGE+1)
|
||||
#define FORMATCHOOSE_CUSTOM_VERIFY (FORMATCHOOSE_MESSAGE+2)
|
||||
|
||||
#define ACMFORMATCHOOSE_STYLEF_SHOWHELP 0x00000004L
|
||||
#define ACMFORMATCHOOSE_STYLEF_ENABLEHOOK 0x00000008L
|
||||
#define ACMFORMATCHOOSE_STYLEF_ENABLETEMPLATE 0x00000010L
|
||||
#define ACMFORMATCHOOSE_STYLEF_ENABLETEMPLATEHANDLE 0x00000020L
|
||||
#define ACMFORMATCHOOSE_STYLEF_INITTOWFXSTRUCT 0x00000040L
|
||||
#define ACMFORMATCHOOSE_STYLEF_CONTEXTHELP 0x00000080L
|
||||
|
||||
#define ACMFORMATDETAILS_FORMAT_CHARS 128
|
||||
|
||||
#define ACM_FORMATDETAILSF_INDEX 0x00000000L
|
||||
#define ACM_FORMATDETAILSF_FORMAT 0x00000001L
|
||||
#define ACM_FORMATDETAILSF_QUERYMASK 0x0000000FL
|
||||
|
||||
#define ACM_FORMATENUMF_WFORMATTAG 0x00010000L
|
||||
#define ACM_FORMATENUMF_NCHANNELS 0x00020000L
|
||||
#define ACM_FORMATENUMF_NSAMPLESPERSEC 0x00040000L
|
||||
#define ACM_FORMATENUMF_WBITSPERSAMPLE 0x00080000L
|
||||
#define ACM_FORMATENUMF_CONVERT 0x00100000L
|
||||
#define ACM_FORMATENUMF_SUGGEST 0x00200000L
|
||||
#define ACM_FORMATENUMF_HARDWARE 0x00400000L
|
||||
#define ACM_FORMATENUMF_INPUT 0x00800000L
|
||||
#define ACM_FORMATENUMF_OUTPUT 0x01000000L
|
||||
|
||||
#define ACM_FORMATSUGGESTF_WFORMATTAG 0x00010000L
|
||||
#define ACM_FORMATSUGGESTF_NCHANNELS 0x00020000L
|
||||
#define ACM_FORMATSUGGESTF_NSAMPLESPERSEC 0x00040000L
|
||||
#define ACM_FORMATSUGGESTF_WBITSPERSAMPLE 0x00080000L
|
||||
#define ACM_FORMATSUGGESTF_TYPEMASK 0x00FF0000L
|
||||
|
||||
#define ACMFORMATTAGDETAILS_FORMATTAG_CHARS 48
|
||||
|
||||
#define ACM_FORMATTAGDETAILSF_INDEX 0x00000000L
|
||||
#define ACM_FORMATTAGDETAILSF_FORMATTAG 0x00000001L
|
||||
#define ACM_FORMATTAGDETAILSF_LARGESTSIZE 0x00000002L
|
||||
#define ACM_FORMATTAGDETAILSF_QUERYMASK 0x0000000FL
|
||||
|
||||
#define ACM_METRIC_COUNT_DRIVERS 1
|
||||
#define ACM_METRIC_COUNT_CODECS 2
|
||||
#define ACM_METRIC_COUNT_CONVERTERS 3
|
||||
#define ACM_METRIC_COUNT_FILTERS 4
|
||||
#define ACM_METRIC_COUNT_DISABLED 5
|
||||
#define ACM_METRIC_COUNT_HARDWARE 6
|
||||
#define ACM_METRIC_COUNT_LOCAL_DRIVERS 20
|
||||
#define ACM_METRIC_COUNT_LOCAL_CODECS 21
|
||||
#define ACM_METRIC_COUNT_LOCAL_CONVERTERS 22
|
||||
#define ACM_METRIC_COUNT_LOCAL_FILTERS 23
|
||||
#define ACM_METRIC_COUNT_LOCAL_DISABLED 24
|
||||
#define ACM_METRIC_HARDWARE_WAVE_INPUT 30
|
||||
#define ACM_METRIC_HARDWARE_WAVE_OUTPUT 31
|
||||
#define ACM_METRIC_MAX_SIZE_FORMAT 50
|
||||
#define ACM_METRIC_MAX_SIZE_FILTER 51
|
||||
#define ACM_METRIC_DRIVER_SUPPORT 100
|
||||
#define ACM_METRIC_DRIVER_PRIORITY 101
|
||||
|
||||
#define ACM_STREAMCONVERTF_BLOCKALIGN 0x00000004
|
||||
#define ACM_STREAMCONVERTF_START 0x00000010
|
||||
#define ACM_STREAMCONVERTF_END 0x00000020
|
||||
|
||||
#define ACMSTREAMHEADER_STATUSF_DONE 0x00010000L
|
||||
#define ACMSTREAMHEADER_STATUSF_PREPARED 0x00020000L
|
||||
#define ACMSTREAMHEADER_STATUSF_INQUEUE 0x00100000L
|
||||
|
||||
#define ACM_STREAMOPENF_QUERY 0x00000001
|
||||
#define ACM_STREAMOPENF_ASYNC 0x00000002
|
||||
#define ACM_STREAMOPENF_NONREALTIME 0x00000004
|
||||
|
||||
#define ACM_STREAMSIZEF_SOURCE 0x00000000L
|
||||
#define ACM_STREAMSIZEF_DESTINATION 0x00000001L
|
||||
#define ACM_STREAMSIZEF_QUERYMASK 0x0000000FL
|
||||
|
||||
#define ACMDM_USER (DRV_USER + 0x0000)
|
||||
#define ACMDM_RESERVED_LOW (DRV_USER + 0x2000)
|
||||
#define ACMDM_RESERVED_HIGH (DRV_USER + 0x2FFF)
|
||||
|
||||
#define ACMDM_BASE ACMDM_RESERVED_LOW
|
||||
|
||||
#define ACMDM_DRIVER_ABOUT (ACMDM_BASE + 11)
|
||||
|
||||
/* handles */
|
||||
|
||||
DECLARE_HANDLE(HACMDRIVERID);
|
||||
DECLARE_HANDLE(HACMDRIVER);
|
||||
DECLARE_HANDLE(HACMSTREAM);
|
||||
DECLARE_HANDLE(HACMOBJ);
|
||||
typedef HACMDRIVERID *PHACMDRIVERID, *LPHACMDRIVERID;
|
||||
typedef HACMDRIVER *PHACMDRIVER, *LPHACMDRIVER;
|
||||
typedef HACMSTREAM *PHACMSTREAM, *LPHACMSTREAM;
|
||||
typedef HACMOBJ *PHACMOBJ, *LPHACMOBJ;
|
||||
|
||||
/***********************************************************************
|
||||
* Callbacks
|
||||
*/
|
||||
|
||||
typedef BOOL (CALLBACK *ACMDRIVERENUMCB)(
|
||||
HACMDRIVERID hadid, DWORD dwInstance, DWORD fdwSupport
|
||||
);
|
||||
|
||||
typedef UINT (CALLBACK *ACMFILTERCHOOSEHOOKPROCA)(
|
||||
HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam
|
||||
);
|
||||
|
||||
typedef UINT (CALLBACK *ACMFILTERCHOOSEHOOKPROCW)(
|
||||
HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam
|
||||
);
|
||||
#define ACMFILTERCHOOSEHOOKPROC WINELIB_NAME_AW(ACMFILTERCHOOSEHOOKPROC)
|
||||
|
||||
typedef UINT (CALLBACK *ACMFORMATCHOOSEHOOKPROCA)(
|
||||
HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam
|
||||
);
|
||||
|
||||
typedef UINT (CALLBACK *ACMFORMATCHOOSEHOOKPROCW)(
|
||||
HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam
|
||||
);
|
||||
#define ACMFORMATCHOOSEHOOKPROC WINELIB_NAME_AW(ACMFORMATCHOOSEHOOKPROC)
|
||||
|
||||
/***********************************************************************
|
||||
* Structures
|
||||
*/
|
||||
|
||||
typedef struct _ACMDRIVERDETAILSA
|
||||
{
|
||||
DWORD cbStruct;
|
||||
|
||||
FOURCC fccType;
|
||||
FOURCC fccComp;
|
||||
|
||||
WORD wMid;
|
||||
WORD wPid;
|
||||
|
||||
DWORD vdwACM;
|
||||
DWORD vdwDriver;
|
||||
|
||||
DWORD fdwSupport;
|
||||
DWORD cFormatTags;
|
||||
DWORD cFilterTags;
|
||||
|
||||
HICON hicon;
|
||||
|
||||
CHAR szShortName[ACMDRIVERDETAILS_SHORTNAME_CHARS];
|
||||
CHAR szLongName[ACMDRIVERDETAILS_LONGNAME_CHARS];
|
||||
CHAR szCopyright[ACMDRIVERDETAILS_COPYRIGHT_CHARS];
|
||||
CHAR szLicensing[ACMDRIVERDETAILS_LICENSING_CHARS];
|
||||
CHAR szFeatures[ACMDRIVERDETAILS_FEATURES_CHARS];
|
||||
} ACMDRIVERDETAILSA, *PACMDRIVERDETAILSA, *LPACMDRIVERDETAILSA;
|
||||
|
||||
typedef struct _ACMDRIVERDETAILSW
|
||||
{
|
||||
DWORD cbStruct;
|
||||
|
||||
FOURCC fccType;
|
||||
FOURCC fccComp;
|
||||
|
||||
WORD wMid;
|
||||
WORD wPid;
|
||||
|
||||
DWORD vdwACM;
|
||||
DWORD vdwDriver;
|
||||
|
||||
DWORD fdwSupport;
|
||||
DWORD cFormatTags;
|
||||
DWORD cFilterTags;
|
||||
|
||||
HICON hicon;
|
||||
|
||||
WCHAR szShortName[ACMDRIVERDETAILS_SHORTNAME_CHARS];
|
||||
WCHAR szLongName[ACMDRIVERDETAILS_LONGNAME_CHARS];
|
||||
WCHAR szCopyright[ACMDRIVERDETAILS_COPYRIGHT_CHARS];
|
||||
WCHAR szLicensing[ACMDRIVERDETAILS_LICENSING_CHARS];
|
||||
WCHAR szFeatures[ACMDRIVERDETAILS_FEATURES_CHARS];
|
||||
} ACMDRIVERDETAILSW, *PACMDRIVERDETAILSW, *LPACMDRIVERDETAILSW;
|
||||
|
||||
DECL_WINELIB_TYPE_AW(ACMDRIVERDETAILS)
|
||||
DECL_WINELIB_TYPE_AW(PACMDRIVERDETAILS)
|
||||
DECL_WINELIB_TYPE_AW(LPACMDRIVERDETAILS)
|
||||
|
||||
typedef struct _ACMFILTERCHOOSEA
|
||||
{
|
||||
DWORD cbStruct;
|
||||
DWORD fdwStyle;
|
||||
|
||||
HWND hwndOwner;
|
||||
|
||||
PWAVEFILTER pwfltr;
|
||||
DWORD cbwfltr;
|
||||
|
||||
LPCSTR pszTitle;
|
||||
|
||||
CHAR szFilterTag[ACMFILTERTAGDETAILS_FILTERTAG_CHARS];
|
||||
CHAR szFilter[ACMFILTERDETAILS_FILTER_CHARS];
|
||||
LPSTR pszName;
|
||||
DWORD cchName;
|
||||
|
||||
DWORD fdwEnum;
|
||||
PWAVEFILTER pwfltrEnum;
|
||||
|
||||
HINSTANCE hInstance;
|
||||
LPCSTR pszTemplateName;
|
||||
LPARAM lCustData;
|
||||
ACMFILTERCHOOSEHOOKPROCA pfnHook;
|
||||
} ACMFILTERCHOOSEA, *PACMFILTERCHOOSEA, *LPACMFILTERCHOOSEA;
|
||||
|
||||
typedef struct _ACMFILTERCHOOSEW
|
||||
{
|
||||
DWORD cbStruct;
|
||||
DWORD fdwStyle;
|
||||
|
||||
HWND hwndOwner;
|
||||
|
||||
PWAVEFILTER pwfltr;
|
||||
DWORD cbwfltr;
|
||||
|
||||
LPCWSTR pszTitle;
|
||||
|
||||
WCHAR szFilterTag[ACMFILTERTAGDETAILS_FILTERTAG_CHARS];
|
||||
WCHAR szFilter[ACMFILTERDETAILS_FILTER_CHARS];
|
||||
LPWSTR pszName;
|
||||
DWORD cchName;
|
||||
|
||||
DWORD fdwEnum;
|
||||
PWAVEFILTER pwfltrEnum;
|
||||
|
||||
HINSTANCE hInstance;
|
||||
LPCWSTR pszTemplateName;
|
||||
LPARAM lCustData;
|
||||
ACMFILTERCHOOSEHOOKPROCW pfnHook;
|
||||
} ACMFILTERCHOOSEW, *PACMFILTERCHOOSEW, *LPACMFILTERCHOOSEW;
|
||||
|
||||
DECL_WINELIB_TYPE_AW(ACMFILTERCHOOSE)
|
||||
DECL_WINELIB_TYPE_AW(PACMFILTERCHOOSE)
|
||||
DECL_WINELIB_TYPE_AW(LPACMFILTERCHOOSE)
|
||||
|
||||
typedef struct _ACMFILTERDETAILSA
|
||||
{
|
||||
DWORD cbStruct;
|
||||
DWORD dwFilterIndex;
|
||||
DWORD dwFilterTag;
|
||||
DWORD fdwSupport;
|
||||
PWAVEFILTER pwfltr;
|
||||
DWORD cbwfltr;
|
||||
CHAR szFilter[ACMFILTERDETAILS_FILTER_CHARS];
|
||||
} ACMFILTERDETAILSA, *PACMFILTERDETAILSA, *LPACMFILTERDETAILSA;
|
||||
|
||||
typedef struct _ACMFILTERDETAILSW
|
||||
{
|
||||
DWORD cbStruct;
|
||||
DWORD dwFilterIndex;
|
||||
DWORD dwFilterTag;
|
||||
DWORD fdwSupport;
|
||||
PWAVEFILTER pwfltr;
|
||||
DWORD cbwfltr;
|
||||
WCHAR szFilter[ACMFILTERDETAILS_FILTER_CHARS];
|
||||
} ACMFILTERDETAILSW, *PACMFILTERDETAILSW, *LPACMFILTERDETAILSW;
|
||||
|
||||
DECL_WINELIB_TYPE_AW(ACMFILTERDETAILS)
|
||||
DECL_WINELIB_TYPE_AW(PACMFILTERDETAILS)
|
||||
DECL_WINELIB_TYPE_AW(LPACMFILTERDETAILS)
|
||||
|
||||
typedef struct _ACMFILTERTAGDETAILSA
|
||||
{
|
||||
DWORD cbStruct;
|
||||
DWORD dwFilterTagIndex;
|
||||
DWORD dwFilterTag;
|
||||
DWORD cbFilterSize;
|
||||
DWORD fdwSupport;
|
||||
DWORD cStandardFilters;
|
||||
CHAR szFilterTag[ACMFILTERTAGDETAILS_FILTERTAG_CHARS];
|
||||
} ACMFILTERTAGDETAILSA, *PACMFILTERTAGDETAILSA, *LPACMFILTERTAGDETAILSA;
|
||||
|
||||
typedef struct _ACMFILTERTAGDETAILSW
|
||||
{
|
||||
DWORD cbStruct;
|
||||
DWORD dwFilterTagIndex;
|
||||
DWORD dwFilterTag;
|
||||
DWORD cbFilterSize;
|
||||
DWORD fdwSupport;
|
||||
DWORD cStandardFilters;
|
||||
WCHAR szFilterTag[ACMFILTERTAGDETAILS_FILTERTAG_CHARS];
|
||||
} ACMFILTERTAGDETAILSW, *PACMFILTERTAGDETAILSW, *LPACMFILTERTAGDETAILSW;
|
||||
|
||||
DECL_WINELIB_TYPE_AW(ACMFILTERTAGDETAILS)
|
||||
DECL_WINELIB_TYPE_AW(PACMFILTERTAGDETAILS)
|
||||
DECL_WINELIB_TYPE_AW(LPACMFILTERTAGDETAILS)
|
||||
|
||||
typedef struct _ACMFORMATCHOOSEA
|
||||
{
|
||||
DWORD cbStruct;
|
||||
DWORD fdwStyle;
|
||||
|
||||
HWND hwndOwner;
|
||||
|
||||
PWAVEFORMATEX pwfx;
|
||||
DWORD cbwfx;
|
||||
LPCSTR pszTitle;
|
||||
|
||||
CHAR szFormatTag[ACMFORMATTAGDETAILS_FORMATTAG_CHARS];
|
||||
CHAR szFormat[ACMFORMATDETAILS_FORMAT_CHARS];
|
||||
|
||||
LPSTR pszName;
|
||||
DWORD cchName;
|
||||
|
||||
DWORD fdwEnum;
|
||||
PWAVEFORMATEX pwfxEnum;
|
||||
|
||||
HINSTANCE hInstance;
|
||||
LPCSTR pszTemplateName;
|
||||
LPARAM lCustData;
|
||||
ACMFORMATCHOOSEHOOKPROCA pfnHook;
|
||||
} ACMFORMATCHOOSEA, *PACMFORMATCHOOSEA, *LPACMFORMATCHOOSEA;
|
||||
|
||||
typedef struct _ACMFORMATCHOOSEW
|
||||
{
|
||||
DWORD cbStruct;
|
||||
DWORD fdwStyle;
|
||||
|
||||
HWND hwndOwner;
|
||||
|
||||
PWAVEFORMATEX pwfx;
|
||||
DWORD cbwfx;
|
||||
LPCWSTR pszTitle;
|
||||
|
||||
WCHAR szFormatTag[ACMFORMATTAGDETAILS_FORMATTAG_CHARS];
|
||||
WCHAR szFormat[ACMFORMATDETAILS_FORMAT_CHARS];
|
||||
|
||||
LPWSTR pszName;
|
||||
DWORD cchName;
|
||||
|
||||
DWORD fdwEnum;
|
||||
LPWAVEFORMATEX pwfxEnum;
|
||||
|
||||
HINSTANCE hInstance;
|
||||
LPCWSTR pszTemplateName;
|
||||
LPARAM lCustData;
|
||||
ACMFORMATCHOOSEHOOKPROCW pfnHook;
|
||||
} ACMFORMATCHOOSEW, *PACMFORMATCHOOSEW, *LPACMFORMATCHOOSEW;
|
||||
|
||||
DECL_WINELIB_TYPE_AW(ACMFORMATCHOOSE)
|
||||
DECL_WINELIB_TYPE_AW(PACMFORMATCHOOSE)
|
||||
DECL_WINELIB_TYPE_AW(LPACMFORMATCHOOSE)
|
||||
|
||||
typedef struct _ACMFORMATDETAILSA
|
||||
{
|
||||
DWORD cbStruct;
|
||||
DWORD dwFormatIndex;
|
||||
DWORD dwFormatTag;
|
||||
DWORD fdwSupport;
|
||||
PWAVEFORMATEX pwfx;
|
||||
DWORD cbwfx;
|
||||
CHAR szFormat[ACMFORMATDETAILS_FORMAT_CHARS];
|
||||
} ACMFORMATDETAILSA, *PACMFORMATDETAILSA, *LPACMFORMATDETAILSA;
|
||||
|
||||
typedef struct _ACMFORMATDETAILSW
|
||||
{
|
||||
DWORD cbStruct;
|
||||
DWORD dwFormatIndex;
|
||||
DWORD dwFormatTag;
|
||||
DWORD fdwSupport;
|
||||
PWAVEFORMATEX pwfx;
|
||||
DWORD cbwfx;
|
||||
WCHAR szFormat[ACMFORMATDETAILS_FORMAT_CHARS];
|
||||
} ACMFORMATDETAILSW, *PACMFORMATDETAILSW, *LPACMFORMATDETAILSW;
|
||||
|
||||
DECL_WINELIB_TYPE_AW(ACMFORMATDETAILS)
|
||||
DECL_WINELIB_TYPE_AW(PACMFORMATDETAILS)
|
||||
DECL_WINELIB_TYPE_AW(LPACMFORMATDETAILS)
|
||||
|
||||
typedef struct _ACMFORMATTAGDETAILSA
|
||||
{
|
||||
DWORD cbStruct;
|
||||
DWORD dwFormatTagIndex;
|
||||
DWORD dwFormatTag;
|
||||
DWORD cbFormatSize;
|
||||
DWORD fdwSupport;
|
||||
DWORD cStandardFormats;
|
||||
CHAR szFormatTag[ACMFORMATTAGDETAILS_FORMATTAG_CHARS];
|
||||
} ACMFORMATTAGDETAILSA, *PACMFORMATTAGDETAILSA, *LPACMFORMATTAGDETAILSA;
|
||||
|
||||
typedef struct _ACMFORMATTAGDETAILSW
|
||||
{
|
||||
DWORD cbStruct;
|
||||
DWORD dwFormatTagIndex;
|
||||
DWORD dwFormatTag;
|
||||
DWORD cbFormatSize;
|
||||
DWORD fdwSupport;
|
||||
DWORD cStandardFormats;
|
||||
WCHAR szFormatTag[ACMFORMATTAGDETAILS_FORMATTAG_CHARS];
|
||||
} ACMFORMATTAGDETAILSW, *PACMFORMATTAGDETAILSW, *LPACMFORMATTAGDETAILSW;
|
||||
|
||||
DECL_WINELIB_TYPE_AW(ACMFORMATTAGDETAILS)
|
||||
DECL_WINELIB_TYPE_AW(PACMFORMATTAGDETAILS)
|
||||
DECL_WINELIB_TYPE_AW(LPACMFORMATTAGDETAILS)
|
||||
|
||||
typedef struct _ACMSTREAMHEADER
|
||||
{
|
||||
DWORD cbStruct;
|
||||
DWORD fdwStatus;
|
||||
DWORD dwUser;
|
||||
LPBYTE pbSrc;
|
||||
DWORD cbSrcLength;
|
||||
DWORD cbSrcLengthUsed;
|
||||
DWORD dwSrcUser;
|
||||
LPBYTE pbDst;
|
||||
DWORD cbDstLength;
|
||||
DWORD cbDstLengthUsed;
|
||||
DWORD dwDstUser;
|
||||
DWORD dwReservedDriver[10];
|
||||
} ACMSTREAMHEADER, *PACMSTREAMHEADER, *LPACMSTREAMHEADER;
|
||||
|
||||
/***********************************************************************
|
||||
* Callbacks 2
|
||||
*/
|
||||
|
||||
typedef BOOL (CALLBACK *ACMFILTERENUMCBA)(
|
||||
HACMDRIVERID hadid, PACMFILTERDETAILSA pafd,
|
||||
DWORD dwInstance, DWORD fdwSupport
|
||||
);
|
||||
|
||||
typedef BOOL (CALLBACK *ACMFILTERENUMCBW)(
|
||||
HACMDRIVERID hadid, PACMFILTERDETAILSW pafd,
|
||||
DWORD dwInstance, DWORD fdwSupport
|
||||
);
|
||||
|
||||
#define ACMFILTERENUMCB WINELIB_NAME_AW(ACMFILTERENUMCB)
|
||||
|
||||
typedef BOOL (CALLBACK *ACMFILTERTAGENUMCBA)(
|
||||
HACMDRIVERID hadid, PACMFILTERTAGDETAILSA paftd,
|
||||
DWORD dwInstance, DWORD fdwSupport
|
||||
);
|
||||
|
||||
typedef BOOL (CALLBACK *ACMFILTERTAGENUMCBW)(
|
||||
HACMDRIVERID hadid, PACMFILTERTAGDETAILSW paftd,
|
||||
DWORD dwInstance, DWORD fdwSupport
|
||||
);
|
||||
|
||||
#define ACMFILTERTAGENUMCB WINELIB_NAME_AW(ACMFILTERTAGENUMCB)
|
||||
|
||||
typedef BOOL (CALLBACK *ACMFORMATENUMCBA)(
|
||||
HACMDRIVERID hadid, PACMFORMATDETAILSA pafd,
|
||||
DWORD dwInstance, DWORD fdwSupport
|
||||
);
|
||||
|
||||
typedef BOOL (CALLBACK *ACMFORMATENUMCBW)(
|
||||
HACMDRIVERID hadid, PACMFORMATDETAILSW pafd,
|
||||
DWORD dwInstance, DWORD fdwSupport
|
||||
);
|
||||
|
||||
#define ACMFORMATENUMCB WINELIB_NAME_AW(ACMFORMATENUMCB)
|
||||
|
||||
typedef BOOL (CALLBACK *ACMFORMATTAGENUMCBA)(
|
||||
HACMDRIVERID hadid, PACMFORMATTAGDETAILSA paftd,
|
||||
DWORD dwInstance, DWORD fdwSupport
|
||||
);
|
||||
|
||||
typedef BOOL (CALLBACK *ACMFORMATTAGENUMCBW)(
|
||||
HACMDRIVERID hadid, PACMFORMATTAGDETAILSW paftd,
|
||||
DWORD dwInstance, DWORD fdwSupport
|
||||
);
|
||||
|
||||
#define ACMFORMATTAGENUMCB WINELIB_NAME_AW(ACMFORMATTAGENUMCB)
|
||||
|
||||
/***********************************************************************
|
||||
* Functions - Win32
|
||||
*/
|
||||
|
||||
MMRESULT WINAPI acmDriverAddA(
|
||||
PHACMDRIVERID phadid, HINSTANCE hinstModule,
|
||||
LPARAM lParam, DWORD dwPriority, DWORD fdwAdd
|
||||
);
|
||||
MMRESULT WINAPI acmDriverAddW(
|
||||
PHACMDRIVERID phadid, HINSTANCE hinstModule,
|
||||
LPARAM lParam, DWORD dwPriority, DWORD fdwAdd
|
||||
);
|
||||
#define acmDriverAdd WINELIB_NAME_AW(acmDriverAdd)
|
||||
|
||||
MMRESULT WINAPI acmDriverClose(
|
||||
HACMDRIVER had, DWORD fdwClose
|
||||
);
|
||||
MMRESULT WINAPI acmDriverDetailsA(
|
||||
HACMDRIVERID hadid, PACMDRIVERDETAILSA padd, DWORD fdwDetails
|
||||
);
|
||||
MMRESULT WINAPI acmDriverDetailsW(
|
||||
HACMDRIVERID hadid, PACMDRIVERDETAILSW padd, DWORD fdwDetails
|
||||
);
|
||||
#define acmDriverDetails WINELIB_NAME_AW(acmDriverDetails)
|
||||
|
||||
MMRESULT WINAPI acmDriverEnum(
|
||||
ACMDRIVERENUMCB fnCallback, DWORD dwInstance, DWORD fdwEnum
|
||||
);
|
||||
MMRESULT WINAPI acmDriverID(
|
||||
HACMOBJ hao, PHACMDRIVERID phadid, DWORD fdwDriverID
|
||||
);
|
||||
LRESULT WINAPI acmDriverMessage(
|
||||
HACMDRIVER had, UINT uMsg, LPARAM lParam1, LPARAM lParam2
|
||||
);
|
||||
MMRESULT WINAPI acmDriverOpen(
|
||||
PHACMDRIVER phad, HACMDRIVERID hadid, DWORD fdwOpen
|
||||
);
|
||||
MMRESULT WINAPI acmDriverPriority(
|
||||
HACMDRIVERID hadid, DWORD dwPriority, DWORD fdwPriority
|
||||
);
|
||||
MMRESULT WINAPI acmDriverRemove(
|
||||
HACMDRIVERID hadid, DWORD fdwRemove
|
||||
);
|
||||
MMRESULT WINAPI acmFilterChooseA(
|
||||
PACMFILTERCHOOSEA pafltrc
|
||||
);
|
||||
MMRESULT WINAPI acmFilterChooseW(
|
||||
PACMFILTERCHOOSEW pafltrc
|
||||
);
|
||||
#define acmFilterChoose WINELIB_NAME_AW(acmFilterChoose)
|
||||
|
||||
MMRESULT WINAPI acmFilterDetailsA(
|
||||
HACMDRIVER had, PACMFILTERDETAILSA pafd, DWORD fdwDetails
|
||||
);
|
||||
MMRESULT WINAPI acmFilterDetailsW(
|
||||
HACMDRIVER had, PACMFILTERDETAILSW pafd, DWORD fdwDetails
|
||||
);
|
||||
#define acmFilterDetails WINELIB_NAME_AW(acmFilterDetails)
|
||||
|
||||
MMRESULT WINAPI acmFilterEnumA(
|
||||
HACMDRIVER had, PACMFILTERDETAILSA pafd,
|
||||
ACMFILTERENUMCBA fnCallback, DWORD dwInstance, DWORD fdwEnum
|
||||
);
|
||||
MMRESULT WINAPI acmFilterEnumW(
|
||||
HACMDRIVER had, PACMFILTERDETAILSW pafd,
|
||||
ACMFILTERENUMCBW fnCallback, DWORD dwInstance, DWORD fdwEnum
|
||||
);
|
||||
#define acmFilterEnum WINELIB_NAME_AW(acmFilterEnum)
|
||||
|
||||
MMRESULT WINAPI acmFilterTagDetailsA(
|
||||
HACMDRIVER had, PACMFILTERTAGDETAILSA paftd, DWORD fdwDetails
|
||||
);
|
||||
MMRESULT WINAPI acmFilterTagDetailsW(
|
||||
HACMDRIVER had, PACMFILTERTAGDETAILSW paftd, DWORD fdwDetails
|
||||
);
|
||||
#define acmFilterTagDetails WINELIB_NAME_AW(acmFilterTagDetails)
|
||||
|
||||
MMRESULT WINAPI acmFilterTagEnumA(
|
||||
HACMDRIVER had, PACMFILTERTAGDETAILSA paftd,
|
||||
ACMFILTERTAGENUMCBA fnCallback, DWORD dwInstance, DWORD fdwEnum
|
||||
);
|
||||
MMRESULT WINAPI acmFilterTagEnumW(
|
||||
HACMDRIVER had, PACMFILTERTAGDETAILSW paftd,
|
||||
ACMFILTERTAGENUMCBW fnCallback, DWORD dwInstance, DWORD fdwEnum
|
||||
);
|
||||
#define acmFilterTagEnum WINELIB_NAME_AW(acmFilterTagEnum)
|
||||
|
||||
MMRESULT WINAPI acmFormatChooseA(
|
||||
PACMFORMATCHOOSEA pafmtc
|
||||
);
|
||||
MMRESULT WINAPI acmFormatChooseW(
|
||||
PACMFORMATCHOOSEW pafmtc
|
||||
);
|
||||
#define acmFormatChoose WINELIB_NAME_AW(acmFormatChoose)
|
||||
|
||||
MMRESULT WINAPI acmFormatDetailsA(
|
||||
HACMDRIVER had, PACMFORMATDETAILSA pafd, DWORD fdwDetails
|
||||
);
|
||||
MMRESULT WINAPI acmFormatDetailsW(
|
||||
HACMDRIVER had, PACMFORMATDETAILSW pafd, DWORD fdwDetails
|
||||
);
|
||||
#define acmFormatDetails WINELIB_NAME_AW(acmFormatDetails)
|
||||
|
||||
MMRESULT WINAPI acmFormatEnumA(
|
||||
HACMDRIVER had, PACMFORMATDETAILSA pafd,
|
||||
ACMFORMATENUMCBA fnCallback, DWORD dwInstance, DWORD fdwEnum
|
||||
);
|
||||
MMRESULT WINAPI acmFormatEnumW(
|
||||
HACMDRIVER had, PACMFORMATDETAILSW pafd,
|
||||
ACMFORMATENUMCBW fnCallback, DWORD dwInstance, DWORD fdwEnum
|
||||
);
|
||||
#define acmFormatEnum WINELIB_NAME_AW(acmFormatEnum)
|
||||
|
||||
MMRESULT WINAPI acmFormatSuggest(
|
||||
HACMDRIVER had, PWAVEFORMATEX pwfxSrc, PWAVEFORMATEX pwfxDst,
|
||||
DWORD cbwfxDst, DWORD fdwSuggest
|
||||
);
|
||||
MMRESULT WINAPI acmFormatTagDetailsA(
|
||||
HACMDRIVER had, PACMFORMATTAGDETAILSA paftd, DWORD fdwDetails
|
||||
);
|
||||
MMRESULT WINAPI acmFormatTagDetailsW(
|
||||
HACMDRIVER had, PACMFORMATTAGDETAILSW paftd, DWORD fdwDetails
|
||||
);
|
||||
#define acmFormatTagDetails WINELIB_NAME_AW(acmFormatTagDetails)
|
||||
|
||||
MMRESULT WINAPI acmFormatTagEnumA(
|
||||
HACMDRIVER had, PACMFORMATTAGDETAILSA paftd,
|
||||
ACMFORMATTAGENUMCBA fnCallback, DWORD dwInstance, DWORD fdwEnum
|
||||
);
|
||||
MMRESULT WINAPI acmFormatTagEnumW(
|
||||
HACMDRIVER had, PACMFORMATTAGDETAILSW paftd,
|
||||
ACMFORMATTAGENUMCBW fnCallback, DWORD dwInstance, DWORD fdwEnum
|
||||
);
|
||||
#define acmFormatTagEnum WINELIB_NAME_AW(acmFormatTagEnum)
|
||||
|
||||
DWORD WINAPI acmGetVersion(void
|
||||
);
|
||||
MMRESULT WINAPI acmMetrics(
|
||||
HACMOBJ hao, UINT uMetric, LPVOID pMetric
|
||||
);
|
||||
MMRESULT WINAPI acmStreamClose(
|
||||
HACMSTREAM has, DWORD fdwClose
|
||||
);
|
||||
MMRESULT WINAPI acmStreamConvert(
|
||||
HACMSTREAM has, PACMSTREAMHEADER pash, DWORD fdwConvert
|
||||
);
|
||||
MMRESULT WINAPI acmStreamMessage(
|
||||
HACMSTREAM has, UINT uMsg, LPARAM lParam1, LPARAM lParam2
|
||||
);
|
||||
MMRESULT WINAPI acmStreamOpen(
|
||||
PHACMSTREAM phas, HACMDRIVER had, PWAVEFORMATEX pwfxSrc,
|
||||
PWAVEFORMATEX pwfxDst, PWAVEFILTER pwfltr, DWORD dwCallback,
|
||||
DWORD dwInstance, DWORD fdwOpen
|
||||
);
|
||||
MMRESULT WINAPI acmStreamPrepareHeader(
|
||||
HACMSTREAM has, PACMSTREAMHEADER pash, DWORD fdwPrepare
|
||||
);
|
||||
MMRESULT WINAPI acmStreamReset(
|
||||
HACMSTREAM has, DWORD fdwReset
|
||||
);
|
||||
MMRESULT WINAPI acmStreamSize(
|
||||
HACMSTREAM has, DWORD cbInput,
|
||||
LPDWORD pdwOutputBytes, DWORD fdwSize
|
||||
);
|
||||
MMRESULT WINAPI acmStreamUnprepareHeader(
|
||||
HACMSTREAM has, PACMSTREAMHEADER pash, DWORD fdwUnprepare
|
||||
);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif /* defined(__cplusplus) */
|
||||
|
||||
#endif /* __WINE_MSACM_H */
|
36
reactos/include/wine/msacmdlg.h
Normal file
36
reactos/include/wine/msacmdlg.h
Normal file
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* definitions for MSACM dialog boxes
|
||||
*
|
||||
* Copyright (C) 2001 Eric Pouech
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#define DLG_ACMFORMATCHOOSE_ID 70
|
||||
#define IDD_ACMFORMATCHOOSE_BTN_HELP 9
|
||||
#define IDD_ACMFORMATCHOOSE_CMB_CUSTOM 100
|
||||
#define IDD_ACMFORMATCHOOSE_CMB_FORMATTAG 101
|
||||
#define IDD_ACMFORMATCHOOSE_CMB_FORMAT 102
|
||||
#define IDD_ACMFORMATCHOOSE_BTN_SETNAME 103
|
||||
#define IDD_ACMFORMATCHOOSE_BTN_DELNAME 104
|
||||
|
||||
#define DLG_ACMFILTERCHOOSE_ID 71
|
||||
#define IDD_ACMFILTERCHOOSE_BTN_HELP 9
|
||||
#define IDD_ACMFILTERCHOOSE_CMB_CUSTOM 100
|
||||
#define IDD_ACMFILTERCHOOSE_CMB_FILTERTAG 101
|
||||
#define IDD_ACMFILTERCHOOSE_CMB_FILTER 102
|
||||
#define IDD_ACMFILTERCHOOSE_BTN_SETNAME 103
|
||||
#define IDD_ACMFILTERCHOOSE_BTN_DELNAME 104
|
||||
|
157
reactos/include/wine/msacmdrv.h
Normal file
157
reactos/include/wine/msacmdrv.h
Normal file
|
@ -0,0 +1,157 @@
|
|||
/*
|
||||
* Declarations for MSACM driver
|
||||
*
|
||||
* Copyright 1998 Patrik Stridvall
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef __WINE_MSACMDRV_H
|
||||
#define __WINE_MSACMDRV_H
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "mmsystem.h"
|
||||
#include "mmreg.h"
|
||||
#include "msacm.h"
|
||||
|
||||
/***********************************************************************
|
||||
* Types
|
||||
*/
|
||||
|
||||
/***********************************************************************
|
||||
* Defines/Enums
|
||||
*/
|
||||
|
||||
#define MAKE_ACM_VERSION(mjr, mnr, bld) \
|
||||
(((long)(mjr)<<24) | ((long)(mnr)<<16) | ((long)bld))
|
||||
|
||||
#define ACMDRVOPENDESC_SECTIONNAME_CHARS
|
||||
|
||||
#define ACMDM_DRIVER_NOTIFY (ACMDM_BASE + 1)
|
||||
#define ACMDM_DRIVER_DETAILS (ACMDM_BASE + 10)
|
||||
|
||||
#define ACMDM_HARDWARE_WAVE_CAPS_INPUT (ACMDM_BASE + 20)
|
||||
#define ACMDM_HARDWARE_WAVE_CAPS_OUTPUT (ACMDM_BASE + 21)
|
||||
|
||||
#define ACMDM_FORMATTAG_DETAILS (ACMDM_BASE + 25)
|
||||
#define ACMDM_FORMAT_DETAILS (ACMDM_BASE + 26)
|
||||
#define ACMDM_FORMAT_SUGGEST (ACMDM_BASE + 27)
|
||||
|
||||
#define ACMDM_FILTERTAG_DETAILS (ACMDM_BASE + 50)
|
||||
#define ACMDM_FILTER_DETAILS (ACMDM_BASE + 51)
|
||||
|
||||
#define ACMDM_STREAM_OPEN (ACMDM_BASE + 76)
|
||||
#define ACMDM_STREAM_CLOSE (ACMDM_BASE + 77)
|
||||
#define ACMDM_STREAM_SIZE (ACMDM_BASE + 78)
|
||||
#define ACMDM_STREAM_CONVERT (ACMDM_BASE + 79)
|
||||
#define ACMDM_STREAM_RESET (ACMDM_BASE + 80)
|
||||
#define ACMDM_STREAM_PREPARE (ACMDM_BASE + 81)
|
||||
#define ACMDM_STREAM_UNPREPARE (ACMDM_BASE + 82)
|
||||
#define ACMDM_STREAM_UPDATE (ACMDM_BASE + 83)
|
||||
|
||||
/***********************************************************************
|
||||
* Structures
|
||||
*/
|
||||
|
||||
typedef struct _ACMDRVOPENDESCA
|
||||
{
|
||||
DWORD cbStruct;
|
||||
FOURCC fccType;
|
||||
FOURCC fccComp;
|
||||
DWORD dwVersion;
|
||||
DWORD dwFlags;
|
||||
DWORD dwError;
|
||||
LPCSTR pszSectionName;
|
||||
LPCSTR pszAliasName;
|
||||
DWORD dnDevNode;
|
||||
} ACMDRVOPENDESCA, *PACMDRVOPENDESCA;
|
||||
|
||||
typedef struct _ACMDRVOPENDESCW
|
||||
{
|
||||
DWORD cbStruct;
|
||||
FOURCC fccType;
|
||||
FOURCC fccComp;
|
||||
DWORD dwVersion;
|
||||
DWORD dwFlags;
|
||||
DWORD dwError;
|
||||
LPCWSTR pszSectionName;
|
||||
LPCWSTR pszAliasName;
|
||||
DWORD dnDevNode;
|
||||
} ACMDRVOPENDESCW, *PACMDRVOPENDESCW;
|
||||
|
||||
typedef struct _ACMDRVSTREAMINSTANCE
|
||||
{
|
||||
DWORD cbStruct;
|
||||
PWAVEFORMATEX pwfxSrc;
|
||||
PWAVEFORMATEX pwfxDst;
|
||||
PWAVEFILTER pwfltr;
|
||||
DWORD dwCallback;
|
||||
DWORD dwInstance;
|
||||
DWORD fdwOpen;
|
||||
DWORD fdwDriver;
|
||||
DWORD dwDriver;
|
||||
HACMSTREAM has;
|
||||
} ACMDRVSTREAMINSTANCE, *PACMDRVSTREAMINSTANCE;
|
||||
|
||||
typedef struct _ACMDRVSTREAMHEADER *PACMDRVSTREAMHEADER;
|
||||
typedef struct _ACMDRVSTREAMHEADER {
|
||||
DWORD cbStruct;
|
||||
DWORD fdwStatus;
|
||||
DWORD dwUser;
|
||||
LPBYTE pbSrc;
|
||||
DWORD cbSrcLength;
|
||||
DWORD cbSrcLengthUsed;
|
||||
DWORD dwSrcUser;
|
||||
LPBYTE pbDst;
|
||||
DWORD cbDstLength;
|
||||
DWORD cbDstLengthUsed;
|
||||
DWORD dwDstUser;
|
||||
|
||||
DWORD fdwConvert;
|
||||
PACMDRVSTREAMHEADER *padshNext;
|
||||
DWORD fdwDriver;
|
||||
DWORD dwDriver;
|
||||
|
||||
/* Internal fields for ACM */
|
||||
DWORD fdwPrepared;
|
||||
DWORD dwPrepared;
|
||||
LPBYTE pbPreparedSrc;
|
||||
DWORD cbPreparedSrcLength;
|
||||
LPBYTE pbPreparedDst;
|
||||
DWORD cbPreparedDstLength;
|
||||
} ACMDRVSTREAMHEADER;
|
||||
|
||||
typedef struct _ACMDRVSTREAMSIZE
|
||||
{
|
||||
DWORD cbStruct;
|
||||
DWORD fdwSize;
|
||||
DWORD cbSrcLength;
|
||||
DWORD cbDstLength;
|
||||
} ACMDRVSTREAMSIZE, *PACMDRVSTREAMSIZE;
|
||||
|
||||
typedef struct _ACMDRVFORMATSUGGEST
|
||||
{
|
||||
DWORD cbStruct;
|
||||
DWORD fdwSuggest;
|
||||
PWAVEFORMATEX pwfxSrc;
|
||||
DWORD cbwfxSrc;
|
||||
PWAVEFORMATEX pwfxDst;
|
||||
DWORD cbwfxDst;
|
||||
} ACMDRVFORMATSUGGEST, *PACMDRVFORMATSUGGEST;
|
||||
|
||||
#endif /* __WINE_MSACMDRV_H */
|
|
@ -118,6 +118,8 @@ static DWORD OpenMidiDevice(UINT DeviceType, DWORD ID, DWORD User, DWORD Param1,
|
|||
static DWORD WriteMidi(PBYTE pData, ULONG Length, PMIDIALLOC pClient)
|
||||
{
|
||||
DWORD BytesReturned;
|
||||
|
||||
printf("IOCTL_MIDI_PLAY == %d [%x]\n", IOCTL_MIDI_PLAY, IOCTL_MIDI_PLAY);
|
||||
|
||||
if ( !DeviceIoControl(pClient->DeviceHandle, IOCTL_MIDI_PLAY, (PVOID)pData,
|
||||
Length, NULL, 0, &BytesReturned, NULL))
|
||||
|
|
87
reactos/lib/mmdrv/mmdef.h
Normal file
87
reactos/lib/mmdrv/mmdef.h
Normal file
|
@ -0,0 +1,87 @@
|
|||
/*
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: lib/mmdrv/mmdef.h
|
||||
* PURPOSE: Multimedia Definitions (for mmdrv.dll)
|
||||
* PROGRAMMER: Andrew Greenwood
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __INCLUDES_MMDEF_H__
|
||||
#define __INCLUDES_MMDEF_H__
|
||||
|
||||
//#define UNICODE
|
||||
|
||||
#define EXPORT __declspec(dllexport)
|
||||
|
||||
|
||||
//#include <stdio.h>
|
||||
//#include <windows.h>
|
||||
//#include <mmsystem.h>
|
||||
//#include <mmddk.h>
|
||||
|
||||
// This needs to be done to get winioctl.h to work:
|
||||
//typedef unsigned __int64 DWORD64, *PDWORD64;
|
||||
|
||||
//#include <winioctl.h>
|
||||
//#include "mmddk.h"
|
||||
|
||||
|
||||
#define SOUND_MAX_DEVICE_NAME 1024 // GUESSWORK
|
||||
#define SOUND_MAX_DEVICES 256 // GUESSWORK
|
||||
|
||||
|
||||
// If the root is \Device and the Device type is
|
||||
// WaveIn and the device number is 2, the full name is \Device\WaveIn2
|
||||
|
||||
#define WAVE_IN_DEVICE_NAME "\\Device\\WaveIn"
|
||||
#define WAVE_IN_DEVICE_NAME_U L"\\Device\\WaveIn"
|
||||
#define WAVE_OUT_DEVICE_NAME "\\Device\\WaveOut"
|
||||
#define WAVE_OUT_DEVICE_NAME_U L"\\Device\\WaveOut"
|
||||
|
||||
#define MIDI_IN_DEVICE_NAME "\\Device\\MidiIn"
|
||||
#define MIDI_IN_DEVICE_NAME_U L"\\Device\\MidiIn"
|
||||
#define MIDI_OUT_DEVICE_NAME "\\Device\\MidiOut"
|
||||
#define MIDI_OUT_DEVICE_NAME_U L"\\Device\\MidiOut"
|
||||
|
||||
#define AUX_DEVICE_NAME "\\Device\\MMAux"
|
||||
#define AUX_DEVICE_NAME_U L"\\Device\\MMAux"
|
||||
|
||||
|
||||
#define IOCTL_SOUND_BASE FILE_DEVICE_SOUND
|
||||
#define IOCTL_WAVE_BASE 0x0000
|
||||
#define IOCTL_MIDI_BASE 0x0080
|
||||
|
||||
// Wave device driver IOCTLs
|
||||
|
||||
#define IOCTL_WAVE_QUERY_FORMAT CTL_CODE(IOCTL_SOUND_BASE, IOCTL_WAVE_BASE + 0x0001, METHOD_BUFFERED, FILE_READ_ACCESS)
|
||||
#define IOCTL_WAVE_SET_FORMAT CTL_CODE(IOCTL_SOUND_BASE, IOCTL_WAVE_BASE + 0x0002, METHOD_BUFFERED, FILE_WRITE_ACCESS)
|
||||
#define IOCTL_WAVE_GET_CAPABILITIES CTL_CODE(IOCTL_SOUND_BASE, IOCTL_WAVE_BASE + 0x0003, METHOD_BUFFERED, FILE_READ_ACCESS)
|
||||
#define IOCTL_WAVE_SET_STATE CTL_CODE(IOCTL_SOUND_BASE, IOCTL_WAVE_BASE + 0x0004, METHOD_BUFFERED, FILE_WRITE_ACCESS)
|
||||
#define IOCTL_WAVE_GET_STATE CTL_CODE(IOCTL_SOUND_BASE, IOCTL_WAVE_BASE + 0x0005, METHOD_BUFFERED, FILE_WRITE_ACCESS)
|
||||
#define IOCTL_WAVE_GET_POSITION CTL_CODE(IOCTL_SOUND_BASE, IOCTL_WAVE_BASE + 0x0006, METHOD_BUFFERED, FILE_WRITE_ACCESS)
|
||||
#define IOCTL_WAVE_SET_VOLUME CTL_CODE(IOCTL_SOUND_BASE, IOCTL_WAVE_BASE + 0x0007, METHOD_BUFFERED, FILE_READ_ACCESS)
|
||||
#define IOCTL_WAVE_GET_VOLUME CTL_CODE(IOCTL_SOUND_BASE, IOCTL_WAVE_BASE + 0x0008, METHOD_BUFFERED, FILE_READ_ACCESS)
|
||||
#define IOCTL_WAVE_SET_PITCH CTL_CODE(IOCTL_SOUND_BASE, IOCTL_WAVE_BASE + 0x0009, METHOD_BUFFERED, FILE_WRITE_ACCESS)
|
||||
#define IOCTL_WAVE_GET_PITCH CTL_CODE(IOCTL_SOUND_BASE, IOCTL_WAVE_BASE + 0x000A, METHOD_BUFFERED, FILE_WRITE_ACCESS)
|
||||
#define IOCTL_WAVE_SET_PLAYBACK_RATE CTL_CODE(IOCTL_SOUND_BASE, IOCTL_WAVE_BASE + 0x000B, METHOD_BUFFERED, FILE_WRITE_ACCESS)
|
||||
#define IOCTL_WAVE_GET_PLAYBACK_RATE CTL_CODE(IOCTL_SOUND_BASE, IOCTL_WAVE_BASE + 0x000C, METHOD_BUFFERED, FILE_WRITE_ACCESS)
|
||||
#define IOCTL_WAVE_PLAY CTL_CODE(IOCTL_SOUND_BASE, IOCTL_WAVE_BASE + 0x000D, METHOD_IN_DIRECT, FILE_WRITE_ACCESS)
|
||||
#define IOCTL_WAVE_RECORD CTL_CODE(IOCTL_SOUND_BASE, IOCTL_WAVE_BASE + 0x000E, METHOD_OUT_DIRECT, FILE_WRITE_ACCESS)
|
||||
#define IOCTL_WAVE_BREAK_LOOP CTL_CODE(IOCTL_SOUND_BASE, IOCTL_WAVE_BASE + 0x000F, METHOD_BUFFERED, FILE_WRITE_ACCESS)
|
||||
#define IOCTL_WAVE_SET_LOW_PRIORITY CTL_CODE(IOCTL_SOUND_BASE, IOCTL_WAVE_BASE + 0x0010, METHOD_BUFFERED, FILE_WRITE_ACCESS)
|
||||
|
||||
// MIDI device driver IOCTLs
|
||||
|
||||
#define IOCTL_MIDI_GET_CAPABILITIES CTL_CODE(IOCTL_SOUND_BASE, IOCTL_MIDI_BASE + 0x0001, METHOD_BUFFERED, FILE_READ_ACCESS)
|
||||
#define IOCTL_MIDI_SET_STATE CTL_CODE(IOCTL_SOUND_BASE, IOCTL_MIDI_BASE + 0x0002, METHOD_BUFFERED, FILE_WRITE_ACCESS)
|
||||
#define IOCTL_MIDI_GET_STATE CTL_CODE(IOCTL_SOUND_BASE, IOCTL_MIDI_BASE + 0x0003, METHOD_BUFFERED, FILE_WRITE_ACCESS)
|
||||
#define IOCTL_MIDI_SET_VOLUME CTL_CODE(IOCTL_SOUND_BASE, IOCTL_MIDI_BASE + 0x0004, METHOD_BUFFERED, FILE_READ_ACCESS)
|
||||
#define IOCTL_MIDI_GET_VOLUME CTL_CODE(IOCTL_SOUND_BASE, IOCTL_MIDI_BASE + 0x0005, METHOD_BUFFERED, FILE_READ_ACCESS)
|
||||
#define IOCTL_MIDI_PLAY CTL_CODE(IOCTL_SOUND_BASE, IOCTL_MIDI_BASE + 0x0006, METHOD_BUFFERED, FILE_WRITE_ACCESS)
|
||||
#define IOCTL_MIDI_RECORD CTL_CODE(IOCTL_SOUND_BASE, IOCTL_MIDI_BASE + 0x0007, METHOD_BUFFERED, FILE_WRITE_ACCESS)
|
||||
#define IOCTL_MIDI_CACHE_PATCHES CTL_CODE(IOCTL_SOUND_BASE, IOCTL_MIDI_BASE + 0x0008, METHOD_BUFFERED, FILE_WRITE_ACCESS)
|
||||
#define IOCTL_MIDI_CACHE_DRUM_PATCHES CTL_CODE(IOCTL_SOUND_BASE, IOCTL_MIDI_BASE + 0x0009, METHOD_BUFFERED, FILE_WRITE_ACCESS)
|
||||
|
||||
#endif
|
|
@ -23,15 +23,17 @@
|
|||
#include <mmddk.h>
|
||||
|
||||
// This needs to be done to get winioctl.h to work:
|
||||
typedef unsigned __int64 DWORD64, *PDWORD64;
|
||||
//typedef unsigned __int64 DWORD64, *PDWORD64;
|
||||
|
||||
#include <winioctl.h>
|
||||
//#include "mmddk.h"
|
||||
|
||||
#include "mmdef.h"
|
||||
|
||||
/*
|
||||
#define SOUND_MAX_DEVICE_NAME 1024 // GUESSWORK
|
||||
#define SOUND_MAX_DEVICES 256 // GUESSWORK
|
||||
|
||||
*/
|
||||
|
||||
// If the root is \Device and the Device type is
|
||||
// WaveIn and the device number is 2, the full name is \Device\WaveIn2
|
||||
|
@ -49,7 +51,7 @@ typedef unsigned __int64 DWORD64, *PDWORD64;
|
|||
#define AUX_DEVICE_NAME "\\Device\\MMAux"
|
||||
#define AUX_DEVICE_NAME_U L"\\Device\\MMAux"
|
||||
|
||||
|
||||
/*
|
||||
#define IOCTL_SOUND_BASE FILE_DEVICE_SOUND
|
||||
#define IOCTL_WAVE_BASE 0x0000
|
||||
#define IOCTL_MIDI_BASE 0x0080
|
||||
|
@ -80,11 +82,11 @@ typedef unsigned __int64 DWORD64, *PDWORD64;
|
|||
#define IOCTL_MIDI_GET_STATE CTL_CODE(IOCTL_SOUND_BASE, IOCTL_MIDI_BASE + 0x0003, METHOD_BUFFERED, FILE_WRITE_ACCESS)
|
||||
#define IOCTL_MIDI_SET_VOLUME CTL_CODE(IOCTL_SOUND_BASE, IOCTL_MIDI_BASE + 0x0004, METHOD_BUFFERED, FILE_READ_ACCESS)
|
||||
#define IOCTL_MIDI_GET_VOLUME CTL_CODE(IOCTL_SOUND_BASE, IOCTL_MIDI_BASE + 0x0005, METHOD_BUFFERED, FILE_READ_ACCESS)
|
||||
#define IOCTL_MIDI_PLAY CTL_CODE(IOCTL_SOUND_BASE, IOCTL_MIDI_BASE + 0x0006, METHOD_NEITHER, FILE_WRITE_ACCESS)
|
||||
#define IOCTL_MIDI_PLAY CTL_CODE(IOCTL_SOUND_BASE, IOCTL_MIDI_BASE + 0x0006, METHOD_BUFFERED, FILE_WRITE_ACCESS)
|
||||
#define IOCTL_MIDI_RECORD CTL_CODE(IOCTL_SOUND_BASE, IOCTL_MIDI_BASE + 0x0007, METHOD_BUFFERED, FILE_WRITE_ACCESS)
|
||||
#define IOCTL_MIDI_CACHE_PATCHES CTL_CODE(IOCTL_SOUND_BASE, IOCTL_MIDI_BASE + 0x0008, METHOD_BUFFERED, FILE_WRITE_ACCESS)
|
||||
#define IOCTL_MIDI_CACHE_DRUM_PATCHES CTL_CODE(IOCTL_SOUND_BASE, IOCTL_MIDI_BASE + 0x0009, METHOD_BUFFERED, FILE_WRITE_ACCESS)
|
||||
|
||||
*/
|
||||
|
||||
|
||||
CRITICAL_SECTION CS; // Serialize access to device lists
|
||||
|
|
|
@ -60,28 +60,42 @@ MMRESULT OpenDevice(UINT DeviceType, DWORD ID, PHANDLE pDeviceHandle,
|
|||
DWORD Access)
|
||||
{
|
||||
printf("OpenDevice()\n");
|
||||
WCHAR Name[SOUND_MAX_DEVICE_NAME];
|
||||
WCHAR DeviceName[SOUND_MAX_DEVICE_NAME];
|
||||
*pDeviceHandle = INVALID_HANDLE_VALUE;
|
||||
|
||||
if (ID > SOUND_MAX_DEVICES)
|
||||
return MMSYSERR_BADDEVICEID;
|
||||
|
||||
wsprintf(Name, L"\\\\.%ls%d",
|
||||
(DeviceType == WaveOutDevice ? WAVE_OUT_DEVICE_NAME_U :
|
||||
DeviceType == WaveInDevice ? WAVE_IN_DEVICE_NAME_U :
|
||||
DeviceType == MidiOutDevice ? MIDI_OUT_DEVICE_NAME_U :
|
||||
DeviceType == MidiInDevice ? MIDI_IN_DEVICE_NAME_U :
|
||||
AUX_DEVICE_NAME_U) + strlen("\\Device"), ID);
|
||||
|
||||
printf("Attempting to open %S\n", Name);
|
||||
switch(DeviceType)
|
||||
{
|
||||
case WaveOutDevice :
|
||||
wsprintf(DeviceName, L"\\\\.%ls%d", WAVE_OUT_DEVICE_NAME_U + strlen("\\Device"), ID);
|
||||
break;
|
||||
case WaveInDevice :
|
||||
wsprintf(DeviceName, L"\\\\.%ls%d", WAVE_IN_DEVICE_NAME_U + strlen("\\Device"), ID);
|
||||
break;
|
||||
case MidiOutDevice :
|
||||
wsprintf(DeviceName, L"\\\\.%ls%d", MIDI_OUT_DEVICE_NAME_U + strlen("\\Device"), ID);
|
||||
break;
|
||||
case MidiInDevice :
|
||||
wsprintf(DeviceName, L"\\\\.%ls%d", MIDI_IN_DEVICE_NAME_U + strlen("\\Device"), ID);
|
||||
break;
|
||||
default : // Aux
|
||||
wsprintf(DeviceName, L"\\\\.%ls%d", AUX_DEVICE_NAME_U + strlen("\\Device"), ID);
|
||||
};
|
||||
|
||||
*pDeviceHandle = CreateFile(Name, Access, FILE_SHARE_WRITE, NULL,
|
||||
printf("Attempting to open %S\n", DeviceName);
|
||||
|
||||
*pDeviceHandle = CreateFile(DeviceName, Access, FILE_SHARE_WRITE, NULL,
|
||||
OPEN_EXISTING, Access != GENERIC_READ ? FILE_FLAG_OVERLAPPED : 0,
|
||||
NULL);
|
||||
|
||||
printf("DeviceHandle == 0x%x\n", (int)*pDeviceHandle);
|
||||
|
||||
return *pDeviceHandle != INVALID_HANDLE_VALUE ? MMSYSERR_NOERROR : TranslateStatus();
|
||||
if (pDeviceHandle == INVALID_HANDLE_VALUE)
|
||||
return TranslateStatus();
|
||||
|
||||
return MMSYSERR_NOERROR;
|
||||
}
|
||||
|
||||
|
||||
|
|
9
reactos/lib/msacm/.cvsignore
Normal file
9
reactos/lib/msacm/.cvsignore
Normal file
|
@ -0,0 +1,9 @@
|
|||
*.a
|
||||
*.d
|
||||
*.o
|
||||
*.dll
|
||||
*.coff
|
||||
*.sym
|
||||
*.map
|
||||
*.tmp
|
||||
temp.exp
|
27
reactos/lib/msacm/Makefile.in
Normal file
27
reactos/lib/msacm/Makefile.in
Normal file
|
@ -0,0 +1,27 @@
|
|||
TOPSRCDIR = @top_srcdir@
|
||||
TOPOBJDIR = ../..
|
||||
SRCDIR = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
MODULE = msacm32.dll
|
||||
IMPORTS = winmm user32 advapi32 kernel32
|
||||
ALTNAMES = msacm.dll
|
||||
|
||||
SPEC_SRCS16 = $(ALTNAMES:.dll=.spec)
|
||||
|
||||
C_SRCS = \
|
||||
driver.c \
|
||||
filter.c \
|
||||
format.c \
|
||||
internal.c \
|
||||
msacm32_main.c \
|
||||
pcmconverter.c \
|
||||
stream.c
|
||||
|
||||
C_SRCS16 = \
|
||||
msacm_main.c
|
||||
|
||||
RC_SRCS = msacm.rc
|
||||
|
||||
@MAKE_DLL_RULES@
|
||||
|
||||
### Dependencies:
|
21
reactos/lib/msacm/Makefile.ros
Normal file
21
reactos/lib/msacm/Makefile.ros
Normal file
|
@ -0,0 +1,21 @@
|
|||
# $Id: Makefile.ros,v 1.1 2004/03/10 15:22:44 silverblade Exp $
|
||||
|
||||
TARGET_NAME = msacm32
|
||||
|
||||
TARGET_OBJECTS = driver.o filter.o format.o internal.o msacm32_main.o pcmconverter.o stream.o
|
||||
|
||||
TARGET_CFLAGS = -D__REACTOS__
|
||||
|
||||
TARGET_SDKLIBS = winmm.a libwine.a advapi32.a kernel32.a ws2_32.a wine_uuid.a ntdll.a
|
||||
|
||||
TARGET_BASE = 0x77300000
|
||||
|
||||
TARGET_RC_SRCS = msacm.rc
|
||||
TARGET_RC_BINSRC = msacm.rc
|
||||
TARGET_RC_BINARIES =
|
||||
|
||||
default: all
|
||||
|
||||
DEP_OBJECTS = $(TARGET_OBJECTS)
|
||||
|
||||
include $(TOOLS_PATH)/depend.mk
|
21
reactos/lib/msacm/Makefile.ros-template
Normal file
21
reactos/lib/msacm/Makefile.ros-template
Normal file
|
@ -0,0 +1,21 @@
|
|||
# $Id: Makefile.ros-template,v 1.1 2004/03/10 15:22:44 silverblade Exp $
|
||||
|
||||
TARGET_NAME = iphlpapi
|
||||
|
||||
TARGET_OBJECTS = @C_SRCS@
|
||||
|
||||
TARGET_CFLAGS = @EXTRADEFS@ -D__REACTOS__
|
||||
|
||||
TARGET_SDKLIBS = @IMPORTS@ libwine.a advapi32.a kernel32.a ws2_32.a wine_uuid.a ntdll.a
|
||||
|
||||
TARGET_BASE = 0x77300000
|
||||
|
||||
TARGET_RC_SRCS = @RC_SRCS@
|
||||
TARGET_RC_BINSRC = @RC_BINSRC@
|
||||
TARGET_RC_BINARIES = @RC_BINARIES@
|
||||
|
||||
default: all
|
||||
|
||||
DEP_OBJECTS = $(TARGET_OBJECTS)
|
||||
|
||||
include $(TOOLS_PATH)/depend.mk
|
400
reactos/lib/msacm/driver.c
Normal file
400
reactos/lib/msacm/driver.c
Normal file
|
@ -0,0 +1,400 @@
|
|||
/* -*- tab-width: 8; c-basic-offset: 4 -*- */
|
||||
|
||||
/*
|
||||
* MSACM32 library
|
||||
*
|
||||
* Copyright 1998 Patrik Stridvall
|
||||
* 1999 Eric Pouech
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "wine/port.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "winerror.h"
|
||||
#include "wingdi.h"
|
||||
#include "winuser.h"
|
||||
#include "winnls.h"
|
||||
#include "winreg.h"
|
||||
#include "mmsystem.h"
|
||||
#include "mmreg.h"
|
||||
#include "msacm.h"
|
||||
#include "msacmdrv.h"
|
||||
#include "wineacm.h"
|
||||
#include "wine/debug.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(msacm);
|
||||
|
||||
/***********************************************************************
|
||||
* acmDriverAddA (MSACM32.@)
|
||||
*/
|
||||
MMRESULT WINAPI acmDriverAddA(PHACMDRIVERID phadid, HINSTANCE hinstModule,
|
||||
LPARAM lParam, DWORD dwPriority, DWORD fdwAdd)
|
||||
{
|
||||
if (!phadid)
|
||||
return MMSYSERR_INVALPARAM;
|
||||
|
||||
/* Check if any unknown flags */
|
||||
if (fdwAdd &
|
||||
~(ACM_DRIVERADDF_FUNCTION|ACM_DRIVERADDF_NOTIFYHWND|
|
||||
ACM_DRIVERADDF_GLOBAL))
|
||||
return MMSYSERR_INVALFLAG;
|
||||
|
||||
/* Check if any incompatible flags */
|
||||
if ((fdwAdd & ACM_DRIVERADDF_FUNCTION) &&
|
||||
(fdwAdd & ACM_DRIVERADDF_NOTIFYHWND))
|
||||
return MMSYSERR_INVALFLAG;
|
||||
|
||||
/* FIXME: in fact, should GetModuleFileName(hinstModule) and do a
|
||||
* LoadDriver on it, to be sure we can call SendDriverMessage on the
|
||||
* hDrvr handle.
|
||||
*/
|
||||
*phadid = (HACMDRIVERID) MSACM_RegisterDriver(NULL, NULL, hinstModule);
|
||||
|
||||
/* FIXME: lParam, dwPriority and fdwAdd ignored */
|
||||
|
||||
return MMSYSERR_NOERROR;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* acmDriverAddW (MSACM32.@)
|
||||
* FIXME
|
||||
* Not implemented
|
||||
*/
|
||||
MMRESULT WINAPI acmDriverAddW(PHACMDRIVERID phadid, HINSTANCE hinstModule,
|
||||
LPARAM lParam, DWORD dwPriority, DWORD fdwAdd)
|
||||
{
|
||||
FIXME("(%p, %p, %ld, %ld, %ld): stub\n",
|
||||
phadid, hinstModule, lParam, dwPriority, fdwAdd);
|
||||
|
||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
return MMSYSERR_ERROR;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* acmDriverClose (MSACM32.@)
|
||||
*/
|
||||
MMRESULT WINAPI acmDriverClose(HACMDRIVER had, DWORD fdwClose)
|
||||
{
|
||||
PWINE_ACMDRIVER pad;
|
||||
PWINE_ACMDRIVERID padid;
|
||||
PWINE_ACMDRIVER* tpad;
|
||||
|
||||
if (fdwClose)
|
||||
return MMSYSERR_INVALFLAG;
|
||||
|
||||
pad = MSACM_GetDriver(had);
|
||||
if (!pad)
|
||||
return MMSYSERR_INVALHANDLE;
|
||||
|
||||
padid = pad->obj.pACMDriverID;
|
||||
|
||||
/* remove driver from list */
|
||||
for (tpad = &(padid->pACMDriverList); *tpad; *tpad = (*tpad)->pNextACMDriver) {
|
||||
if (*tpad == pad) {
|
||||
*tpad = (*tpad)->pNextACMDriver;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* close driver if it has been opened */
|
||||
if (pad->hDrvr && !padid->hInstModule)
|
||||
CloseDriver(pad->hDrvr, 0, 0);
|
||||
|
||||
HeapFree(MSACM_hHeap, 0, pad);
|
||||
|
||||
return MMSYSERR_NOERROR;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* acmDriverDetailsA (MSACM32.@)
|
||||
*/
|
||||
MMRESULT WINAPI acmDriverDetailsA(HACMDRIVERID hadid, PACMDRIVERDETAILSA padd, DWORD fdwDetails)
|
||||
{
|
||||
MMRESULT mmr;
|
||||
ACMDRIVERDETAILSW addw;
|
||||
|
||||
addw.cbStruct = sizeof(addw);
|
||||
mmr = acmDriverDetailsW(hadid, &addw, fdwDetails);
|
||||
if (mmr == 0) {
|
||||
padd->fccType = addw.fccType;
|
||||
padd->fccComp = addw.fccComp;
|
||||
padd->wMid = addw.wMid;
|
||||
padd->wPid = addw.wPid;
|
||||
padd->vdwACM = addw.vdwACM;
|
||||
padd->vdwDriver = addw.vdwDriver;
|
||||
padd->fdwSupport = addw.fdwSupport;
|
||||
padd->cFormatTags = addw.cFormatTags;
|
||||
padd->cFilterTags = addw.cFilterTags;
|
||||
padd->hicon = addw.hicon;
|
||||
WideCharToMultiByte( CP_ACP, 0, addw.szShortName, -1, padd->szShortName,
|
||||
sizeof(padd->szShortName), NULL, NULL );
|
||||
WideCharToMultiByte( CP_ACP, 0, addw.szLongName, -1, padd->szLongName,
|
||||
sizeof(padd->szLongName), NULL, NULL );
|
||||
WideCharToMultiByte( CP_ACP, 0, addw.szCopyright, -1, padd->szCopyright,
|
||||
sizeof(padd->szCopyright), NULL, NULL );
|
||||
WideCharToMultiByte( CP_ACP, 0, addw.szLicensing, -1, padd->szLicensing,
|
||||
sizeof(padd->szLicensing), NULL, NULL );
|
||||
WideCharToMultiByte( CP_ACP, 0, addw.szFeatures, -1, padd->szFeatures,
|
||||
sizeof(padd->szFeatures), NULL, NULL );
|
||||
}
|
||||
return mmr;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* acmDriverDetailsW (MSACM32.@)
|
||||
*/
|
||||
MMRESULT WINAPI acmDriverDetailsW(HACMDRIVERID hadid, PACMDRIVERDETAILSW padd, DWORD fdwDetails)
|
||||
{
|
||||
HACMDRIVER acmDrvr;
|
||||
MMRESULT mmr;
|
||||
|
||||
if (fdwDetails)
|
||||
return MMSYSERR_INVALFLAG;
|
||||
|
||||
mmr = acmDriverOpen(&acmDrvr, hadid, 0);
|
||||
if (mmr == MMSYSERR_NOERROR) {
|
||||
mmr = (MMRESULT)MSACM_Message(acmDrvr, ACMDM_DRIVER_DETAILS, (LPARAM)padd, 0);
|
||||
|
||||
acmDriverClose(acmDrvr, 0);
|
||||
}
|
||||
|
||||
return mmr;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* acmDriverEnum (MSACM32.@)
|
||||
*/
|
||||
MMRESULT WINAPI acmDriverEnum(ACMDRIVERENUMCB fnCallback, DWORD dwInstance, DWORD fdwEnum)
|
||||
{
|
||||
PWINE_ACMDRIVERID padid;
|
||||
DWORD fdwSupport;
|
||||
|
||||
if (!fnCallback) return MMSYSERR_INVALPARAM;
|
||||
|
||||
if (fdwEnum & ~(ACM_DRIVERENUMF_NOLOCAL|ACM_DRIVERENUMF_DISABLED))
|
||||
return MMSYSERR_INVALFLAG;
|
||||
|
||||
for (padid = MSACM_pFirstACMDriverID; padid; padid = padid->pNextACMDriverID) {
|
||||
fdwSupport = padid->fdwSupport;
|
||||
|
||||
if (padid->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_DISABLED) {
|
||||
if (fdwEnum & ACM_DRIVERENUMF_DISABLED)
|
||||
fdwSupport |= ACMDRIVERDETAILS_SUPPORTF_DISABLED;
|
||||
else
|
||||
continue;
|
||||
}
|
||||
if (!(*fnCallback)((HACMDRIVERID)padid, dwInstance, fdwSupport))
|
||||
break;
|
||||
}
|
||||
|
||||
return MMSYSERR_NOERROR;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* acmDriverID (MSACM32.@)
|
||||
*/
|
||||
MMRESULT WINAPI acmDriverID(HACMOBJ hao, PHACMDRIVERID phadid, DWORD fdwDriverID)
|
||||
{
|
||||
PWINE_ACMOBJ pao;
|
||||
|
||||
if (!phadid)
|
||||
return MMSYSERR_INVALPARAM;
|
||||
|
||||
if (fdwDriverID)
|
||||
return MMSYSERR_INVALFLAG;
|
||||
|
||||
pao = MSACM_GetObj(hao, WINE_ACMOBJ_DONTCARE);
|
||||
if (!pao)
|
||||
return MMSYSERR_INVALHANDLE;
|
||||
|
||||
*phadid = (HACMDRIVERID) pao->pACMDriverID;
|
||||
|
||||
return MMSYSERR_NOERROR;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* acmDriverMessage (MSACM32.@)
|
||||
*
|
||||
*/
|
||||
LRESULT WINAPI acmDriverMessage(HACMDRIVER had, UINT uMsg, LPARAM lParam1, LPARAM lParam2)
|
||||
{
|
||||
if ((uMsg >= ACMDM_USER && uMsg < ACMDM_RESERVED_LOW) ||
|
||||
uMsg == ACMDM_DRIVER_ABOUT ||
|
||||
uMsg == DRV_QUERYCONFIGURE ||
|
||||
uMsg == DRV_CONFIGURE)
|
||||
return MSACM_Message(had, uMsg, lParam1, lParam2);
|
||||
return MMSYSERR_INVALPARAM;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* acmDriverOpen (MSACM32.@)
|
||||
*/
|
||||
MMRESULT WINAPI acmDriverOpen(PHACMDRIVER phad, HACMDRIVERID hadid, DWORD fdwOpen)
|
||||
{
|
||||
PWINE_ACMDRIVERID padid;
|
||||
PWINE_ACMDRIVER pad = NULL;
|
||||
MMRESULT ret;
|
||||
|
||||
TRACE("(%p, %p, %08lu)\n", phad, hadid, fdwOpen);
|
||||
|
||||
if (!phad)
|
||||
return MMSYSERR_INVALPARAM;
|
||||
|
||||
if (fdwOpen)
|
||||
return MMSYSERR_INVALFLAG;
|
||||
|
||||
padid = MSACM_GetDriverID(hadid);
|
||||
if (!padid)
|
||||
return MMSYSERR_INVALHANDLE;
|
||||
|
||||
pad = HeapAlloc(MSACM_hHeap, 0, sizeof(WINE_ACMDRIVER));
|
||||
if (!pad)
|
||||
return MMSYSERR_NOMEM;
|
||||
|
||||
pad->obj.dwType = WINE_ACMOBJ_DRIVER;
|
||||
pad->obj.pACMDriverID = padid;
|
||||
|
||||
if (!(pad->hDrvr = (HDRVR)padid->hInstModule))
|
||||
{
|
||||
ACMDRVOPENDESCW adod;
|
||||
int len;
|
||||
|
||||
/* this is not an externally added driver... need to actually load it */
|
||||
if (!padid->pszDriverAlias)
|
||||
{
|
||||
ret = MMSYSERR_ERROR;
|
||||
goto gotError;
|
||||
}
|
||||
|
||||
adod.cbStruct = sizeof(adod);
|
||||
adod.fccType = ACMDRIVERDETAILS_FCCTYPE_AUDIOCODEC;
|
||||
adod.fccComp = ACMDRIVERDETAILS_FCCCOMP_UNDEFINED;
|
||||
adod.dwVersion = acmGetVersion();
|
||||
adod.dwFlags = fdwOpen;
|
||||
adod.dwError = 0;
|
||||
len = strlen("Drivers32") + 1;
|
||||
adod.pszSectionName = HeapAlloc(MSACM_hHeap, 0, len * sizeof(WCHAR));
|
||||
MultiByteToWideChar(CP_ACP, 0, "Drivers32", -1, (LPWSTR)adod.pszSectionName, len);
|
||||
adod.pszAliasName = padid->pszDriverAlias;
|
||||
adod.dnDevNode = 0;
|
||||
|
||||
pad->hDrvr = OpenDriver(padid->pszDriverAlias, NULL, (DWORD)&adod);
|
||||
|
||||
HeapFree(MSACM_hHeap, 0, (LPWSTR)adod.pszSectionName);
|
||||
if (!pad->hDrvr)
|
||||
{
|
||||
ret = adod.dwError;
|
||||
goto gotError;
|
||||
}
|
||||
}
|
||||
|
||||
/* insert new pad at beg of list */
|
||||
pad->pNextACMDriver = padid->pACMDriverList;
|
||||
padid->pACMDriverList = pad;
|
||||
|
||||
/* FIXME: Create a WINE_ACMDRIVER32 */
|
||||
*phad = (HACMDRIVER)pad;
|
||||
TRACE("'%s' => %08lx\n", debugstr_w(padid->pszDriverAlias), (DWORD)pad);
|
||||
|
||||
return MMSYSERR_NOERROR;
|
||||
gotError:
|
||||
if (pad && !pad->hDrvr)
|
||||
HeapFree(MSACM_hHeap, 0, pad);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* acmDriverPriority (MSACM32.@)
|
||||
*/
|
||||
MMRESULT WINAPI acmDriverPriority(HACMDRIVERID hadid, DWORD dwPriority, DWORD fdwPriority)
|
||||
{
|
||||
PWINE_ACMDRIVERID padid;
|
||||
CHAR szSubKey[17];
|
||||
CHAR szBuffer[256];
|
||||
LONG lBufferLength = sizeof(szBuffer);
|
||||
LONG lError;
|
||||
HKEY hPriorityKey;
|
||||
DWORD dwPriorityCounter;
|
||||
|
||||
padid = MSACM_GetDriverID(hadid);
|
||||
if (!padid)
|
||||
return MMSYSERR_INVALHANDLE;
|
||||
|
||||
/* Check for unknown flags */
|
||||
if (fdwPriority &
|
||||
~(ACM_DRIVERPRIORITYF_ENABLE|ACM_DRIVERPRIORITYF_DISABLE|
|
||||
ACM_DRIVERPRIORITYF_BEGIN|ACM_DRIVERPRIORITYF_END))
|
||||
return MMSYSERR_INVALFLAG;
|
||||
|
||||
/* Check for incompatible flags */
|
||||
if ((fdwPriority & ACM_DRIVERPRIORITYF_ENABLE) &&
|
||||
(fdwPriority & ACM_DRIVERPRIORITYF_DISABLE))
|
||||
return MMSYSERR_INVALFLAG;
|
||||
|
||||
/* Check for incompatible flags */
|
||||
if ((fdwPriority & ACM_DRIVERPRIORITYF_BEGIN) &&
|
||||
(fdwPriority & ACM_DRIVERPRIORITYF_END))
|
||||
return MMSYSERR_INVALFLAG;
|
||||
|
||||
lError = RegOpenKeyA(HKEY_CURRENT_USER,
|
||||
"Software\\Microsoft\\Multimedia\\"
|
||||
"Audio Compression Manager\\Priority v4.00",
|
||||
&hPriorityKey
|
||||
);
|
||||
/* FIXME: Create key */
|
||||
if (lError != ERROR_SUCCESS)
|
||||
return MMSYSERR_ERROR;
|
||||
|
||||
for (dwPriorityCounter = 1; ; dwPriorityCounter++) {
|
||||
snprintf(szSubKey, 17, "Priority%ld", dwPriorityCounter);
|
||||
lError = RegQueryValueA(hPriorityKey, szSubKey, szBuffer, &lBufferLength);
|
||||
if (lError != ERROR_SUCCESS)
|
||||
break;
|
||||
|
||||
FIXME("(%p, %ld, %ld): stub (partial)\n",
|
||||
hadid, dwPriority, fdwPriority);
|
||||
break;
|
||||
}
|
||||
|
||||
RegCloseKey(hPriorityKey);
|
||||
|
||||
return MMSYSERR_ERROR;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* acmDriverRemove (MSACM32.@)
|
||||
*/
|
||||
MMRESULT WINAPI acmDriverRemove(HACMDRIVERID hadid, DWORD fdwRemove)
|
||||
{
|
||||
PWINE_ACMDRIVERID padid;
|
||||
|
||||
padid = MSACM_GetDriverID(hadid);
|
||||
if (!padid)
|
||||
return MMSYSERR_INVALHANDLE;
|
||||
|
||||
if (fdwRemove)
|
||||
return MMSYSERR_INVALFLAG;
|
||||
|
||||
MSACM_UnregisterDriver(padid);
|
||||
|
||||
return MMSYSERR_NOERROR;
|
||||
}
|
454
reactos/lib/msacm/filter.c
Normal file
454
reactos/lib/msacm/filter.c
Normal file
|
@ -0,0 +1,454 @@
|
|||
/* -*- tab-width: 8; c-basic-offset: 4 -*- */
|
||||
|
||||
/*
|
||||
* MSACM32 library
|
||||
*
|
||||
* Copyright 1998 Patrik Stridvall
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "winnls.h"
|
||||
#include "winerror.h"
|
||||
#include "mmsystem.h"
|
||||
#include "mmreg.h"
|
||||
#include "msacm.h"
|
||||
#include "msacmdrv.h"
|
||||
#include "wineacm.h"
|
||||
#include "wine/debug.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(msacm);
|
||||
|
||||
/***********************************************************************
|
||||
* acmFilterChooseA (MSACM32.@)
|
||||
*/
|
||||
MMRESULT WINAPI acmFilterChooseA(PACMFILTERCHOOSEA pafltrc)
|
||||
{
|
||||
FIXME("(%p): stub\n", pafltrc);
|
||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
return MMSYSERR_ERROR;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* acmFilterChooseW (MSACM32.@)
|
||||
*/
|
||||
MMRESULT WINAPI acmFilterChooseW(PACMFILTERCHOOSEW pafltrc)
|
||||
{
|
||||
FIXME("(%p): stub\n", pafltrc);
|
||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
return MMSYSERR_ERROR;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* acmFilterDetailsA (MSACM32.@)
|
||||
*/
|
||||
MMRESULT WINAPI acmFilterDetailsA(HACMDRIVER had, PACMFILTERDETAILSA pafd,
|
||||
DWORD fdwDetails)
|
||||
{
|
||||
ACMFILTERDETAILSW afdw;
|
||||
MMRESULT mmr;
|
||||
|
||||
memset(&afdw, 0, sizeof(afdw));
|
||||
afdw.cbStruct = sizeof(afdw);
|
||||
afdw.dwFilterIndex = pafd->dwFilterIndex;
|
||||
afdw.dwFilterTag = pafd->dwFilterTag;
|
||||
afdw.pwfltr = pafd->pwfltr;
|
||||
afdw.cbwfltr = pafd->cbwfltr;
|
||||
|
||||
mmr = acmFilterDetailsW(had, &afdw, fdwDetails);
|
||||
if (mmr == MMSYSERR_NOERROR) {
|
||||
pafd->dwFilterTag = afdw.dwFilterTag;
|
||||
pafd->fdwSupport = afdw.fdwSupport;
|
||||
WideCharToMultiByte( CP_ACP, 0, afdw.szFilter, -1, pafd->szFilter,
|
||||
sizeof(pafd->szFilter), NULL, NULL );
|
||||
}
|
||||
return mmr;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* acmFilterDetailsW (MSACM32.@)
|
||||
*/
|
||||
MMRESULT WINAPI acmFilterDetailsW(HACMDRIVER had, PACMFILTERDETAILSW pafd,
|
||||
DWORD fdwDetails)
|
||||
{
|
||||
MMRESULT mmr;
|
||||
ACMFILTERTAGDETAILSA aftd;
|
||||
|
||||
TRACE("(%p, %p, %ld)\n", had, pafd, fdwDetails);
|
||||
|
||||
memset(&aftd, 0, sizeof(aftd));
|
||||
aftd.cbStruct = sizeof(aftd);
|
||||
|
||||
if (pafd->cbStruct < sizeof(*pafd)) return MMSYSERR_INVALPARAM;
|
||||
|
||||
switch (fdwDetails) {
|
||||
case ACM_FILTERDETAILSF_FILTER:
|
||||
if (pafd->dwFilterTag != pafd->pwfltr->dwFilterTag) {
|
||||
mmr = MMSYSERR_INVALPARAM;
|
||||
break;
|
||||
}
|
||||
if (had == NULL) {
|
||||
PWINE_ACMDRIVERID padid;
|
||||
|
||||
mmr = ACMERR_NOTPOSSIBLE;
|
||||
for (padid = MSACM_pFirstACMDriverID; padid; padid = padid->pNextACMDriverID) {
|
||||
/* should check for codec only */
|
||||
if (!(padid->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_DISABLED) &&
|
||||
acmDriverOpen(&had, (HACMDRIVERID)padid, 0) == 0) {
|
||||
mmr = MSACM_Message(had, ACMDM_FILTER_DETAILS,
|
||||
(LPARAM)pafd, (LPARAM)fdwDetails);
|
||||
acmDriverClose(had, 0);
|
||||
if (mmr == MMSYSERR_NOERROR) break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
mmr = MSACM_Message(had, ACMDM_FILTER_DETAILS, (LPARAM)pafd, fdwDetails);
|
||||
}
|
||||
break;
|
||||
case ACM_FILTERDETAILSF_INDEX:
|
||||
/* should check pafd->dwFilterIndex < aftd->cStandardFilters */
|
||||
mmr = MSACM_Message(had, ACMDM_FILTER_DETAILS, (LPARAM)pafd, fdwDetails);
|
||||
break;
|
||||
default:
|
||||
WARN("Unknown fdwDetails %08lx\n", fdwDetails);
|
||||
mmr = MMSYSERR_INVALFLAG;
|
||||
break;
|
||||
}
|
||||
|
||||
TRACE("=> %d\n", mmr);
|
||||
return mmr;
|
||||
}
|
||||
|
||||
struct MSACM_FilterEnumWtoA_Instance {
|
||||
PACMFILTERDETAILSA pafda;
|
||||
DWORD dwInstance;
|
||||
ACMFILTERENUMCBA fnCallback;
|
||||
};
|
||||
|
||||
static BOOL CALLBACK MSACM_FilterEnumCallbackWtoA(HACMDRIVERID hadid,
|
||||
PACMFILTERDETAILSW pafdw,
|
||||
DWORD dwInstance,
|
||||
DWORD fdwSupport)
|
||||
{
|
||||
struct MSACM_FilterEnumWtoA_Instance* pafei;
|
||||
|
||||
pafei = (struct MSACM_FilterEnumWtoA_Instance*)dwInstance;
|
||||
|
||||
pafei->pafda->dwFilterIndex = pafdw->dwFilterIndex;
|
||||
pafei->pafda->dwFilterTag = pafdw->dwFilterTag;
|
||||
pafei->pafda->fdwSupport = pafdw->fdwSupport;
|
||||
WideCharToMultiByte( CP_ACP, 0, pafdw->szFilter, -1, pafei->pafda->szFilter,
|
||||
sizeof(pafei->pafda->szFilter), NULL, NULL );
|
||||
|
||||
return (pafei->fnCallback)(hadid, pafei->pafda,
|
||||
pafei->dwInstance, fdwSupport);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* acmFilterEnumA (MSACM32.@)
|
||||
*/
|
||||
MMRESULT WINAPI acmFilterEnumA(HACMDRIVER had, PACMFILTERDETAILSA pafda,
|
||||
ACMFILTERENUMCBA fnCallback, DWORD dwInstance,
|
||||
DWORD fdwEnum)
|
||||
{
|
||||
ACMFILTERDETAILSW afdw;
|
||||
struct MSACM_FilterEnumWtoA_Instance afei;
|
||||
|
||||
memset(&afdw, 0, sizeof(afdw));
|
||||
afdw.cbStruct = sizeof(afdw);
|
||||
afdw.dwFilterIndex = pafda->dwFilterIndex;
|
||||
afdw.dwFilterTag = pafda->dwFilterTag;
|
||||
afdw.pwfltr = pafda->pwfltr;
|
||||
afdw.cbwfltr = pafda->cbwfltr;
|
||||
|
||||
afei.pafda = pafda;
|
||||
afei.dwInstance = dwInstance;
|
||||
afei.fnCallback = fnCallback;
|
||||
|
||||
return acmFilterEnumW(had, &afdw, MSACM_FilterEnumCallbackWtoA,
|
||||
(DWORD)&afei, fdwEnum);
|
||||
}
|
||||
|
||||
static BOOL MSACM_FilterEnumHelper(PWINE_ACMDRIVERID padid, HACMDRIVER had,
|
||||
PACMFILTERDETAILSW pafd,
|
||||
ACMFILTERENUMCBW fnCallback, DWORD dwInstance,
|
||||
DWORD fdwEnum)
|
||||
{
|
||||
ACMFILTERTAGDETAILSW aftd;
|
||||
int i, j;
|
||||
|
||||
for (i = 0; i < padid->cFilterTags; i++) {
|
||||
memset(&aftd, 0, sizeof(aftd));
|
||||
aftd.cbStruct = sizeof(aftd);
|
||||
aftd.dwFilterTagIndex = i;
|
||||
if (acmFilterTagDetailsW(had, &aftd, ACM_FILTERTAGDETAILSF_INDEX) != MMSYSERR_NOERROR)
|
||||
continue;
|
||||
|
||||
if ((fdwEnum & ACM_FILTERENUMF_DWFILTERTAG) &&
|
||||
aftd.dwFilterTag != pafd->pwfltr->dwFilterTag)
|
||||
continue;
|
||||
|
||||
for (j = 0; j < aftd.cStandardFilters; j++) {
|
||||
pafd->dwFilterIndex = j;
|
||||
pafd->dwFilterTag = aftd.dwFilterTag;
|
||||
if (acmFilterDetailsW(had, pafd, ACM_FILTERDETAILSF_INDEX) != MMSYSERR_NOERROR)
|
||||
continue;
|
||||
|
||||
if (!(fnCallback)((HACMDRIVERID)padid, pafd, dwInstance, padid->fdwSupport))
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* acmFilterEnumW (MSACM32.@)
|
||||
*/
|
||||
MMRESULT WINAPI acmFilterEnumW(HACMDRIVER had, PACMFILTERDETAILSW pafd,
|
||||
ACMFILTERENUMCBW fnCallback, DWORD dwInstance,
|
||||
DWORD fdwEnum)
|
||||
{
|
||||
PWINE_ACMDRIVERID padid;
|
||||
BOOL ret;
|
||||
|
||||
TRACE("(%p, %p, %p, %ld, %ld)\n",
|
||||
had, pafd, fnCallback, dwInstance, fdwEnum);
|
||||
|
||||
if (pafd->cbStruct < sizeof(*pafd)) return MMSYSERR_INVALPARAM;
|
||||
|
||||
if (fdwEnum & ~(ACM_FILTERENUMF_DWFILTERTAG))
|
||||
FIXME("Unsupported fdwEnum values\n");
|
||||
|
||||
if (had) {
|
||||
HACMDRIVERID hadid;
|
||||
|
||||
if (acmDriverID((HACMOBJ)had, &hadid, 0) != MMSYSERR_NOERROR)
|
||||
return MMSYSERR_INVALHANDLE;
|
||||
MSACM_FilterEnumHelper(MSACM_GetDriverID(hadid), had, pafd,
|
||||
fnCallback, dwInstance, fdwEnum);
|
||||
return MMSYSERR_NOERROR;
|
||||
}
|
||||
for (padid = MSACM_pFirstACMDriverID; padid; padid = padid->pNextACMDriverID) {
|
||||
/* should check for codec only */
|
||||
if ((padid->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_DISABLED) ||
|
||||
acmDriverOpen(&had, (HACMDRIVERID)padid, 0) != MMSYSERR_NOERROR)
|
||||
continue;
|
||||
ret = MSACM_FilterEnumHelper(padid, had, pafd,
|
||||
fnCallback, dwInstance, fdwEnum);
|
||||
acmDriverClose(had, 0);
|
||||
if (!ret) break;
|
||||
}
|
||||
return MMSYSERR_NOERROR;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* acmFilterTagDetailsA (MSACM32.@)
|
||||
*/
|
||||
MMRESULT WINAPI acmFilterTagDetailsA(HACMDRIVER had, PACMFILTERTAGDETAILSA paftda,
|
||||
DWORD fdwDetails)
|
||||
{
|
||||
ACMFILTERTAGDETAILSW aftdw;
|
||||
MMRESULT mmr;
|
||||
|
||||
memset(&aftdw, 0, sizeof(aftdw));
|
||||
aftdw.cbStruct = sizeof(aftdw);
|
||||
aftdw.dwFilterTagIndex = paftda->dwFilterTagIndex;
|
||||
aftdw.dwFilterTag = paftda->dwFilterTag;
|
||||
|
||||
mmr = acmFilterTagDetailsW(had, &aftdw, fdwDetails);
|
||||
if (mmr == MMSYSERR_NOERROR) {
|
||||
paftda->dwFilterTag = aftdw.dwFilterTag;
|
||||
paftda->dwFilterTagIndex = aftdw.dwFilterTagIndex;
|
||||
paftda->cbFilterSize = aftdw.cbFilterSize;
|
||||
paftda->fdwSupport = aftdw.fdwSupport;
|
||||
paftda->cStandardFilters = aftdw.cStandardFilters;
|
||||
WideCharToMultiByte( CP_ACP, 0, aftdw.szFilterTag, -1, paftda->szFilterTag,
|
||||
sizeof(paftda->szFilterTag), NULL, NULL );
|
||||
}
|
||||
return mmr;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* acmFilterTagDetailsW (MSACM32.@)
|
||||
*/
|
||||
MMRESULT WINAPI acmFilterTagDetailsW(HACMDRIVER had, PACMFILTERTAGDETAILSW paftd,
|
||||
DWORD fdwDetails)
|
||||
{
|
||||
PWINE_ACMDRIVERID padid;
|
||||
MMRESULT mmr;
|
||||
|
||||
TRACE("(%p, %p, %ld)\n", had, paftd, fdwDetails);
|
||||
|
||||
if (fdwDetails & ~(ACM_FILTERTAGDETAILSF_FILTERTAG|ACM_FILTERTAGDETAILSF_INDEX|
|
||||
ACM_FILTERTAGDETAILSF_LARGESTSIZE))
|
||||
return MMSYSERR_INVALFLAG;
|
||||
|
||||
switch (fdwDetails) {
|
||||
case ACM_FILTERTAGDETAILSF_FILTERTAG:
|
||||
if (had == NULL) {
|
||||
mmr = ACMERR_NOTPOSSIBLE;
|
||||
for (padid = MSACM_pFirstACMDriverID; padid; padid = padid->pNextACMDriverID) {
|
||||
/* should check for codec only */
|
||||
if (!(padid->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_DISABLED) &&
|
||||
acmDriverOpen(&had, (HACMDRIVERID)padid, 0) == 0) {
|
||||
mmr = MSACM_Message(had, ACMDM_FILTERTAG_DETAILS, (LPARAM)paftd, fdwDetails);
|
||||
acmDriverClose(had, 0);
|
||||
if (mmr == MMSYSERR_NOERROR) break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
mmr = MSACM_Message(had, ACMDM_FILTERTAG_DETAILS, (LPARAM)paftd, fdwDetails);
|
||||
}
|
||||
break;
|
||||
|
||||
case ACM_FILTERTAGDETAILSF_INDEX:
|
||||
/* FIXME should check paftd->dwFilterTagIndex < add.cFilterTags */
|
||||
mmr = MSACM_Message(had, ACMDM_FILTERTAG_DETAILS, (LPARAM)paftd, fdwDetails);
|
||||
break;
|
||||
|
||||
case ACM_FILTERTAGDETAILSF_LARGESTSIZE:
|
||||
if (had == NULL) {
|
||||
ACMFILTERTAGDETAILSW tmp;
|
||||
DWORD ft = paftd->dwFilterTag;
|
||||
|
||||
mmr = ACMERR_NOTPOSSIBLE;
|
||||
for (padid = MSACM_pFirstACMDriverID; padid; padid = padid->pNextACMDriverID) {
|
||||
/* should check for codec only */
|
||||
if (!(padid->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_DISABLED) &&
|
||||
acmDriverOpen(&had, (HACMDRIVERID)padid, 0) == 0) {
|
||||
|
||||
memset(&tmp, 0, sizeof(tmp));
|
||||
tmp.cbStruct = sizeof(tmp);
|
||||
tmp.dwFilterTag = ft;
|
||||
|
||||
if (MSACM_Message(had, ACMDM_FILTERTAG_DETAILS,
|
||||
(LPARAM)&tmp, fdwDetails) == MMSYSERR_NOERROR) {
|
||||
if (mmr == ACMERR_NOTPOSSIBLE ||
|
||||
paftd->cbFilterSize < tmp.cbFilterSize) {
|
||||
*paftd = tmp;
|
||||
mmr = MMSYSERR_NOERROR;
|
||||
}
|
||||
}
|
||||
acmDriverClose(had, 0);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
mmr = MSACM_Message(had, ACMDM_FILTERTAG_DETAILS, (LPARAM)paftd, fdwDetails);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
WARN("Unsupported fdwDetails=%08lx\n", fdwDetails);
|
||||
mmr = MMSYSERR_ERROR;
|
||||
}
|
||||
|
||||
if (mmr == MMSYSERR_NOERROR &&
|
||||
paftd->dwFilterTag == WAVE_FORMAT_PCM && paftd->szFilterTag[0] == 0)
|
||||
MultiByteToWideChar( CP_ACP, 0, "PCM", -1, paftd->szFilterTag,
|
||||
sizeof(paftd->szFilterTag)/sizeof(WCHAR) );
|
||||
|
||||
return mmr;
|
||||
}
|
||||
|
||||
struct MSACM_FilterTagEnumWtoA_Instance {
|
||||
PACMFILTERTAGDETAILSA paftda;
|
||||
DWORD dwInstance;
|
||||
ACMFILTERTAGENUMCBA fnCallback;
|
||||
};
|
||||
|
||||
static BOOL CALLBACK MSACM_FilterTagEnumCallbackWtoA(HACMDRIVERID hadid,
|
||||
PACMFILTERTAGDETAILSW paftdw,
|
||||
DWORD dwInstance,
|
||||
DWORD fdwSupport)
|
||||
{
|
||||
struct MSACM_FilterTagEnumWtoA_Instance* paftei;
|
||||
|
||||
paftei = (struct MSACM_FilterTagEnumWtoA_Instance*)dwInstance;
|
||||
|
||||
paftei->paftda->dwFilterTagIndex = paftdw->dwFilterTagIndex;
|
||||
paftei->paftda->dwFilterTag = paftdw->dwFilterTag;
|
||||
paftei->paftda->cbFilterSize = paftdw->cbFilterSize;
|
||||
paftei->paftda->fdwSupport = paftdw->fdwSupport;
|
||||
paftei->paftda->cStandardFilters = paftdw->cStandardFilters;
|
||||
WideCharToMultiByte( CP_ACP, 0, paftdw->szFilterTag, -1, paftei->paftda->szFilterTag,
|
||||
sizeof(paftei->paftda->szFilterTag), NULL, NULL );
|
||||
|
||||
return (paftei->fnCallback)(hadid, paftei->paftda,
|
||||
paftei->dwInstance, fdwSupport);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* acmFilterTagEnumA (MSACM32.@)
|
||||
*/
|
||||
MMRESULT WINAPI acmFilterTagEnumA(HACMDRIVER had, PACMFILTERTAGDETAILSA paftda,
|
||||
ACMFILTERTAGENUMCBA fnCallback, DWORD dwInstance,
|
||||
DWORD fdwEnum)
|
||||
{
|
||||
ACMFILTERTAGDETAILSW aftdw;
|
||||
struct MSACM_FilterTagEnumWtoA_Instance aftei;
|
||||
|
||||
memset(&aftdw, 0, sizeof(aftdw));
|
||||
aftdw.cbStruct = sizeof(aftdw);
|
||||
aftdw.dwFilterTagIndex = paftda->dwFilterTagIndex;
|
||||
aftdw.dwFilterTag = paftda->dwFilterTag;
|
||||
|
||||
aftei.paftda = paftda;
|
||||
aftei.dwInstance = dwInstance;
|
||||
aftei.fnCallback = fnCallback;
|
||||
|
||||
return acmFilterTagEnumW(had, &aftdw, MSACM_FilterTagEnumCallbackWtoA,
|
||||
(DWORD)&aftei, fdwEnum);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* acmFilterTagEnumW (MSACM32.@)
|
||||
*/
|
||||
MMRESULT WINAPI acmFilterTagEnumW(HACMDRIVER had, PACMFILTERTAGDETAILSW paftd,
|
||||
ACMFILTERTAGENUMCBW fnCallback, DWORD dwInstance,
|
||||
DWORD fdwEnum)
|
||||
{
|
||||
PWINE_ACMDRIVERID padid;
|
||||
int i;
|
||||
|
||||
TRACE("(%p, %p, %p, %ld, %ld)\n",
|
||||
had, paftd, fnCallback, dwInstance, fdwEnum);
|
||||
|
||||
if (paftd->cbStruct < sizeof(*paftd)) return MMSYSERR_INVALPARAM;
|
||||
|
||||
if (had) FIXME("had != NULL, not supported\n");
|
||||
|
||||
for (padid = MSACM_pFirstACMDriverID; padid; padid = padid->pNextACMDriverID) {
|
||||
/* should check for codec only */
|
||||
if (!(padid->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_DISABLED) &&
|
||||
acmDriverOpen(&had, (HACMDRIVERID)padid, 0) == MMSYSERR_NOERROR) {
|
||||
|
||||
for (i = 0; i < padid->cFilterTags; i++) {
|
||||
paftd->dwFilterTagIndex = i;
|
||||
if (acmFilterTagDetailsW(had, paftd, ACM_FILTERTAGDETAILSF_INDEX) == MMSYSERR_NOERROR) {
|
||||
if (!(fnCallback)((HACMDRIVERID)padid, paftd, dwInstance, padid->fdwSupport)) {
|
||||
padid = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
acmDriverClose(had, 0);
|
||||
}
|
||||
return MMSYSERR_NOERROR;
|
||||
}
|
832
reactos/lib/msacm/format.c
Normal file
832
reactos/lib/msacm/format.c
Normal file
|
@ -0,0 +1,832 @@
|
|||
/* -*- tab-width: 8; c-basic-offset: 4 -*- */
|
||||
|
||||
/*
|
||||
* MSACM32 library
|
||||
*
|
||||
* Copyright 1998 Patrik Stridvall
|
||||
* 2000 Eric Pouech
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "winnls.h"
|
||||
#include "winerror.h"
|
||||
#include "wingdi.h"
|
||||
#include "winuser.h"
|
||||
#include "wine/unicode.h"
|
||||
#include "wine/debug.h"
|
||||
#include "mmsystem.h"
|
||||
#include "mmreg.h"
|
||||
#include "msacm.h"
|
||||
#include "msacmdrv.h"
|
||||
#include "wineacm.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(msacm);
|
||||
|
||||
static PACMFORMATCHOOSEA afc;
|
||||
|
||||
struct MSACM_FillFormatData {
|
||||
HWND hWnd;
|
||||
#define WINE_ACMFF_TAG 0
|
||||
#define WINE_ACMFF_FORMAT 1
|
||||
#define WINE_ACMFF_WFX 2
|
||||
int mode;
|
||||
char szFormatTag[ACMFORMATTAGDETAILS_FORMATTAG_CHARS];
|
||||
PACMFORMATCHOOSEA afc;
|
||||
DWORD ret;
|
||||
};
|
||||
|
||||
static BOOL CALLBACK MSACM_FillFormatTagsCB(HACMDRIVERID hadid,
|
||||
PACMFORMATTAGDETAILSA paftd,
|
||||
DWORD dwInstance, DWORD fdwSupport)
|
||||
{
|
||||
struct MSACM_FillFormatData* affd = (struct MSACM_FillFormatData*)dwInstance;
|
||||
|
||||
switch (affd->mode) {
|
||||
case WINE_ACMFF_TAG:
|
||||
if (SendDlgItemMessageA(affd->hWnd, IDD_ACMFORMATCHOOSE_CMB_FORMATTAG,
|
||||
CB_FINDSTRINGEXACT,
|
||||
(WPARAM)-1, (LPARAM)paftd->szFormatTag) == CB_ERR)
|
||||
SendDlgItemMessageA(affd->hWnd, IDD_ACMFORMATCHOOSE_CMB_FORMATTAG,
|
||||
CB_ADDSTRING, 0, (DWORD)paftd->szFormatTag);
|
||||
break;
|
||||
case WINE_ACMFF_FORMAT:
|
||||
if (strcmp(affd->szFormatTag, paftd->szFormatTag) == 0) {
|
||||
HACMDRIVER had;
|
||||
|
||||
if (acmDriverOpen(&had, hadid, 0) == MMSYSERR_NOERROR) {
|
||||
ACMFORMATDETAILSA afd;
|
||||
int i, idx;
|
||||
MMRESULT mmr;
|
||||
char buffer[ACMFORMATDETAILS_FORMAT_CHARS+16];
|
||||
|
||||
afd.cbStruct = sizeof(afd);
|
||||
afd.dwFormatTag = paftd->dwFormatTag;
|
||||
afd.pwfx = HeapAlloc(MSACM_hHeap, 0, paftd->cbFormatSize);
|
||||
if (!afd.pwfx) return FALSE;
|
||||
afd.pwfx->wFormatTag = paftd->dwFormatTag;
|
||||
afd.pwfx->cbSize = paftd->cbFormatSize;
|
||||
afd.cbwfx = paftd->cbFormatSize;
|
||||
|
||||
for (i = 0; i < paftd->cStandardFormats; i++) {
|
||||
afd.dwFormatIndex = i;
|
||||
mmr = acmFormatDetailsA(had, &afd, ACM_FORMATDETAILSF_INDEX);
|
||||
if (mmr == MMSYSERR_NOERROR) {
|
||||
strncpy(buffer, afd.szFormat, ACMFORMATTAGDETAILS_FORMATTAG_CHARS);
|
||||
for (idx = strlen(buffer);
|
||||
idx < ACMFORMATTAGDETAILS_FORMATTAG_CHARS; idx++)
|
||||
buffer[idx] = ' ';
|
||||
wsprintfA(buffer + ACMFORMATTAGDETAILS_FORMATTAG_CHARS,
|
||||
"%d Ko/s",
|
||||
(afd.pwfx->nAvgBytesPerSec + 512) / 1024);
|
||||
SendDlgItemMessageA(affd->hWnd,
|
||||
IDD_ACMFORMATCHOOSE_CMB_FORMAT,
|
||||
CB_ADDSTRING, 0, (DWORD)buffer);
|
||||
}
|
||||
}
|
||||
acmDriverClose(had, 0);
|
||||
SendDlgItemMessageA(affd->hWnd, IDD_ACMFORMATCHOOSE_CMB_FORMAT,
|
||||
CB_SETCURSEL, 0, 0);
|
||||
HeapFree(MSACM_hHeap, 0, afd.pwfx);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case WINE_ACMFF_WFX:
|
||||
if (strcmp(affd->szFormatTag, paftd->szFormatTag) == 0) {
|
||||
HACMDRIVER had;
|
||||
|
||||
if (acmDriverOpen(&had, hadid, 0) == MMSYSERR_NOERROR) {
|
||||
ACMFORMATDETAILSA afd;
|
||||
|
||||
afd.cbStruct = sizeof(afd);
|
||||
afd.dwFormatTag = paftd->dwFormatTag;
|
||||
afd.pwfx = affd->afc->pwfx;
|
||||
afd.cbwfx = affd->afc->cbwfx;
|
||||
|
||||
afd.dwFormatIndex = SendDlgItemMessageA(affd->hWnd, IDD_ACMFORMATCHOOSE_CMB_FORMAT,
|
||||
CB_GETCURSEL, 0, 0);
|
||||
affd->ret = acmFormatDetailsA(had, &afd, ACM_FORMATDETAILSF_INDEX);
|
||||
acmDriverClose(had, 0);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
FIXME("Unknown mode (%d)\n", affd->mode);
|
||||
break;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL MSACM_FillFormatTags(HWND hWnd)
|
||||
{
|
||||
ACMFORMATTAGDETAILSA aftd;
|
||||
struct MSACM_FillFormatData affd;
|
||||
|
||||
memset(&aftd, 0, sizeof(aftd));
|
||||
aftd.cbStruct = sizeof(aftd);
|
||||
|
||||
affd.hWnd = hWnd;
|
||||
affd.mode = WINE_ACMFF_TAG;
|
||||
|
||||
acmFormatTagEnumA(NULL, &aftd, MSACM_FillFormatTagsCB, (DWORD)&affd, 0);
|
||||
SendDlgItemMessageA(hWnd, IDD_ACMFORMATCHOOSE_CMB_FORMATTAG, CB_SETCURSEL, 0, 0);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL MSACM_FillFormat(HWND hWnd)
|
||||
{
|
||||
ACMFORMATTAGDETAILSA aftd;
|
||||
struct MSACM_FillFormatData affd;
|
||||
|
||||
SendDlgItemMessageA(hWnd, IDD_ACMFORMATCHOOSE_CMB_FORMAT, CB_RESETCONTENT, 0, 0);
|
||||
|
||||
memset(&aftd, 0, sizeof(aftd));
|
||||
aftd.cbStruct = sizeof(aftd);
|
||||
|
||||
affd.hWnd = hWnd;
|
||||
affd.mode = WINE_ACMFF_FORMAT;
|
||||
SendDlgItemMessageA(hWnd, IDD_ACMFORMATCHOOSE_CMB_FORMATTAG,
|
||||
CB_GETLBTEXT,
|
||||
SendDlgItemMessageA(hWnd, IDD_ACMFORMATCHOOSE_CMB_FORMATTAG,
|
||||
CB_GETCURSEL, 0, 0),
|
||||
(DWORD)affd.szFormatTag);
|
||||
|
||||
acmFormatTagEnumA(NULL, &aftd, MSACM_FillFormatTagsCB, (DWORD)&affd, 0);
|
||||
SendDlgItemMessageA(hWnd, IDD_ACMFORMATCHOOSE_CMB_FORMAT, CB_SETCURSEL, 0, 0);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static MMRESULT MSACM_GetWFX(HWND hWnd, PACMFORMATCHOOSEA afc)
|
||||
{
|
||||
ACMFORMATTAGDETAILSA aftd;
|
||||
struct MSACM_FillFormatData affd;
|
||||
|
||||
memset(&aftd, 0, sizeof(aftd));
|
||||
aftd.cbStruct = sizeof(aftd);
|
||||
|
||||
affd.hWnd = hWnd;
|
||||
affd.mode = WINE_ACMFF_WFX;
|
||||
affd.afc = afc;
|
||||
affd.ret = MMSYSERR_NOERROR;
|
||||
SendDlgItemMessageA(hWnd, IDD_ACMFORMATCHOOSE_CMB_FORMATTAG,
|
||||
CB_GETLBTEXT,
|
||||
SendDlgItemMessageA(hWnd, IDD_ACMFORMATCHOOSE_CMB_FORMATTAG,
|
||||
CB_GETCURSEL, 0, 0),
|
||||
(DWORD)affd.szFormatTag);
|
||||
|
||||
acmFormatTagEnumA(NULL, &aftd, MSACM_FillFormatTagsCB, (DWORD)&affd, 0);
|
||||
return affd.ret;
|
||||
}
|
||||
|
||||
static INT_PTR CALLBACK FormatChooseDlgProc(HWND hWnd, UINT msg,
|
||||
WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
|
||||
TRACE("hwnd=%p msg=%i 0x%08x 0x%08lx\n", hWnd, msg, wParam, lParam );
|
||||
|
||||
switch (msg) {
|
||||
case WM_INITDIALOG:
|
||||
afc = (PACMFORMATCHOOSEA)lParam;
|
||||
MSACM_FillFormatTags(hWnd);
|
||||
MSACM_FillFormat(hWnd);
|
||||
if ((afc->fdwStyle & ~(ACMFORMATCHOOSE_STYLEF_CONTEXTHELP|
|
||||
ACMFORMATCHOOSE_STYLEF_SHOWHELP)) != 0)
|
||||
FIXME("Unsupported style %08lx\n", ((PACMFORMATCHOOSEA)lParam)->fdwStyle);
|
||||
if (!(afc->fdwStyle & ACMFORMATCHOOSE_STYLEF_SHOWHELP))
|
||||
ShowWindow(GetDlgItem(hWnd, IDD_ACMFORMATCHOOSE_BTN_HELP), SW_HIDE);
|
||||
return TRUE;
|
||||
|
||||
case WM_COMMAND:
|
||||
switch (LOWORD(wParam)) {
|
||||
case IDOK:
|
||||
EndDialog(hWnd, MSACM_GetWFX(hWnd, afc));
|
||||
return TRUE;
|
||||
case IDCANCEL:
|
||||
EndDialog(hWnd, ACMERR_CANCELED);
|
||||
return TRUE;
|
||||
case IDD_ACMFORMATCHOOSE_CMB_FORMATTAG:
|
||||
switch (HIWORD(wParam)) {
|
||||
case CBN_SELCHANGE:
|
||||
MSACM_FillFormat(hWnd);
|
||||
break;
|
||||
default:
|
||||
TRACE("Dropped dlgNotif (fmtTag): 0x%08x 0x%08lx\n",
|
||||
HIWORD(wParam), lParam);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case IDD_ACMFORMATCHOOSE_BTN_HELP:
|
||||
if (afc->fdwStyle & ACMFORMATCHOOSE_STYLEF_SHOWHELP)
|
||||
SendMessageA(afc->hwndOwner,
|
||||
RegisterWindowMessageA(ACMHELPMSGSTRINGA), 0L, 0L);
|
||||
break;
|
||||
|
||||
default:
|
||||
TRACE("Dropped dlgCmd: ctl=%d ntf=0x%04x 0x%08lx\n",
|
||||
LOWORD(wParam), HIWORD(wParam), lParam);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case WM_CONTEXTMENU:
|
||||
if (afc->fdwStyle & ACMFORMATCHOOSE_STYLEF_CONTEXTHELP)
|
||||
SendMessageA(afc->hwndOwner,
|
||||
RegisterWindowMessageA(ACMHELPMSGCONTEXTMENUA),
|
||||
wParam, lParam);
|
||||
break;
|
||||
#if defined(WM_CONTEXTHELP)
|
||||
case WM_CONTEXTHELP:
|
||||
if (afc->fdwStyle & ACMFORMATCHOOSE_STYLEF_CONTEXTHELP)
|
||||
SendMessageA(afc->hwndOwner,
|
||||
RegisterWindowMessageA(ACMHELPMSGCONTEXTHELPA),
|
||||
wParam, lParam);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
TRACE("Dropped dlgMsg: hwnd=%p msg=%i 0x%08x 0x%08lx\n",
|
||||
hWnd, msg, wParam, lParam );
|
||||
break;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* acmFormatChooseA (MSACM32.@)
|
||||
*/
|
||||
MMRESULT WINAPI acmFormatChooseA(PACMFORMATCHOOSEA pafmtc)
|
||||
{
|
||||
return DialogBoxParamA(MSACM_hInstance32, MAKEINTRESOURCEA(DLG_ACMFORMATCHOOSE_ID),
|
||||
pafmtc->hwndOwner, FormatChooseDlgProc, (INT)pafmtc);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* acmFormatChooseW (MSACM32.@)
|
||||
*/
|
||||
MMRESULT WINAPI acmFormatChooseW(PACMFORMATCHOOSEW pafmtc)
|
||||
{
|
||||
FIXME("(%p): stub\n", pafmtc);
|
||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
return MMSYSERR_ERROR;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* acmFormatDetailsA (MSACM32.@)
|
||||
*/
|
||||
MMRESULT WINAPI acmFormatDetailsA(HACMDRIVER had, PACMFORMATDETAILSA pafd,
|
||||
DWORD fdwDetails)
|
||||
{
|
||||
ACMFORMATDETAILSW afdw;
|
||||
MMRESULT mmr;
|
||||
|
||||
memset(&afdw, 0, sizeof(afdw));
|
||||
afdw.cbStruct = sizeof(afdw);
|
||||
afdw.dwFormatIndex = pafd->dwFormatIndex;
|
||||
afdw.dwFormatTag = pafd->dwFormatTag;
|
||||
afdw.pwfx = pafd->pwfx;
|
||||
afdw.cbwfx = pafd->cbwfx;
|
||||
|
||||
mmr = acmFormatDetailsW(had, &afdw, fdwDetails);
|
||||
if (mmr == MMSYSERR_NOERROR) {
|
||||
pafd->dwFormatTag = afdw.dwFormatTag;
|
||||
pafd->fdwSupport = afdw.fdwSupport;
|
||||
WideCharToMultiByte( CP_ACP, 0, afdw.szFormat, -1,
|
||||
pafd->szFormat, sizeof(pafd->szFormat), NULL, NULL );
|
||||
}
|
||||
return mmr;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* acmFormatDetailsW (MSACM32.@)
|
||||
*/
|
||||
MMRESULT WINAPI acmFormatDetailsW(HACMDRIVER had, PACMFORMATDETAILSW pafd, DWORD fdwDetails)
|
||||
{
|
||||
MMRESULT mmr;
|
||||
static WCHAR fmt1[] = {'%','d',' ','H','z',0};
|
||||
static WCHAR fmt2[] = {';',' ','%','d',' ','b','i','t','s',0};
|
||||
ACMFORMATTAGDETAILSA aftd;
|
||||
|
||||
TRACE("(%p, %p, %ld)\n", had, pafd, fdwDetails);
|
||||
|
||||
memset(&aftd, 0, sizeof(aftd));
|
||||
aftd.cbStruct = sizeof(aftd);
|
||||
|
||||
if (pafd->cbStruct < sizeof(*pafd)) return MMSYSERR_INVALPARAM;
|
||||
|
||||
switch (fdwDetails) {
|
||||
case ACM_FORMATDETAILSF_FORMAT:
|
||||
if (pafd->dwFormatTag != pafd->pwfx->wFormatTag) {
|
||||
mmr = MMSYSERR_INVALPARAM;
|
||||
break;
|
||||
}
|
||||
if (had == NULL) {
|
||||
PWINE_ACMDRIVERID padid;
|
||||
|
||||
mmr = ACMERR_NOTPOSSIBLE;
|
||||
for (padid = MSACM_pFirstACMDriverID; padid; padid = padid->pNextACMDriverID) {
|
||||
/* should check for codec only */
|
||||
if (!(padid->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_DISABLED) &&
|
||||
acmDriverOpen(&had, (HACMDRIVERID)padid, 0) == 0) {
|
||||
mmr = MSACM_Message(had, ACMDM_FORMAT_DETAILS, (LPARAM)pafd, fdwDetails);
|
||||
acmDriverClose(had, 0);
|
||||
if (mmr == MMSYSERR_NOERROR) break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
mmr = MSACM_Message(had, ACMDM_FORMAT_DETAILS, (LPARAM)pafd, fdwDetails);
|
||||
}
|
||||
break;
|
||||
case ACM_FORMATDETAILSF_INDEX:
|
||||
/* should check pafd->dwFormatIndex < aftd->cStandardFormats */
|
||||
mmr = MSACM_Message(had, ACMDM_FORMAT_DETAILS, (LPARAM)pafd, fdwDetails);
|
||||
break;
|
||||
default:
|
||||
WARN("Unknown fdwDetails %08lx\n", fdwDetails);
|
||||
mmr = MMSYSERR_INVALFLAG;
|
||||
break;
|
||||
}
|
||||
|
||||
if (mmr == MMSYSERR_NOERROR && pafd->szFormat[0] == (WCHAR)0) {
|
||||
wsprintfW(pafd->szFormat, fmt1, pafd->pwfx->nSamplesPerSec);
|
||||
if (pafd->pwfx->wBitsPerSample) {
|
||||
wsprintfW(pafd->szFormat + lstrlenW(pafd->szFormat), fmt2,
|
||||
pafd->pwfx->wBitsPerSample);
|
||||
}
|
||||
MultiByteToWideChar( CP_ACP, 0, (pafd->pwfx->nChannels == 1) ? "; Mono" : "; Stereo", -1,
|
||||
pafd->szFormat + strlenW(pafd->szFormat),
|
||||
sizeof(pafd->szFormat)/sizeof(WCHAR) - strlenW(pafd->szFormat) );
|
||||
}
|
||||
|
||||
TRACE("=> %d\n", mmr);
|
||||
return mmr;
|
||||
}
|
||||
|
||||
struct MSACM_FormatEnumWtoA_Instance {
|
||||
PACMFORMATDETAILSA pafda;
|
||||
DWORD dwInstance;
|
||||
ACMFORMATENUMCBA fnCallback;
|
||||
};
|
||||
|
||||
static BOOL CALLBACK MSACM_FormatEnumCallbackWtoA(HACMDRIVERID hadid,
|
||||
PACMFORMATDETAILSW pafdw,
|
||||
DWORD dwInstance,
|
||||
DWORD fdwSupport)
|
||||
{
|
||||
struct MSACM_FormatEnumWtoA_Instance* pafei;
|
||||
|
||||
pafei = (struct MSACM_FormatEnumWtoA_Instance*)dwInstance;
|
||||
|
||||
pafei->pafda->dwFormatIndex = pafdw->dwFormatIndex;
|
||||
pafei->pafda->dwFormatTag = pafdw->dwFormatTag;
|
||||
pafei->pafda->fdwSupport = pafdw->fdwSupport;
|
||||
WideCharToMultiByte( CP_ACP, 0, pafdw->szFormat, -1,
|
||||
pafei->pafda->szFormat, sizeof(pafei->pafda->szFormat), NULL, NULL );
|
||||
|
||||
return (pafei->fnCallback)(hadid, pafei->pafda,
|
||||
pafei->dwInstance, fdwSupport);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* acmFormatEnumA (MSACM32.@)
|
||||
*/
|
||||
MMRESULT WINAPI acmFormatEnumA(HACMDRIVER had, PACMFORMATDETAILSA pafda,
|
||||
ACMFORMATENUMCBA fnCallback, DWORD dwInstance,
|
||||
DWORD fdwEnum)
|
||||
{
|
||||
ACMFORMATDETAILSW afdw;
|
||||
struct MSACM_FormatEnumWtoA_Instance afei;
|
||||
|
||||
memset(&afdw, 0, sizeof(afdw));
|
||||
afdw.cbStruct = sizeof(afdw);
|
||||
afdw.dwFormatIndex = pafda->dwFormatIndex;
|
||||
afdw.dwFormatTag = pafda->dwFormatTag;
|
||||
afdw.pwfx = pafda->pwfx;
|
||||
afdw.cbwfx = pafda->cbwfx;
|
||||
|
||||
afei.pafda = pafda;
|
||||
afei.dwInstance = dwInstance;
|
||||
afei.fnCallback = fnCallback;
|
||||
|
||||
return acmFormatEnumW(had, &afdw, MSACM_FormatEnumCallbackWtoA,
|
||||
(DWORD)&afei, fdwEnum);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* acmFormatEnumW (MSACM32.@)
|
||||
*/
|
||||
static BOOL MSACM_FormatEnumHelper(PWINE_ACMDRIVERID padid, HACMDRIVER had,
|
||||
PACMFORMATDETAILSW pafd, PWAVEFORMATEX pwfxRef,
|
||||
ACMFORMATENUMCBW fnCallback, DWORD dwInstance,
|
||||
DWORD fdwEnum)
|
||||
{
|
||||
ACMFORMATTAGDETAILSW aftd;
|
||||
int i, j;
|
||||
|
||||
for (i = 0; i < padid->cFormatTags; i++) {
|
||||
memset(&aftd, 0, sizeof(aftd));
|
||||
aftd.cbStruct = sizeof(aftd);
|
||||
aftd.dwFormatTagIndex = i;
|
||||
if (acmFormatTagDetailsW(had, &aftd, ACM_FORMATTAGDETAILSF_INDEX) != MMSYSERR_NOERROR)
|
||||
continue;
|
||||
|
||||
if ((fdwEnum & ACM_FORMATENUMF_WFORMATTAG) && aftd.dwFormatTag != pwfxRef->wFormatTag)
|
||||
continue;
|
||||
|
||||
for (j = 0; j < aftd.cStandardFormats; j++) {
|
||||
pafd->dwFormatIndex = j;
|
||||
pafd->dwFormatTag = aftd.dwFormatTag;
|
||||
if (acmFormatDetailsW(had, pafd, ACM_FORMATDETAILSF_INDEX) != MMSYSERR_NOERROR)
|
||||
continue;
|
||||
|
||||
if ((fdwEnum & ACM_FORMATENUMF_NCHANNELS) &&
|
||||
pafd->pwfx->nChannels != pwfxRef->nChannels)
|
||||
continue;
|
||||
if ((fdwEnum & ACM_FORMATENUMF_NSAMPLESPERSEC) &&
|
||||
pafd->pwfx->nSamplesPerSec != pwfxRef->nSamplesPerSec)
|
||||
continue;
|
||||
if ((fdwEnum & ACM_FORMATENUMF_WBITSPERSAMPLE) &&
|
||||
pafd->pwfx->wBitsPerSample != pwfxRef->wBitsPerSample)
|
||||
continue;
|
||||
if ((fdwEnum & ACM_FORMATENUMF_HARDWARE) &&
|
||||
!(pafd->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_HARDWARE))
|
||||
continue;
|
||||
|
||||
/* more checks to be done on fdwEnum */
|
||||
|
||||
if (!(fnCallback)((HACMDRIVERID)padid, pafd, dwInstance, padid->fdwSupport))
|
||||
return FALSE;
|
||||
}
|
||||
/* the "formats" used by the filters are also reported */
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**********************************************************************/
|
||||
|
||||
MMRESULT WINAPI acmFormatEnumW(HACMDRIVER had, PACMFORMATDETAILSW pafd,
|
||||
ACMFORMATENUMCBW fnCallback, DWORD dwInstance,
|
||||
DWORD fdwEnum)
|
||||
{
|
||||
PWINE_ACMDRIVERID padid;
|
||||
WAVEFORMATEX wfxRef;
|
||||
BOOL ret;
|
||||
|
||||
TRACE("(%p, %p, %p, %ld, %ld)\n",
|
||||
had, pafd, fnCallback, dwInstance, fdwEnum);
|
||||
|
||||
if (pafd->cbStruct < sizeof(*pafd)) return MMSYSERR_INVALPARAM;
|
||||
|
||||
if (fdwEnum & (ACM_FORMATENUMF_WFORMATTAG|ACM_FORMATENUMF_NCHANNELS|
|
||||
ACM_FORMATENUMF_NSAMPLESPERSEC|ACM_FORMATENUMF_WBITSPERSAMPLE|
|
||||
ACM_FORMATENUMF_CONVERT|ACM_FORMATENUMF_SUGGEST))
|
||||
wfxRef = *pafd->pwfx;
|
||||
|
||||
if ((fdwEnum & ACM_FORMATENUMF_HARDWARE) &&
|
||||
!(fdwEnum & (ACM_FORMATENUMF_INPUT|ACM_FORMATENUMF_OUTPUT)))
|
||||
return MMSYSERR_INVALPARAM;
|
||||
|
||||
if ((fdwEnum & ACM_FORMATENUMF_WFORMATTAG) &&
|
||||
(pafd->dwFormatTag != pafd->pwfx->wFormatTag))
|
||||
return MMSYSERR_INVALPARAM;
|
||||
|
||||
if (fdwEnum & (ACM_FORMATENUMF_CONVERT|ACM_FORMATENUMF_SUGGEST|
|
||||
ACM_FORMATENUMF_INPUT|ACM_FORMATENUMF_OUTPUT))
|
||||
FIXME("Unsupported fdwEnum values %08lx\n", fdwEnum);
|
||||
|
||||
if (had) {
|
||||
HACMDRIVERID hadid;
|
||||
|
||||
if (acmDriverID((HACMOBJ)had, &hadid, 0) != MMSYSERR_NOERROR)
|
||||
return MMSYSERR_INVALHANDLE;
|
||||
MSACM_FormatEnumHelper(MSACM_GetDriverID(hadid), had, pafd, &wfxRef,
|
||||
fnCallback, dwInstance, fdwEnum);
|
||||
return MMSYSERR_NOERROR;
|
||||
}
|
||||
for (padid = MSACM_pFirstACMDriverID; padid; padid = padid->pNextACMDriverID) {
|
||||
/* should check for codec only */
|
||||
if ((padid->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_DISABLED) ||
|
||||
acmDriverOpen(&had, (HACMDRIVERID)padid, 0) != MMSYSERR_NOERROR)
|
||||
continue;
|
||||
ret = MSACM_FormatEnumHelper(padid, had, pafd, &wfxRef,
|
||||
fnCallback, dwInstance, fdwEnum);
|
||||
acmDriverClose(had, 0);
|
||||
if (!ret) break;
|
||||
}
|
||||
return MMSYSERR_NOERROR;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* acmFormatSuggest (MSACM32.@)
|
||||
*/
|
||||
MMRESULT WINAPI acmFormatSuggest(HACMDRIVER had, PWAVEFORMATEX pwfxSrc,
|
||||
PWAVEFORMATEX pwfxDst, DWORD cbwfxDst, DWORD fdwSuggest)
|
||||
{
|
||||
ACMDRVFORMATSUGGEST adfg;
|
||||
MMRESULT mmr;
|
||||
|
||||
TRACE("(%p, %p, %p, %ld, %ld)\n",
|
||||
had, pwfxSrc, pwfxDst, cbwfxDst, fdwSuggest);
|
||||
|
||||
if (fdwSuggest & ~(ACM_FORMATSUGGESTF_NCHANNELS|ACM_FORMATSUGGESTF_NSAMPLESPERSEC|
|
||||
ACM_FORMATSUGGESTF_WBITSPERSAMPLE|ACM_FORMATSUGGESTF_WFORMATTAG))
|
||||
return MMSYSERR_INVALFLAG;
|
||||
|
||||
adfg.cbStruct = sizeof(adfg);
|
||||
adfg.fdwSuggest = fdwSuggest;
|
||||
adfg.pwfxSrc = pwfxSrc;
|
||||
adfg.cbwfxSrc = (pwfxSrc->wFormatTag == WAVE_FORMAT_PCM) ?
|
||||
sizeof(WAVEFORMATEX) : (sizeof(WAVEFORMATEX) + pwfxSrc->cbSize);
|
||||
adfg.pwfxDst = pwfxDst;
|
||||
adfg.cbwfxDst = cbwfxDst;
|
||||
|
||||
if (had == NULL) {
|
||||
PWINE_ACMDRIVERID padid;
|
||||
|
||||
/* MS doc says: ACM finds the best suggestion.
|
||||
* Well, first found will be the "best"
|
||||
*/
|
||||
mmr = ACMERR_NOTPOSSIBLE;
|
||||
for (padid = MSACM_pFirstACMDriverID; padid; padid = padid->pNextACMDriverID) {
|
||||
/* should check for codec only */
|
||||
if ((padid->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_DISABLED) ||
|
||||
acmDriverOpen(&had, (HACMDRIVERID)padid, 0) != MMSYSERR_NOERROR)
|
||||
continue;
|
||||
|
||||
if (MSACM_Message(had, ACMDM_FORMAT_SUGGEST, (LPARAM)&adfg, 0L) == MMSYSERR_NOERROR) {
|
||||
mmr = MMSYSERR_NOERROR;
|
||||
break;
|
||||
}
|
||||
acmDriverClose(had, 0);
|
||||
}
|
||||
} else {
|
||||
mmr = MSACM_Message(had, ACMDM_FORMAT_SUGGEST, (LPARAM)&adfg, 0L);
|
||||
}
|
||||
return mmr;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* acmFormatTagDetailsA (MSACM32.@)
|
||||
*/
|
||||
MMRESULT WINAPI acmFormatTagDetailsA(HACMDRIVER had, PACMFORMATTAGDETAILSA paftda,
|
||||
DWORD fdwDetails)
|
||||
{
|
||||
ACMFORMATTAGDETAILSW aftdw;
|
||||
MMRESULT mmr;
|
||||
|
||||
memset(&aftdw, 0, sizeof(aftdw));
|
||||
aftdw.cbStruct = sizeof(aftdw);
|
||||
aftdw.dwFormatTagIndex = paftda->dwFormatTagIndex;
|
||||
aftdw.dwFormatTag = paftda->dwFormatTag;
|
||||
|
||||
mmr = acmFormatTagDetailsW(had, &aftdw, fdwDetails);
|
||||
if (mmr == MMSYSERR_NOERROR) {
|
||||
paftda->dwFormatTag = aftdw.dwFormatTag;
|
||||
paftda->dwFormatTagIndex = aftdw.dwFormatTagIndex;
|
||||
paftda->cbFormatSize = aftdw.cbFormatSize;
|
||||
paftda->fdwSupport = aftdw.fdwSupport;
|
||||
paftda->cStandardFormats = aftdw.cStandardFormats;
|
||||
WideCharToMultiByte( CP_ACP, 0, aftdw.szFormatTag, -1, paftda->szFormatTag,
|
||||
sizeof(paftda->szFormatTag), NULL, NULL );
|
||||
}
|
||||
return mmr;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* acmFormatTagDetailsW (MSACM32.@)
|
||||
*/
|
||||
MMRESULT WINAPI acmFormatTagDetailsW(HACMDRIVER had, PACMFORMATTAGDETAILSW paftd,
|
||||
DWORD fdwDetails)
|
||||
{
|
||||
PWINE_ACMDRIVERID padid;
|
||||
MMRESULT mmr = ACMERR_NOTPOSSIBLE;
|
||||
|
||||
TRACE("(%p, %p, %ld)\n", had, paftd, fdwDetails);
|
||||
|
||||
if (fdwDetails & ~(ACM_FORMATTAGDETAILSF_FORMATTAG|ACM_FORMATTAGDETAILSF_INDEX|
|
||||
ACM_FORMATTAGDETAILSF_LARGESTSIZE))
|
||||
return MMSYSERR_INVALFLAG;
|
||||
|
||||
switch (fdwDetails) {
|
||||
case ACM_FORMATTAGDETAILSF_FORMATTAG:
|
||||
if (had == NULL) {
|
||||
for (padid = MSACM_pFirstACMDriverID; padid; padid = padid->pNextACMDriverID) {
|
||||
/* should check for codec only */
|
||||
if (!(padid->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_DISABLED) &&
|
||||
MSACM_FindFormatTagInCache(padid, paftd->dwFormatTag, NULL) &&
|
||||
acmDriverOpen(&had, (HACMDRIVERID)padid, 0) == 0) {
|
||||
mmr = MSACM_Message(had, ACMDM_FORMATTAG_DETAILS, (LPARAM)paftd, fdwDetails);
|
||||
acmDriverClose(had, 0);
|
||||
if (mmr == MMSYSERR_NOERROR) break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
PWINE_ACMDRIVER pad = MSACM_GetDriver(had);
|
||||
|
||||
if (pad && MSACM_FindFormatTagInCache(pad->obj.pACMDriverID, paftd->dwFormatTag, NULL))
|
||||
mmr = MSACM_Message(had, ACMDM_FORMATTAG_DETAILS, (LPARAM)paftd, fdwDetails);
|
||||
}
|
||||
break;
|
||||
|
||||
case ACM_FORMATTAGDETAILSF_INDEX:
|
||||
if (had != NULL) {
|
||||
PWINE_ACMDRIVER pad = MSACM_GetDriver(had);
|
||||
|
||||
if (pad && paftd->dwFormatTagIndex < pad->obj.pACMDriverID->cFormatTags)
|
||||
mmr = MSACM_Message(had, ACMDM_FORMATTAG_DETAILS, (LPARAM)paftd, fdwDetails);
|
||||
}
|
||||
break;
|
||||
|
||||
case ACM_FORMATTAGDETAILSF_LARGESTSIZE:
|
||||
if (had == NULL) {
|
||||
ACMFORMATTAGDETAILSW tmp;
|
||||
DWORD ft = paftd->dwFormatTag;
|
||||
|
||||
for (padid = MSACM_pFirstACMDriverID; padid; padid = padid->pNextACMDriverID) {
|
||||
/* should check for codec only */
|
||||
if (!(padid->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_DISABLED) &&
|
||||
acmDriverOpen(&had, (HACMDRIVERID)padid, 0) == 0) {
|
||||
|
||||
memset(&tmp, 0, sizeof(tmp));
|
||||
tmp.cbStruct = sizeof(tmp);
|
||||
tmp.dwFormatTag = ft;
|
||||
|
||||
if (MSACM_Message(had, ACMDM_FORMATTAG_DETAILS,
|
||||
(LPARAM)&tmp, fdwDetails) == MMSYSERR_NOERROR) {
|
||||
if (mmr == ACMERR_NOTPOSSIBLE ||
|
||||
paftd->cbFormatSize < tmp.cbFormatSize) {
|
||||
*paftd = tmp;
|
||||
mmr = MMSYSERR_NOERROR;
|
||||
}
|
||||
}
|
||||
acmDriverClose(had, 0);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
mmr = MSACM_Message(had, ACMDM_FORMATTAG_DETAILS, (LPARAM)paftd, fdwDetails);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
WARN("Unsupported fdwDetails=%08lx\n", fdwDetails);
|
||||
mmr = MMSYSERR_ERROR;
|
||||
}
|
||||
|
||||
if (mmr == MMSYSERR_NOERROR &&
|
||||
paftd->dwFormatTag == WAVE_FORMAT_PCM && paftd->szFormatTag[0] == 0)
|
||||
MultiByteToWideChar( CP_ACP, 0, "PCM", -1, paftd->szFormatTag,
|
||||
sizeof(paftd->szFormatTag)/sizeof(WCHAR) );
|
||||
|
||||
return mmr;
|
||||
}
|
||||
|
||||
struct MSACM_FormatTagEnumWtoA_Instance {
|
||||
PACMFORMATTAGDETAILSA paftda;
|
||||
DWORD dwInstance;
|
||||
ACMFORMATTAGENUMCBA fnCallback;
|
||||
};
|
||||
|
||||
static BOOL CALLBACK MSACM_FormatTagEnumCallbackWtoA(HACMDRIVERID hadid,
|
||||
PACMFORMATTAGDETAILSW paftdw,
|
||||
DWORD dwInstance,
|
||||
DWORD fdwSupport)
|
||||
{
|
||||
struct MSACM_FormatTagEnumWtoA_Instance* paftei;
|
||||
|
||||
paftei = (struct MSACM_FormatTagEnumWtoA_Instance*)dwInstance;
|
||||
|
||||
paftei->paftda->dwFormatTagIndex = paftdw->dwFormatTagIndex;
|
||||
paftei->paftda->dwFormatTag = paftdw->dwFormatTag;
|
||||
paftei->paftda->cbFormatSize = paftdw->cbFormatSize;
|
||||
paftei->paftda->fdwSupport = paftdw->fdwSupport;
|
||||
paftei->paftda->cStandardFormats = paftdw->cStandardFormats;
|
||||
WideCharToMultiByte( CP_ACP, 0, paftdw->szFormatTag, -1, paftei->paftda->szFormatTag,
|
||||
sizeof(paftei->paftda->szFormatTag), NULL, NULL );
|
||||
|
||||
return (paftei->fnCallback)(hadid, paftei->paftda,
|
||||
paftei->dwInstance, fdwSupport);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* acmFormatTagEnumA (MSACM32.@)
|
||||
*/
|
||||
MMRESULT WINAPI acmFormatTagEnumA(HACMDRIVER had, PACMFORMATTAGDETAILSA paftda,
|
||||
ACMFORMATTAGENUMCBA fnCallback, DWORD dwInstance,
|
||||
DWORD fdwEnum)
|
||||
{
|
||||
ACMFORMATTAGDETAILSW aftdw;
|
||||
struct MSACM_FormatTagEnumWtoA_Instance aftei;
|
||||
|
||||
memset(&aftdw, 0, sizeof(aftdw));
|
||||
aftdw.cbStruct = sizeof(aftdw);
|
||||
aftdw.dwFormatTagIndex = paftda->dwFormatTagIndex;
|
||||
aftdw.dwFormatTag = paftda->dwFormatTag;
|
||||
|
||||
aftei.paftda = paftda;
|
||||
aftei.dwInstance = dwInstance;
|
||||
aftei.fnCallback = fnCallback;
|
||||
|
||||
return acmFormatTagEnumW(had, &aftdw, MSACM_FormatTagEnumCallbackWtoA,
|
||||
(DWORD)&aftei, fdwEnum);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* acmFormatTagEnumW (MSACM32.@)
|
||||
*/
|
||||
MMRESULT WINAPI acmFormatTagEnumW(HACMDRIVER had, PACMFORMATTAGDETAILSW paftd,
|
||||
ACMFORMATTAGENUMCBW fnCallback, DWORD dwInstance,
|
||||
DWORD fdwEnum)
|
||||
{
|
||||
PWINE_ACMDRIVERID padid;
|
||||
int i;
|
||||
BOOL bPcmDone = FALSE;
|
||||
|
||||
TRACE("(%p, %p, %p, %ld, %ld)\n",
|
||||
had, paftd, fnCallback, dwInstance, fdwEnum);
|
||||
|
||||
if (paftd->cbStruct < sizeof(*paftd)) return MMSYSERR_INVALPARAM;
|
||||
|
||||
/* (WS) MSDN info page says that if had != 0, then we should find
|
||||
* the specific driver to get its tags from. Therefore I'm removing
|
||||
* the FIXME call and adding a search block below. It also seems
|
||||
* that the lack of this functionality was the responsible for
|
||||
* codecs to be multiply and incorrectly listed.
|
||||
*/
|
||||
|
||||
/* if (had) FIXME("had != NULL, not supported\n"); */
|
||||
|
||||
if (had) {
|
||||
|
||||
if (acmDriverID((HACMOBJ)had, (HACMDRIVERID *)&padid, 0) != MMSYSERR_NOERROR)
|
||||
return MMSYSERR_INVALHANDLE;
|
||||
|
||||
for (i = 0; i < padid->cFormatTags; i++) {
|
||||
paftd->dwFormatTagIndex = i;
|
||||
if (MSACM_Message(had, ACMDM_FORMATTAG_DETAILS,
|
||||
(LPARAM)paftd, ACM_FORMATTAGDETAILSF_INDEX) == MMSYSERR_NOERROR) {
|
||||
if (paftd->dwFormatTag == WAVE_FORMAT_PCM) {
|
||||
if (paftd->szFormatTag[0] == 0)
|
||||
MultiByteToWideChar( CP_ACP, 0, "PCM", -1, paftd->szFormatTag,
|
||||
sizeof(paftd->szFormatTag)/sizeof(WCHAR) );
|
||||
/* (WS) I'm preserving this PCM hack since it seems to be
|
||||
* correct. Please notice this block was borrowed from
|
||||
* below.
|
||||
*/
|
||||
if (bPcmDone) continue;
|
||||
bPcmDone = TRUE;
|
||||
}
|
||||
if (!(fnCallback)((HACMDRIVERID)padid, paftd, dwInstance, padid->fdwSupport))
|
||||
return MMSYSERR_NOERROR;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* if had==0 then search for the first suitable driver */
|
||||
else {
|
||||
for (padid = MSACM_pFirstACMDriverID; padid; padid = padid->pNextACMDriverID) {
|
||||
/* should check for codec only */
|
||||
if (!(padid->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_DISABLED) &&
|
||||
acmDriverOpen(&had, (HACMDRIVERID)padid, 0) == MMSYSERR_NOERROR) {
|
||||
for (i = 0; i < padid->cFormatTags; i++) {
|
||||
paftd->dwFormatTagIndex = i;
|
||||
if (MSACM_Message(had, ACMDM_FORMATTAG_DETAILS,
|
||||
(LPARAM)paftd, ACM_FORMATTAGDETAILSF_INDEX) == MMSYSERR_NOERROR) {
|
||||
if (paftd->dwFormatTag == WAVE_FORMAT_PCM) {
|
||||
if (paftd->szFormatTag[0] == 0)
|
||||
MultiByteToWideChar( CP_ACP, 0, "PCM", -1, paftd->szFormatTag,
|
||||
sizeof(paftd->szFormatTag)/sizeof(WCHAR) );
|
||||
/* FIXME (EPP): I'm not sure this is the correct
|
||||
* algorithm (should make more sense to apply the same
|
||||
* for all already loaded formats, but this will do
|
||||
* for now
|
||||
*/
|
||||
if (bPcmDone) continue;
|
||||
bPcmDone = TRUE;
|
||||
}
|
||||
if (!(fnCallback)((HACMDRIVERID)padid, paftd, dwInstance, padid->fdwSupport)) {
|
||||
acmDriverClose(had, 0);
|
||||
return MMSYSERR_NOERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
acmDriverClose(had, 0);
|
||||
}
|
||||
}
|
||||
return MMSYSERR_NOERROR;
|
||||
}
|
3
reactos/lib/msacm/imaadp32/.cvsignore
Normal file
3
reactos/lib/msacm/imaadp32/.cvsignore
Normal file
|
@ -0,0 +1,3 @@
|
|||
Makefile
|
||||
imaadp32.acm.dbg.c
|
||||
imaadp32.acm.spec.c
|
12
reactos/lib/msacm/imaadp32/Makefile.in
Normal file
12
reactos/lib/msacm/imaadp32/Makefile.in
Normal file
|
@ -0,0 +1,12 @@
|
|||
TOPSRCDIR = @top_srcdir@
|
||||
TOPOBJDIR = ../../..
|
||||
SRCDIR = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
MODULE = imaadp32.acm
|
||||
IMPORTS = winmm user32 kernel32
|
||||
|
||||
C_SRCS = imaadp32.c
|
||||
|
||||
@MAKE_DLL_RULES@
|
||||
|
||||
### Dependencies:
|
1
reactos/lib/msacm/imaadp32/imaadp32.acm.spec
Normal file
1
reactos/lib/msacm/imaadp32/imaadp32.acm.spec
Normal file
|
@ -0,0 +1 @@
|
|||
@ stdcall DriverProc (long long long long long) ADPCM_DriverProc
|
938
reactos/lib/msacm/imaadp32/imaadp32.c
Normal file
938
reactos/lib/msacm/imaadp32/imaadp32.c
Normal file
|
@ -0,0 +1,938 @@
|
|||
/*
|
||||
* IMA ADPCM handling
|
||||
*
|
||||
* Copyright (C) 2001,2002 Eric Pouech
|
||||
*
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "wingdi.h"
|
||||
#include "winuser.h"
|
||||
#include "winnls.h"
|
||||
#include "mmsystem.h"
|
||||
#include "mmreg.h"
|
||||
#include "msacm.h"
|
||||
#include "msacmdrv.h"
|
||||
#include "wine/debug.h"
|
||||
|
||||
/* see http://www.pcisys.net/~melanson/codecs/adpcm.txt for the details */
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(adpcm);
|
||||
|
||||
/***********************************************************************
|
||||
* ADPCM_drvOpen
|
||||
*/
|
||||
static DWORD ADPCM_drvOpen(LPCSTR str)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* ADPCM_drvClose
|
||||
*/
|
||||
static DWORD ADPCM_drvClose(DWORD dwDevID)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
typedef struct tagAcmAdpcmData
|
||||
{
|
||||
void (*convert)(PACMDRVSTREAMINSTANCE adsi,
|
||||
const unsigned char*, LPDWORD, unsigned char*, LPDWORD);
|
||||
/* IMA encoding only */
|
||||
BYTE stepIndexL;
|
||||
BYTE stepIndexR;
|
||||
/* short sample; */
|
||||
} AcmAdpcmData;
|
||||
|
||||
/* table to list all supported formats... those are the basic ones. this
|
||||
* also helps given a unique index to each of the supported formats
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
int nChannels;
|
||||
int nBits;
|
||||
int rate;
|
||||
} Format;
|
||||
|
||||
static Format PCM_Formats[] =
|
||||
{
|
||||
{1, 8, 8000}, {2, 8, 8000}, {1, 16, 8000}, {2, 16, 8000},
|
||||
{1, 8, 11025}, {2, 8, 11025}, {1, 16, 11025}, {2, 16, 11025},
|
||||
{1, 8, 22050}, {2, 8, 22050}, {1, 16, 22050}, {2, 16, 22050},
|
||||
{1, 8, 44100}, {2, 8, 44100}, {1, 16, 44100}, {2, 16, 44100},
|
||||
};
|
||||
|
||||
static Format ADPCM_Formats[] =
|
||||
{
|
||||
{1, 4, 8000}, {2, 4, 8000}, {1, 4, 11025}, {2, 4, 11025},
|
||||
{1, 4, 22050}, {2, 4, 22050}, {1, 4, 44100}, {2, 4, 44100},
|
||||
};
|
||||
|
||||
#define NUM_PCM_FORMATS (sizeof(PCM_Formats) / sizeof(PCM_Formats[0]))
|
||||
#define NUM_ADPCM_FORMATS (sizeof(ADPCM_Formats) / sizeof(ADPCM_Formats[0]))
|
||||
|
||||
/***********************************************************************
|
||||
* ADPCM_GetFormatIndex
|
||||
*/
|
||||
static DWORD ADPCM_GetFormatIndex(LPWAVEFORMATEX wfx)
|
||||
{
|
||||
int i, hi;
|
||||
Format* fmts;
|
||||
|
||||
switch (wfx->wFormatTag)
|
||||
{
|
||||
case WAVE_FORMAT_PCM:
|
||||
hi = NUM_PCM_FORMATS;
|
||||
fmts = PCM_Formats;
|
||||
break;
|
||||
case WAVE_FORMAT_IMA_ADPCM:
|
||||
hi = NUM_ADPCM_FORMATS;
|
||||
fmts = ADPCM_Formats;
|
||||
break;
|
||||
default:
|
||||
return 0xFFFFFFFF;
|
||||
}
|
||||
|
||||
for (i = 0; i < hi; i++)
|
||||
{
|
||||
if (wfx->nChannels == fmts[i].nChannels &&
|
||||
wfx->nSamplesPerSec == fmts[i].rate &&
|
||||
wfx->wBitsPerSample == fmts[i].nBits)
|
||||
return i;
|
||||
}
|
||||
|
||||
return 0xFFFFFFFF;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* R16
|
||||
*
|
||||
* Read a 16 bit sample (correctly handles endianess)
|
||||
*/
|
||||
static inline short R16(const unsigned char* src)
|
||||
{
|
||||
return (short)((unsigned short)src[0] | ((unsigned short)src[1] << 8));
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* W16
|
||||
*
|
||||
* Write a 16 bit sample (correctly handles endianess)
|
||||
*/
|
||||
static inline void W16(unsigned char* dst, short s)
|
||||
{
|
||||
dst[0] = LOBYTE(s);
|
||||
dst[1] = HIBYTE(s);
|
||||
}
|
||||
|
||||
/* IMA (or DVI) APDCM codec routines */
|
||||
|
||||
static const unsigned IMA_StepTable[89] =
|
||||
{
|
||||
7, 8, 9, 10, 11, 12, 13, 14,
|
||||
16, 17, 19, 21, 23, 25, 28, 31,
|
||||
34, 37, 41, 45, 50, 55, 60, 66,
|
||||
73, 80, 88, 97, 107, 118, 130, 143,
|
||||
157, 173, 190, 209, 230, 253, 279, 307,
|
||||
337, 371, 408, 449, 494, 544, 598, 658,
|
||||
724, 796, 876, 963, 1060, 1166, 1282, 1411,
|
||||
1552, 1707, 1878, 2066, 2272, 2499, 2749, 3024,
|
||||
3327, 3660, 4026, 4428, 4871, 5358, 5894, 6484,
|
||||
7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
|
||||
15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794,
|
||||
32767
|
||||
};
|
||||
|
||||
static const int IMA_IndexTable[16] =
|
||||
{
|
||||
-1, -1, -1, -1, 2, 4, 6, 8,
|
||||
-1, -1, -1, -1, 2, 4, 6, 8
|
||||
};
|
||||
|
||||
static inline void clamp_step_index(int* stepIndex)
|
||||
{
|
||||
if (*stepIndex < 0 ) *stepIndex = 0;
|
||||
if (*stepIndex > 88) *stepIndex = 88;
|
||||
}
|
||||
|
||||
static inline void clamp_sample(int* sample)
|
||||
{
|
||||
if (*sample < -32768) *sample = -32768;
|
||||
if (*sample > 32767) *sample = 32767;
|
||||
}
|
||||
|
||||
static inline void process_nibble(unsigned char code, int* stepIndex, int* sample)
|
||||
{
|
||||
unsigned step;
|
||||
int diff;
|
||||
|
||||
code &= 0x0F;
|
||||
|
||||
step = IMA_StepTable[*stepIndex];
|
||||
diff = step >> 3;
|
||||
if (code & 1) diff += step >> 2;
|
||||
if (code & 2) diff += step >> 1;
|
||||
if (code & 4) diff += step;
|
||||
if (code & 8) *sample -= diff;
|
||||
else *sample += diff;
|
||||
clamp_sample(sample);
|
||||
*stepIndex += IMA_IndexTable[code];
|
||||
clamp_step_index(stepIndex);
|
||||
}
|
||||
|
||||
static inline unsigned char generate_nibble(int in, int* stepIndex, int* sample)
|
||||
{
|
||||
int effdiff, diff = in - *sample;
|
||||
unsigned step;
|
||||
unsigned char code;
|
||||
|
||||
if (diff < 0)
|
||||
{
|
||||
diff = -diff;
|
||||
code = 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
code = 0;
|
||||
}
|
||||
|
||||
step = IMA_StepTable[*stepIndex];
|
||||
effdiff = (step >> 3);
|
||||
if (diff >= step)
|
||||
{
|
||||
code |= 4;
|
||||
diff -= step;
|
||||
effdiff += step;
|
||||
}
|
||||
step >>= 1;
|
||||
if (diff >= step)
|
||||
{
|
||||
code |= 2;
|
||||
diff -= step;
|
||||
effdiff += step;
|
||||
}
|
||||
step >>= 1;
|
||||
if (diff >= step)
|
||||
{
|
||||
code |= 1;
|
||||
effdiff += step;
|
||||
}
|
||||
if (code & 8) *sample -= effdiff;
|
||||
else *sample += effdiff;
|
||||
clamp_sample(sample);
|
||||
*stepIndex += IMA_IndexTable[code];
|
||||
clamp_step_index(stepIndex);
|
||||
return code;
|
||||
}
|
||||
|
||||
static void cvtSSima16K(PACMDRVSTREAMINSTANCE adsi,
|
||||
const unsigned char* src, LPDWORD nsrc,
|
||||
unsigned char* dst, LPDWORD ndst)
|
||||
{
|
||||
int i;
|
||||
int sampleL, sampleR;
|
||||
int stepIndexL, stepIndexR;
|
||||
int nsamp_blk = ((LPIMAADPCMWAVEFORMAT)adsi->pwfxSrc)->wSamplesPerBlock;
|
||||
int nsamp;
|
||||
/* compute the number of entire blocks we can decode...
|
||||
* it's the min of the number of entire blocks in source buffer and the number
|
||||
* of entire blocks in destination buffer
|
||||
*/
|
||||
DWORD nblock = min(*nsrc / adsi->pwfxSrc->nBlockAlign,
|
||||
*ndst / (nsamp_blk * 2 * 2));
|
||||
|
||||
*nsrc = nblock * adsi->pwfxSrc->nBlockAlign;
|
||||
*ndst = nblock * (nsamp_blk * 2 * 2);
|
||||
|
||||
nsamp_blk--; /* remove the sample in block header */
|
||||
for (; nblock > 0; nblock--)
|
||||
{
|
||||
const unsigned char* in_src = src;
|
||||
|
||||
/* handle headers first */
|
||||
sampleL = R16(src);
|
||||
stepIndexL = (unsigned)*(src + 2);
|
||||
clamp_step_index(&stepIndexL);
|
||||
src += 4;
|
||||
W16(dst, sampleL); dst += 2;
|
||||
|
||||
sampleR = R16(src);
|
||||
stepIndexR = (unsigned)*(src + 2);
|
||||
clamp_step_index(&stepIndexR);
|
||||
src += 4;
|
||||
W16(dst, sampleR); dst += 2;
|
||||
|
||||
for (nsamp = nsamp_blk; nsamp > 0; nsamp -= 8)
|
||||
{
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
process_nibble(*src, &stepIndexL, &sampleL);
|
||||
W16(dst + (2 * i + 0) * 4 + 0, sampleL);
|
||||
process_nibble(*src++ >> 4, &stepIndexL, &sampleL);
|
||||
W16(dst + (2 * i + 1) * 4 + 0, sampleL);
|
||||
}
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
process_nibble(*src , &stepIndexR, &sampleR);
|
||||
W16(dst + (2 * i + 0) * 4 + 2, sampleR);
|
||||
process_nibble(*src++ >>4, &stepIndexR, &sampleR);
|
||||
W16(dst + (2 * i + 1) * 4 + 2, sampleR);
|
||||
}
|
||||
dst += 32;
|
||||
}
|
||||
/* we have now to realign the source pointer on block */
|
||||
src = in_src + adsi->pwfxSrc->nBlockAlign;
|
||||
}
|
||||
}
|
||||
|
||||
static void cvtMMima16K(PACMDRVSTREAMINSTANCE adsi,
|
||||
const unsigned char* src, LPDWORD nsrc,
|
||||
unsigned char* dst, LPDWORD ndst)
|
||||
{
|
||||
int sample;
|
||||
int stepIndex;
|
||||
int nsamp_blk = ((LPIMAADPCMWAVEFORMAT)adsi->pwfxSrc)->wSamplesPerBlock;
|
||||
int nsamp;
|
||||
/* compute the number of entire blocks we can decode...
|
||||
* it's the min of the number of entire blocks in source buffer and the number
|
||||
* of entire blocks in destination buffer
|
||||
*/
|
||||
DWORD nblock = min(*nsrc / adsi->pwfxSrc->nBlockAlign,
|
||||
*ndst / (nsamp_blk * 2));
|
||||
|
||||
*nsrc = nblock * adsi->pwfxSrc->nBlockAlign;
|
||||
*ndst = nblock * nsamp_blk * 2;
|
||||
|
||||
nsamp_blk--; /* remove the sample in block header */
|
||||
for (; nblock > 0; nblock--)
|
||||
{
|
||||
const unsigned char* in_src = src;
|
||||
|
||||
/* handle header first */
|
||||
sample = R16(src);
|
||||
stepIndex = (unsigned)*(src + 2);
|
||||
clamp_step_index(&stepIndex);
|
||||
src += 4;
|
||||
W16(dst, sample); dst += 2;
|
||||
|
||||
for (nsamp = nsamp_blk; nsamp > 0; nsamp -= 2)
|
||||
{
|
||||
process_nibble(*src, &stepIndex, &sample);
|
||||
W16(dst, sample); dst += 2;
|
||||
process_nibble(*src++ >> 4, &stepIndex, &sample);
|
||||
W16(dst, sample); dst += 2;
|
||||
}
|
||||
/* we have now to realign the source pointer on block */
|
||||
src = in_src + adsi->pwfxSrc->nBlockAlign;
|
||||
}
|
||||
}
|
||||
|
||||
static void cvtSS16imaK(PACMDRVSTREAMINSTANCE adsi,
|
||||
const unsigned char* src, LPDWORD nsrc,
|
||||
unsigned char* dst, LPDWORD ndst)
|
||||
{
|
||||
int stepIndexL, stepIndexR;
|
||||
int sampleL, sampleR;
|
||||
BYTE code1, code2;
|
||||
int nsamp_blk = ((LPIMAADPCMWAVEFORMAT)adsi->pwfxDst)->wSamplesPerBlock;
|
||||
int i, nsamp;
|
||||
/* compute the number of entire blocks we can decode...
|
||||
* it's the min of the number of entire blocks in source buffer and the number
|
||||
* of entire blocks in destination buffer
|
||||
*/
|
||||
DWORD nblock = min(*nsrc / (nsamp_blk * 2 * 2),
|
||||
*ndst / adsi->pwfxDst->nBlockAlign);
|
||||
|
||||
*nsrc = nblock * (nsamp_blk * 2 * 2);
|
||||
*ndst = nblock * adsi->pwfxDst->nBlockAlign;
|
||||
|
||||
stepIndexL = ((AcmAdpcmData*)adsi->dwDriver)->stepIndexL;
|
||||
stepIndexR = ((AcmAdpcmData*)adsi->dwDriver)->stepIndexR;
|
||||
|
||||
nsamp_blk--; /* so that we won't count the sample in header while filling the block */
|
||||
|
||||
for (; nblock > 0; nblock--)
|
||||
{
|
||||
char* in_dst = dst;
|
||||
|
||||
/* generate header */
|
||||
sampleL = R16(src); src += 2;
|
||||
W16(dst, sampleL); dst += 2;
|
||||
*dst = (unsigned char)(unsigned)stepIndexL;
|
||||
dst += 2;
|
||||
|
||||
sampleR = R16(src); src += 2;
|
||||
W16(dst, sampleR); dst += 2;
|
||||
*dst = (unsigned char)(unsigned)stepIndexR;
|
||||
dst += 2;
|
||||
|
||||
for (nsamp = nsamp_blk; nsamp > 0; nsamp -= 8)
|
||||
{
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
code1 = generate_nibble(R16(src + (2 * i + 0) * 2 + 0),
|
||||
&stepIndexL, &sampleL);
|
||||
code2 = generate_nibble(R16(src + (2 * i + 1) * 2 + 0),
|
||||
&stepIndexL, &sampleL);
|
||||
*dst++ = (code1 << 4) | code2;
|
||||
}
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
code1 = generate_nibble(R16(src + (2 * i + 0) * 2 + 1),
|
||||
&stepIndexR, &sampleR);
|
||||
code2 = generate_nibble(R16(src + (2 * i + 1) * 2 + 1),
|
||||
&stepIndexR, &sampleR);
|
||||
*dst++ = (code1 << 4) | code2;
|
||||
}
|
||||
src += 32;
|
||||
}
|
||||
dst = in_dst + adsi->pwfxDst->nBlockAlign;
|
||||
}
|
||||
((AcmAdpcmData*)adsi->dwDriver)->stepIndexL = stepIndexL;
|
||||
((AcmAdpcmData*)adsi->dwDriver)->stepIndexR = stepIndexR;
|
||||
}
|
||||
|
||||
static void cvtMM16imaK(PACMDRVSTREAMINSTANCE adsi,
|
||||
const unsigned char* src, LPDWORD nsrc,
|
||||
unsigned char* dst, LPDWORD ndst)
|
||||
{
|
||||
int stepIndex;
|
||||
int sample;
|
||||
BYTE code1, code2;
|
||||
int nsamp_blk = ((LPIMAADPCMWAVEFORMAT)adsi->pwfxDst)->wSamplesPerBlock;
|
||||
int nsamp;
|
||||
/* compute the number of entire blocks we can decode...
|
||||
* it's the min of the number of entire blocks in source buffer and the number
|
||||
* of entire blocks in destination buffer
|
||||
*/
|
||||
DWORD nblock = min(*nsrc / (nsamp_blk * 2),
|
||||
*ndst / adsi->pwfxDst->nBlockAlign);
|
||||
|
||||
*nsrc = nblock * (nsamp_blk * 2);
|
||||
*ndst = nblock * adsi->pwfxDst->nBlockAlign;
|
||||
|
||||
stepIndex = ((AcmAdpcmData*)adsi->dwDriver)->stepIndexL;
|
||||
nsamp_blk--; /* so that we won't count the sample in header while filling the block */
|
||||
|
||||
for (; nblock > 0; nblock--)
|
||||
{
|
||||
char* in_dst = dst;
|
||||
|
||||
/* generate header */
|
||||
/* FIXME: what about the last effective sample from previous block ??? */
|
||||
/* perhaps something like:
|
||||
* sample += R16(src);
|
||||
* clamp_sample(sample);
|
||||
* and with :
|
||||
* + saving the sample in adsi->dwDriver when all blocks are done
|
||||
+ + reset should set the field in adsi->dwDriver to 0 too
|
||||
*/
|
||||
sample = R16(src); src += 2;
|
||||
W16(dst, sample); dst += 2;
|
||||
*dst = (unsigned char)(unsigned)stepIndex;
|
||||
dst += 2;
|
||||
|
||||
for (nsamp = nsamp_blk; nsamp > 0; nsamp -= 2)
|
||||
{
|
||||
code1 = generate_nibble(R16(src), &stepIndex, &sample);
|
||||
src += 2;
|
||||
code2 = generate_nibble(R16(src), &stepIndex, &sample);
|
||||
src += 2;
|
||||
*dst++ = (code1 << 4) | code2;
|
||||
}
|
||||
dst = in_dst + adsi->pwfxDst->nBlockAlign;
|
||||
}
|
||||
((AcmAdpcmData*)adsi->dwDriver)->stepIndexL = stepIndex;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* ADPCM_DriverDetails
|
||||
*
|
||||
*/
|
||||
static LRESULT ADPCM_DriverDetails(PACMDRIVERDETAILSW add)
|
||||
{
|
||||
add->fccType = ACMDRIVERDETAILS_FCCTYPE_AUDIOCODEC;
|
||||
add->fccComp = ACMDRIVERDETAILS_FCCCOMP_UNDEFINED;
|
||||
add->wMid = 0xFF;
|
||||
add->wPid = 0x00;
|
||||
add->vdwACM = 0x01000000;
|
||||
add->vdwDriver = 0x01000000;
|
||||
add->fdwSupport = ACMDRIVERDETAILS_SUPPORTF_CODEC;
|
||||
add->cFormatTags = 2; /* PCM, IMA ADPCM */
|
||||
add->cFilterTags = 0;
|
||||
add->hicon = NULL;
|
||||
MultiByteToWideChar( CP_ACP, 0, "WINE-ADPCM", -1,
|
||||
add->szShortName, sizeof(add->szShortName)/sizeof(WCHAR) );
|
||||
MultiByteToWideChar( CP_ACP, 0, "Wine IMA ADPCM converter", -1,
|
||||
add->szLongName, sizeof(add->szLongName)/sizeof(WCHAR) );
|
||||
MultiByteToWideChar( CP_ACP, 0, "Brought to you by the Wine team...", -1,
|
||||
add->szCopyright, sizeof(add->szCopyright)/sizeof(WCHAR) );
|
||||
MultiByteToWideChar( CP_ACP, 0, "Refer to LICENSE file", -1,
|
||||
add->szLicensing, sizeof(add->szLicensing)/sizeof(WCHAR) );
|
||||
add->szFeatures[0] = 0;
|
||||
|
||||
return MMSYSERR_NOERROR;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* ADPCM_FormatTagDetails
|
||||
*
|
||||
*/
|
||||
static LRESULT ADPCM_FormatTagDetails(PACMFORMATTAGDETAILSW aftd, DWORD dwQuery)
|
||||
{
|
||||
static WCHAR szPcm[]={'P','C','M',0};
|
||||
static WCHAR szImaAdPcm[]={'I','M','A',' ','A','d','P','C','M',0};
|
||||
|
||||
switch (dwQuery)
|
||||
{
|
||||
case ACM_FORMATTAGDETAILSF_INDEX:
|
||||
if (aftd->dwFormatTagIndex >= 2) return ACMERR_NOTPOSSIBLE;
|
||||
break;
|
||||
case ACM_FORMATTAGDETAILSF_LARGESTSIZE:
|
||||
if (aftd->dwFormatTag == WAVE_FORMAT_UNKNOWN)
|
||||
{
|
||||
aftd->dwFormatTagIndex = 1; /* WAVE_FORMAT_IMA_ADPCM is bigger than PCM */
|
||||
break;
|
||||
}
|
||||
/* fall thru */
|
||||
case ACM_FORMATTAGDETAILSF_FORMATTAG:
|
||||
switch (aftd->dwFormatTag)
|
||||
{
|
||||
case WAVE_FORMAT_PCM: aftd->dwFormatTagIndex = 0; break;
|
||||
case WAVE_FORMAT_IMA_ADPCM: aftd->dwFormatTagIndex = 1; break;
|
||||
default: return ACMERR_NOTPOSSIBLE;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
WARN("Unsupported query %08lx\n", dwQuery);
|
||||
return MMSYSERR_NOTSUPPORTED;
|
||||
}
|
||||
|
||||
aftd->fdwSupport = ACMDRIVERDETAILS_SUPPORTF_CODEC;
|
||||
switch (aftd->dwFormatTagIndex)
|
||||
{
|
||||
case 0:
|
||||
aftd->dwFormatTag = WAVE_FORMAT_PCM;
|
||||
aftd->cbFormatSize = sizeof(PCMWAVEFORMAT);
|
||||
aftd->cStandardFormats = NUM_PCM_FORMATS;
|
||||
lstrcpyW(aftd->szFormatTag, szPcm);
|
||||
break;
|
||||
case 1:
|
||||
aftd->dwFormatTag = WAVE_FORMAT_IMA_ADPCM;
|
||||
aftd->cbFormatSize = sizeof(IMAADPCMWAVEFORMAT);
|
||||
aftd->cStandardFormats = NUM_ADPCM_FORMATS;
|
||||
lstrcpyW(aftd->szFormatTag, szImaAdPcm);
|
||||
break;
|
||||
}
|
||||
return MMSYSERR_NOERROR;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* ADPCM_FormatDetails
|
||||
*
|
||||
*/
|
||||
static LRESULT ADPCM_FormatDetails(PACMFORMATDETAILSW afd, DWORD dwQuery)
|
||||
{
|
||||
switch (dwQuery)
|
||||
{
|
||||
case ACM_FORMATDETAILSF_FORMAT:
|
||||
if (ADPCM_GetFormatIndex(afd->pwfx) == 0xFFFFFFFF) return ACMERR_NOTPOSSIBLE;
|
||||
break;
|
||||
case ACM_FORMATDETAILSF_INDEX:
|
||||
afd->pwfx->wFormatTag = afd->dwFormatTag;
|
||||
switch (afd->dwFormatTag)
|
||||
{
|
||||
case WAVE_FORMAT_PCM:
|
||||
if (afd->dwFormatIndex >= NUM_PCM_FORMATS) return ACMERR_NOTPOSSIBLE;
|
||||
afd->pwfx->nChannels = PCM_Formats[afd->dwFormatIndex].nChannels;
|
||||
afd->pwfx->nSamplesPerSec = PCM_Formats[afd->dwFormatIndex].rate;
|
||||
afd->pwfx->wBitsPerSample = PCM_Formats[afd->dwFormatIndex].nBits;
|
||||
/* native MSACM uses a PCMWAVEFORMAT structure, so cbSize is not accessible
|
||||
* afd->pwfx->cbSize = 0;
|
||||
*/
|
||||
afd->pwfx->nBlockAlign =
|
||||
(afd->pwfx->nChannels * afd->pwfx->wBitsPerSample) / 8;
|
||||
afd->pwfx->nAvgBytesPerSec =
|
||||
afd->pwfx->nSamplesPerSec * afd->pwfx->nBlockAlign;
|
||||
break;
|
||||
case WAVE_FORMAT_IMA_ADPCM:
|
||||
if (afd->dwFormatIndex >= NUM_ADPCM_FORMATS) return ACMERR_NOTPOSSIBLE;
|
||||
afd->pwfx->nChannels = ADPCM_Formats[afd->dwFormatIndex].nChannels;
|
||||
afd->pwfx->nSamplesPerSec = ADPCM_Formats[afd->dwFormatIndex].rate;
|
||||
afd->pwfx->wBitsPerSample = ADPCM_Formats[afd->dwFormatIndex].nBits;
|
||||
afd->pwfx->nBlockAlign = 1024;
|
||||
/* we got 4 bits per sample */
|
||||
afd->pwfx->nAvgBytesPerSec =
|
||||
(afd->pwfx->nSamplesPerSec * 4) / 8;
|
||||
if (afd->cbwfx >= sizeof(WAVEFORMATEX))
|
||||
afd->pwfx->cbSize = sizeof(WORD);
|
||||
if (afd->cbwfx >= sizeof(IMAADPCMWAVEFORMAT))
|
||||
((IMAADPCMWAVEFORMAT*)afd->pwfx)->wSamplesPerBlock = (1024 - 4 * afd->pwfx->nChannels) * (2 / afd->pwfx->nChannels) + 1;
|
||||
break;
|
||||
default:
|
||||
WARN("Unsupported tag %08lx\n", afd->dwFormatTag);
|
||||
return MMSYSERR_INVALPARAM;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
WARN("Unsupported query %08lx\n", dwQuery);
|
||||
return MMSYSERR_NOTSUPPORTED;
|
||||
}
|
||||
afd->fdwSupport = ACMDRIVERDETAILS_SUPPORTF_CODEC;
|
||||
afd->szFormat[0] = 0; /* let MSACM format this for us... */
|
||||
|
||||
return MMSYSERR_NOERROR;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* ADPCM_FormatSuggest
|
||||
*
|
||||
*/
|
||||
static LRESULT ADPCM_FormatSuggest(PACMDRVFORMATSUGGEST adfs)
|
||||
{
|
||||
/* some tests ... */
|
||||
if (adfs->cbwfxSrc < sizeof(PCMWAVEFORMAT) ||
|
||||
adfs->cbwfxDst < sizeof(PCMWAVEFORMAT) ||
|
||||
ADPCM_GetFormatIndex(adfs->pwfxSrc) == 0xFFFFFFFF) return ACMERR_NOTPOSSIBLE;
|
||||
/* FIXME: should do those tests against the real size (according to format tag */
|
||||
|
||||
/* If no suggestion for destination, then copy source value */
|
||||
if (!(adfs->fdwSuggest & ACM_FORMATSUGGESTF_NCHANNELS))
|
||||
adfs->pwfxDst->nChannels = adfs->pwfxSrc->nChannels;
|
||||
if (!(adfs->fdwSuggest & ACM_FORMATSUGGESTF_NSAMPLESPERSEC))
|
||||
adfs->pwfxDst->nSamplesPerSec = adfs->pwfxSrc->nSamplesPerSec;
|
||||
|
||||
if (!(adfs->fdwSuggest & ACM_FORMATSUGGESTF_WBITSPERSAMPLE))
|
||||
{
|
||||
if (adfs->pwfxSrc->wFormatTag == WAVE_FORMAT_PCM)
|
||||
adfs->pwfxDst->wBitsPerSample = 4;
|
||||
else
|
||||
adfs->pwfxDst->wBitsPerSample = 16;
|
||||
}
|
||||
if (!(adfs->fdwSuggest & ACM_FORMATSUGGESTF_WFORMATTAG))
|
||||
{
|
||||
if (adfs->pwfxSrc->wFormatTag == WAVE_FORMAT_PCM)
|
||||
adfs->pwfxDst->wFormatTag = WAVE_FORMAT_IMA_ADPCM;
|
||||
else
|
||||
adfs->pwfxDst->wFormatTag = WAVE_FORMAT_PCM;
|
||||
}
|
||||
|
||||
/* check if result is ok */
|
||||
if (ADPCM_GetFormatIndex(adfs->pwfxDst) == 0xFFFFFFFF) return ACMERR_NOTPOSSIBLE;
|
||||
|
||||
/* recompute other values */
|
||||
switch (adfs->pwfxDst->wFormatTag)
|
||||
{
|
||||
case WAVE_FORMAT_PCM:
|
||||
adfs->pwfxDst->nBlockAlign = (adfs->pwfxDst->nChannels * adfs->pwfxDst->wBitsPerSample) / 8;
|
||||
adfs->pwfxDst->nAvgBytesPerSec = adfs->pwfxDst->nSamplesPerSec * adfs->pwfxDst->nBlockAlign;
|
||||
break;
|
||||
case WAVE_FORMAT_IMA_ADPCM:
|
||||
adfs->pwfxDst->nBlockAlign = 1024;
|
||||
/* FIXME: not handling header overhead */
|
||||
adfs->pwfxDst->nAvgBytesPerSec = ((adfs->pwfxDst->nSamplesPerSec * 4) / 8) * adfs->pwfxSrc->nChannels;
|
||||
((IMAADPCMWAVEFORMAT*)adfs->pwfxDst)->wSamplesPerBlock = (1024 - 4 * adfs->pwfxSrc->nChannels) * (2 / adfs->pwfxSrc->nChannels) + 1;
|
||||
TRACE("setting spb=%u\n", ((IMAADPCMWAVEFORMAT*)adfs->pwfxDst)->wSamplesPerBlock);
|
||||
break;
|
||||
default:
|
||||
FIXME("\n");
|
||||
break;
|
||||
}
|
||||
|
||||
return MMSYSERR_NOERROR;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* ADPCM_Reset
|
||||
*
|
||||
*/
|
||||
static void ADPCM_Reset(PACMDRVSTREAMINSTANCE adsi, AcmAdpcmData* aad)
|
||||
{
|
||||
aad->stepIndexL = aad->stepIndexR = 0;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* ADPCM_StreamOpen
|
||||
*
|
||||
*/
|
||||
static LRESULT ADPCM_StreamOpen(PACMDRVSTREAMINSTANCE adsi)
|
||||
{
|
||||
AcmAdpcmData* aad;
|
||||
unsigned nspb;
|
||||
|
||||
assert(!(adsi->fdwOpen & ACM_STREAMOPENF_ASYNC));
|
||||
|
||||
if (ADPCM_GetFormatIndex(adsi->pwfxSrc) == 0xFFFFFFFF ||
|
||||
ADPCM_GetFormatIndex(adsi->pwfxDst) == 0xFFFFFFFF)
|
||||
return ACMERR_NOTPOSSIBLE;
|
||||
|
||||
aad = HeapAlloc(GetProcessHeap(), 0, sizeof(AcmAdpcmData));
|
||||
if (aad == 0) return MMSYSERR_NOMEM;
|
||||
|
||||
adsi->dwDriver = (DWORD)aad;
|
||||
|
||||
if (adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_PCM &&
|
||||
adsi->pwfxDst->wFormatTag == WAVE_FORMAT_PCM)
|
||||
{
|
||||
goto theEnd;
|
||||
}
|
||||
else if (adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_IMA_ADPCM &&
|
||||
adsi->pwfxDst->wFormatTag == WAVE_FORMAT_PCM)
|
||||
{
|
||||
/* resampling or mono <=> stereo not available
|
||||
* ADPCM algo only define 16 bit per sample output
|
||||
*/
|
||||
if (adsi->pwfxSrc->nSamplesPerSec != adsi->pwfxDst->nSamplesPerSec ||
|
||||
adsi->pwfxSrc->nChannels != adsi->pwfxDst->nChannels ||
|
||||
adsi->pwfxDst->wBitsPerSample != 16)
|
||||
goto theEnd;
|
||||
|
||||
nspb = ((LPIMAADPCMWAVEFORMAT)adsi->pwfxSrc)->wSamplesPerBlock;
|
||||
TRACE("spb=%u\n", nspb);
|
||||
|
||||
/* we check that in a block, after the header, samples are present on
|
||||
* 4-sample packet pattern
|
||||
* we also check that the block alignement is bigger than the expected size
|
||||
*/
|
||||
if (((nspb - 1) & 3) != 0) goto theEnd;
|
||||
if ((((nspb - 1) / 2) + 4) * adsi->pwfxSrc->nChannels < adsi->pwfxSrc->nBlockAlign)
|
||||
goto theEnd;
|
||||
|
||||
/* adpcm decoding... */
|
||||
if (adsi->pwfxDst->wBitsPerSample == 16 && adsi->pwfxDst->nChannels == 2)
|
||||
aad->convert = cvtSSima16K;
|
||||
if (adsi->pwfxDst->wBitsPerSample == 16 && adsi->pwfxDst->nChannels == 1)
|
||||
aad->convert = cvtMMima16K;
|
||||
}
|
||||
else if (adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_PCM &&
|
||||
adsi->pwfxDst->wFormatTag == WAVE_FORMAT_IMA_ADPCM)
|
||||
{
|
||||
if (adsi->pwfxSrc->nSamplesPerSec != adsi->pwfxDst->nSamplesPerSec ||
|
||||
adsi->pwfxSrc->nChannels != adsi->pwfxDst->nChannels ||
|
||||
adsi->pwfxSrc->wBitsPerSample != 16)
|
||||
goto theEnd;
|
||||
|
||||
nspb = ((LPIMAADPCMWAVEFORMAT)adsi->pwfxDst)->wSamplesPerBlock;
|
||||
TRACE("spb=%u\n", nspb);
|
||||
|
||||
/* we check that in a block, after the header, samples are present on
|
||||
* 4-sample packet pattern
|
||||
* we also check that the block alignement is bigger than the expected size
|
||||
*/
|
||||
if (((nspb - 1) & 3) != 0) goto theEnd;
|
||||
if ((((nspb - 1) / 2) + 4) * adsi->pwfxDst->nChannels < adsi->pwfxDst->nBlockAlign)
|
||||
goto theEnd;
|
||||
|
||||
/* adpcm coding... */
|
||||
if (adsi->pwfxSrc->wBitsPerSample == 16 && adsi->pwfxSrc->nChannels == 2)
|
||||
aad->convert = cvtSS16imaK;
|
||||
if (adsi->pwfxSrc->wBitsPerSample == 16 && adsi->pwfxSrc->nChannels == 1)
|
||||
aad->convert = cvtMM16imaK;
|
||||
}
|
||||
else goto theEnd;
|
||||
ADPCM_Reset(adsi, aad);
|
||||
|
||||
return MMSYSERR_NOERROR;
|
||||
|
||||
theEnd:
|
||||
HeapFree(GetProcessHeap(), 0, aad);
|
||||
adsi->dwDriver = 0L;
|
||||
return MMSYSERR_NOTSUPPORTED;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* ADPCM_StreamClose
|
||||
*
|
||||
*/
|
||||
static LRESULT ADPCM_StreamClose(PACMDRVSTREAMINSTANCE adsi)
|
||||
{
|
||||
HeapFree(GetProcessHeap(), 0, (void*)adsi->dwDriver);
|
||||
return MMSYSERR_NOERROR;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* ADPCM_round
|
||||
*
|
||||
*/
|
||||
static inline DWORD ADPCM_round(DWORD a, DWORD b, DWORD c)
|
||||
{
|
||||
assert(a && b && c);
|
||||
/* to be sure, always return an entire number of c... */
|
||||
return ((double)a * (double)b + (double)c - 1) / (double)c;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* ADPCM_StreamSize
|
||||
*
|
||||
*/
|
||||
static LRESULT ADPCM_StreamSize(PACMDRVSTREAMINSTANCE adsi, PACMDRVSTREAMSIZE adss)
|
||||
{
|
||||
switch (adss->fdwSize)
|
||||
{
|
||||
case ACM_STREAMSIZEF_DESTINATION:
|
||||
/* cbDstLength => cbSrcLength */
|
||||
if (adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_PCM &&
|
||||
adsi->pwfxDst->wFormatTag == WAVE_FORMAT_IMA_ADPCM)
|
||||
{
|
||||
/* don't take block overhead into account, doesn't matter too much */
|
||||
adss->cbSrcLength = adss->cbDstLength * 4;
|
||||
}
|
||||
else if (adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_IMA_ADPCM &&
|
||||
adsi->pwfxDst->wFormatTag == WAVE_FORMAT_PCM)
|
||||
{
|
||||
FIXME("misses the block header overhead\n");
|
||||
adss->cbSrcLength = 256 + adss->cbDstLength / 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
return MMSYSERR_NOTSUPPORTED;
|
||||
}
|
||||
break;
|
||||
case ACM_STREAMSIZEF_SOURCE:
|
||||
/* cbSrcLength => cbDstLength */
|
||||
if (adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_PCM &&
|
||||
adsi->pwfxDst->wFormatTag == WAVE_FORMAT_IMA_ADPCM)
|
||||
{
|
||||
FIXME("misses the block header overhead\n");
|
||||
adss->cbDstLength = 256 + adss->cbSrcLength / 4;
|
||||
}
|
||||
else if (adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_IMA_ADPCM &&
|
||||
adsi->pwfxDst->wFormatTag == WAVE_FORMAT_PCM)
|
||||
{
|
||||
/* don't take block overhead into account, doesn't matter too much */
|
||||
adss->cbDstLength = adss->cbSrcLength * 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
return MMSYSERR_NOTSUPPORTED;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
WARN("Unsupported query %08lx\n", adss->fdwSize);
|
||||
return MMSYSERR_NOTSUPPORTED;
|
||||
}
|
||||
return MMSYSERR_NOERROR;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* ADPCM_StreamConvert
|
||||
*
|
||||
*/
|
||||
static LRESULT ADPCM_StreamConvert(PACMDRVSTREAMINSTANCE adsi, PACMDRVSTREAMHEADER adsh)
|
||||
{
|
||||
AcmAdpcmData* aad = (AcmAdpcmData*)adsi->dwDriver;
|
||||
DWORD nsrc = adsh->cbSrcLength;
|
||||
DWORD ndst = adsh->cbDstLength;
|
||||
|
||||
if (adsh->fdwConvert &
|
||||
~(ACM_STREAMCONVERTF_BLOCKALIGN|
|
||||
ACM_STREAMCONVERTF_END|
|
||||
ACM_STREAMCONVERTF_START))
|
||||
{
|
||||
FIXME("Unsupported fdwConvert (%08lx), ignoring it\n", adsh->fdwConvert);
|
||||
}
|
||||
/* ACM_STREAMCONVERTF_BLOCKALIGN
|
||||
* currently all conversions are block aligned, so do nothing for this flag
|
||||
* ACM_STREAMCONVERTF_END
|
||||
* no pending data, so do nothing for this flag
|
||||
*/
|
||||
if ((adsh->fdwConvert & ACM_STREAMCONVERTF_START))
|
||||
{
|
||||
ADPCM_Reset(adsi, aad);
|
||||
}
|
||||
|
||||
aad->convert(adsi, adsh->pbSrc, &nsrc, adsh->pbDst, &ndst);
|
||||
adsh->cbSrcLengthUsed = nsrc;
|
||||
adsh->cbDstLengthUsed = ndst;
|
||||
|
||||
return MMSYSERR_NOERROR;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* ADPCM_DriverProc [exported]
|
||||
*/
|
||||
LRESULT CALLBACK ADPCM_DriverProc(DWORD dwDevID, HDRVR hDriv, UINT wMsg,
|
||||
LPARAM dwParam1, LPARAM dwParam2)
|
||||
{
|
||||
TRACE("(%08lx %08lx %04x %08lx %08lx);\n",
|
||||
dwDevID, (DWORD)hDriv, wMsg, dwParam1, dwParam2);
|
||||
|
||||
switch (wMsg)
|
||||
{
|
||||
case DRV_LOAD: return 1;
|
||||
case DRV_FREE: return 1;
|
||||
case DRV_OPEN: return ADPCM_drvOpen((LPSTR)dwParam1);
|
||||
case DRV_CLOSE: return ADPCM_drvClose(dwDevID);
|
||||
case DRV_ENABLE: return 1;
|
||||
case DRV_DISABLE: return 1;
|
||||
case DRV_QUERYCONFIGURE: return 1;
|
||||
case DRV_CONFIGURE: MessageBoxA(0, "MSACM IMA ADPCM filter !", "Wine Driver", MB_OK); return 1;
|
||||
case DRV_INSTALL: return DRVCNF_RESTART;
|
||||
case DRV_REMOVE: return DRVCNF_RESTART;
|
||||
|
||||
case ACMDM_DRIVER_NOTIFY:
|
||||
/* no caching from other ACM drivers is done so far */
|
||||
return MMSYSERR_NOERROR;
|
||||
|
||||
case ACMDM_DRIVER_DETAILS:
|
||||
return ADPCM_DriverDetails((PACMDRIVERDETAILSW)dwParam1);
|
||||
|
||||
case ACMDM_FORMATTAG_DETAILS:
|
||||
return ADPCM_FormatTagDetails((PACMFORMATTAGDETAILSW)dwParam1, dwParam2);
|
||||
|
||||
case ACMDM_FORMAT_DETAILS:
|
||||
return ADPCM_FormatDetails((PACMFORMATDETAILSW)dwParam1, dwParam2);
|
||||
|
||||
case ACMDM_FORMAT_SUGGEST:
|
||||
return ADPCM_FormatSuggest((PACMDRVFORMATSUGGEST)dwParam1);
|
||||
|
||||
case ACMDM_STREAM_OPEN:
|
||||
return ADPCM_StreamOpen((PACMDRVSTREAMINSTANCE)dwParam1);
|
||||
|
||||
case ACMDM_STREAM_CLOSE:
|
||||
return ADPCM_StreamClose((PACMDRVSTREAMINSTANCE)dwParam1);
|
||||
|
||||
case ACMDM_STREAM_SIZE:
|
||||
return ADPCM_StreamSize((PACMDRVSTREAMINSTANCE)dwParam1, (PACMDRVSTREAMSIZE)dwParam2);
|
||||
|
||||
case ACMDM_STREAM_CONVERT:
|
||||
return ADPCM_StreamConvert((PACMDRVSTREAMINSTANCE)dwParam1, (PACMDRVSTREAMHEADER)dwParam2);
|
||||
|
||||
case ACMDM_HARDWARE_WAVE_CAPS_INPUT:
|
||||
case ACMDM_HARDWARE_WAVE_CAPS_OUTPUT:
|
||||
/* this converter is not a hardware driver */
|
||||
case ACMDM_FILTERTAG_DETAILS:
|
||||
case ACMDM_FILTER_DETAILS:
|
||||
/* this converter is not a filter */
|
||||
case ACMDM_STREAM_RESET:
|
||||
/* only needed for asynchronous driver... we aren't, so just say it */
|
||||
return MMSYSERR_NOTSUPPORTED;
|
||||
case ACMDM_STREAM_PREPARE:
|
||||
case ACMDM_STREAM_UNPREPARE:
|
||||
/* nothing special to do here... so don't do anything */
|
||||
return MMSYSERR_NOERROR;
|
||||
|
||||
default:
|
||||
return DefDriverProc(dwDevID, hDriv, wMsg, dwParam1, dwParam2);
|
||||
}
|
||||
return 0;
|
||||
}
|
415
reactos/lib/msacm/internal.c
Normal file
415
reactos/lib/msacm/internal.c
Normal file
|
@ -0,0 +1,415 @@
|
|||
/* -*- tab-width: 8; c-basic-offset: 4 -*- */
|
||||
|
||||
/*
|
||||
* MSACM32 library
|
||||
*
|
||||
* Copyright 1998 Patrik Stridvall
|
||||
* 1999 Eric Pouech
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "wingdi.h"
|
||||
#include "winuser.h"
|
||||
#include "winerror.h"
|
||||
#include "winreg.h"
|
||||
#include "mmsystem.h"
|
||||
#include "mmreg.h"
|
||||
#include "msacm.h"
|
||||
#include "msacmdrv.h"
|
||||
#include "wineacm.h"
|
||||
#include "wine/debug.h"
|
||||
#include "wine/unicode.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(msacm);
|
||||
|
||||
/**********************************************************************/
|
||||
|
||||
HANDLE MSACM_hHeap = NULL;
|
||||
PWINE_ACMDRIVERID MSACM_pFirstACMDriverID = NULL;
|
||||
PWINE_ACMDRIVERID MSACM_pLastACMDriverID = NULL;
|
||||
|
||||
#if 0
|
||||
/***********************************************************************
|
||||
* MSACM_DumpCache
|
||||
*/
|
||||
static void MSACM_DumpCache(PWINE_ACMDRIVERID padid)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
TRACE("cFilterTags=%lu cFormatTags=%lu fdwSupport=%08lx\n",
|
||||
padid->cFilterTags, padid->cFormatTags, padid->fdwSupport);
|
||||
for (i = 0; i < padid->cache->cFormatTags; i++) {
|
||||
TRACE("\tdwFormatTag=%lu cbwfx=%lu\n",
|
||||
padid->aFormatTag[i].dwFormatTag, padid->aFormatTag[i].cbwfx);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/***********************************************************************
|
||||
* MSACM_FindFormatTagInCache [internal]
|
||||
*
|
||||
* Returns TRUE is the format tag fmtTag is present in the cache.
|
||||
* If so, idx is set to its index.
|
||||
*/
|
||||
BOOL MSACM_FindFormatTagInCache(WINE_ACMDRIVERID* padid, DWORD fmtTag, LPDWORD idx)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i < padid->cFormatTags; i++) {
|
||||
if (padid->aFormatTag[i].dwFormatTag == fmtTag) {
|
||||
if (idx) *idx = i;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* MSACM_FillCache
|
||||
*/
|
||||
static BOOL MSACM_FillCache(PWINE_ACMDRIVERID padid)
|
||||
{
|
||||
HACMDRIVER had = 0;
|
||||
int ntag;
|
||||
ACMDRIVERDETAILSW add;
|
||||
ACMFORMATTAGDETAILSW aftd;
|
||||
|
||||
if (acmDriverOpen(&had, (HACMDRIVERID)padid, 0) != 0)
|
||||
return FALSE;
|
||||
|
||||
padid->aFormatTag = NULL;
|
||||
add.cbStruct = sizeof(add);
|
||||
if (MSACM_Message(had, ACMDM_DRIVER_DETAILS, (LPARAM)&add, 0))
|
||||
goto errCleanUp;
|
||||
|
||||
if (add.cFormatTags > 0) {
|
||||
padid->aFormatTag = HeapAlloc(MSACM_hHeap, HEAP_ZERO_MEMORY,
|
||||
add.cFormatTags * sizeof(padid->aFormatTag[0]));
|
||||
if (!padid->aFormatTag) goto errCleanUp;
|
||||
}
|
||||
|
||||
padid->cFormatTags = add.cFormatTags;
|
||||
padid->cFilterTags = add.cFilterTags;
|
||||
padid->fdwSupport = add.fdwSupport;
|
||||
|
||||
aftd.cbStruct = sizeof(aftd);
|
||||
|
||||
for (ntag = 0; ntag < add.cFormatTags; ntag++) {
|
||||
aftd.dwFormatTagIndex = ntag;
|
||||
if (MSACM_Message(had, ACMDM_FORMATTAG_DETAILS, (LPARAM)&aftd, ACM_FORMATTAGDETAILSF_INDEX)) {
|
||||
TRACE("IIOs (%s)\n", debugstr_w(padid->pszDriverAlias));
|
||||
goto errCleanUp;
|
||||
}
|
||||
padid->aFormatTag[ntag].dwFormatTag = aftd.dwFormatTag;
|
||||
padid->aFormatTag[ntag].cbwfx = aftd.cbFormatSize;
|
||||
}
|
||||
|
||||
acmDriverClose(had, 0);
|
||||
|
||||
return TRUE;
|
||||
|
||||
errCleanUp:
|
||||
if (had) acmDriverClose(had, 0);
|
||||
HeapFree(MSACM_hHeap, 0, padid->aFormatTag);
|
||||
padid->aFormatTag = NULL;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* MSACM_GetRegistryKey
|
||||
*/
|
||||
static LPWSTR MSACM_GetRegistryKey(const WINE_ACMDRIVERID* padid)
|
||||
{
|
||||
static const WCHAR baseKey[] = {'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\',
|
||||
'A','u','d','i','o','C','o','m','p','r','e','s','s','i','o','n','M','a','n','a','g','e','r','\\',
|
||||
'D','r','i','v','e','r','C','a','c','h','e','\\','\0'};
|
||||
LPWSTR ret;
|
||||
int len;
|
||||
|
||||
if (!padid->pszDriverAlias) {
|
||||
ERR("No alias needed for registry entry\n");
|
||||
return NULL;
|
||||
}
|
||||
len = strlenW(baseKey);
|
||||
ret = HeapAlloc(MSACM_hHeap, 0, (len + strlenW(padid->pszDriverAlias) + 1) * sizeof(WCHAR));
|
||||
if (!ret) return NULL;
|
||||
|
||||
strcpyW(ret, baseKey);
|
||||
strcpyW(ret + len, padid->pszDriverAlias);
|
||||
CharLowerW(ret + len);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* MSACM_ReadCache
|
||||
*/
|
||||
static BOOL MSACM_ReadCache(PWINE_ACMDRIVERID padid)
|
||||
{
|
||||
LPWSTR key = MSACM_GetRegistryKey(padid);
|
||||
HKEY hKey;
|
||||
DWORD type, size;
|
||||
|
||||
if (!key) return FALSE;
|
||||
|
||||
padid->aFormatTag = NULL;
|
||||
|
||||
if (RegCreateKeyW(HKEY_LOCAL_MACHINE, key, &hKey))
|
||||
goto errCleanUp;
|
||||
|
||||
size = sizeof(padid->cFormatTags);
|
||||
if (RegQueryValueExA(hKey, "cFormatTags", 0, &type, (void*)&padid->cFormatTags, &size))
|
||||
goto errCleanUp;
|
||||
size = sizeof(padid->cFilterTags);
|
||||
if (RegQueryValueExA(hKey, "cFilterTags", 0, &type, (void*)&padid->cFilterTags, &size))
|
||||
goto errCleanUp;
|
||||
size = sizeof(padid->fdwSupport);
|
||||
if (RegQueryValueExA(hKey, "fdwSupport", 0, &type, (void*)&padid->fdwSupport, &size))
|
||||
goto errCleanUp;
|
||||
|
||||
if (padid->cFormatTags > 0) {
|
||||
size = padid->cFormatTags * sizeof(padid->aFormatTag[0]);
|
||||
padid->aFormatTag = HeapAlloc(MSACM_hHeap, HEAP_ZERO_MEMORY, size);
|
||||
if (!padid->aFormatTag) goto errCleanUp;
|
||||
if (RegQueryValueExA(hKey, "aFormatTagCache", 0, &type, (void*)padid->aFormatTag, &size))
|
||||
goto errCleanUp;
|
||||
}
|
||||
HeapFree(MSACM_hHeap, 0, key);
|
||||
return TRUE;
|
||||
|
||||
errCleanUp:
|
||||
HeapFree(MSACM_hHeap, 0, key);
|
||||
HeapFree(MSACM_hHeap, 0, padid->aFormatTag);
|
||||
padid->aFormatTag = NULL;
|
||||
RegCloseKey(hKey);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* MSACM_WriteCache
|
||||
*/
|
||||
static BOOL MSACM_WriteCache(PWINE_ACMDRIVERID padid)
|
||||
{
|
||||
LPWSTR key = MSACM_GetRegistryKey(padid);
|
||||
HKEY hKey;
|
||||
|
||||
if (!key) return FALSE;
|
||||
|
||||
if (RegCreateKeyW(HKEY_LOCAL_MACHINE, key, &hKey))
|
||||
goto errCleanUp;
|
||||
|
||||
if (RegSetValueExA(hKey, "cFormatTags", 0, REG_DWORD, (void*)&padid->cFormatTags, sizeof(DWORD)))
|
||||
goto errCleanUp;
|
||||
if (RegSetValueExA(hKey, "cFilterTags", 0, REG_DWORD, (void*)&padid->cFilterTags, sizeof(DWORD)))
|
||||
goto errCleanUp;
|
||||
if (RegSetValueExA(hKey, "fdwSupport", 0, REG_DWORD, (void*)&padid->fdwSupport, sizeof(DWORD)))
|
||||
goto errCleanUp;
|
||||
if (RegSetValueExA(hKey, "aFormatTagCache", 0, REG_BINARY,
|
||||
(void*)padid->aFormatTag,
|
||||
padid->cFormatTags * sizeof(padid->aFormatTag[0])))
|
||||
goto errCleanUp;
|
||||
HeapFree(MSACM_hHeap, 0, key);
|
||||
return TRUE;
|
||||
|
||||
errCleanUp:
|
||||
HeapFree(MSACM_hHeap, 0, key);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* MSACM_RegisterDriver()
|
||||
*/
|
||||
PWINE_ACMDRIVERID MSACM_RegisterDriver(LPWSTR pszDriverAlias, LPWSTR pszFileName,
|
||||
HINSTANCE hinstModule)
|
||||
{
|
||||
PWINE_ACMDRIVERID padid;
|
||||
|
||||
TRACE("(%s, %s, %p)\n",
|
||||
debugstr_w(pszDriverAlias), debugstr_w(pszFileName), hinstModule);
|
||||
|
||||
padid = (PWINE_ACMDRIVERID) HeapAlloc(MSACM_hHeap, 0, sizeof(WINE_ACMDRIVERID));
|
||||
padid->obj.dwType = WINE_ACMOBJ_DRIVERID;
|
||||
padid->obj.pACMDriverID = padid;
|
||||
padid->pszDriverAlias = NULL;
|
||||
if (pszDriverAlias)
|
||||
{
|
||||
padid->pszDriverAlias = HeapAlloc( MSACM_hHeap, 0, (strlenW(pszDriverAlias)+1) * sizeof(WCHAR) );
|
||||
strcpyW( padid->pszDriverAlias, pszDriverAlias );
|
||||
}
|
||||
padid->pszFileName = NULL;
|
||||
if (pszFileName)
|
||||
{
|
||||
padid->pszFileName = HeapAlloc( MSACM_hHeap, 0, (strlenW(pszFileName)+1) * sizeof(WCHAR) );
|
||||
strcpyW( padid->pszFileName, pszFileName );
|
||||
}
|
||||
padid->hInstModule = hinstModule;
|
||||
|
||||
padid->pACMDriverList = NULL;
|
||||
padid->pNextACMDriverID = NULL;
|
||||
padid->pPrevACMDriverID = MSACM_pLastACMDriverID;
|
||||
if (MSACM_pLastACMDriverID)
|
||||
MSACM_pLastACMDriverID->pNextACMDriverID = padid;
|
||||
MSACM_pLastACMDriverID = padid;
|
||||
if (!MSACM_pFirstACMDriverID)
|
||||
MSACM_pFirstACMDriverID = padid;
|
||||
/* disable the driver if we cannot load the cache */
|
||||
if (!MSACM_ReadCache(padid) && !MSACM_FillCache(padid)) {
|
||||
WARN("Couldn't load cache for ACM driver (%s)\n", debugstr_w(pszFileName));
|
||||
MSACM_UnregisterDriver(padid);
|
||||
return NULL;
|
||||
}
|
||||
return padid;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* MSACM_RegisterAllDrivers()
|
||||
*/
|
||||
void MSACM_RegisterAllDrivers(void)
|
||||
{
|
||||
LPWSTR pszBuffer;
|
||||
DWORD dwBufferLength;
|
||||
static WCHAR msacm32[] = {'m','s','a','c','m','3','2','.','d','l','l','\0'};
|
||||
static WCHAR msacmW[] = {'M','S','A','C','M','.'};
|
||||
static WCHAR drv32[] = {'d','r','i','v','e','r','s','3','2','\0'};
|
||||
static WCHAR sys[] = {'s','y','s','t','e','m','.','i','n','i','\0'};
|
||||
|
||||
/* FIXME
|
||||
* What if the user edits system.ini while the program is running?
|
||||
* Does Windows handle that?
|
||||
*/
|
||||
if (MSACM_pFirstACMDriverID)
|
||||
return;
|
||||
|
||||
/* FIXME: Does not work! How do I determine the section length? */
|
||||
dwBufferLength = 1024;
|
||||
/* EPP GetPrivateProfileSectionA("drivers32", NULL, 0, "system.ini"); */
|
||||
|
||||
pszBuffer = (LPWSTR) HeapAlloc(MSACM_hHeap, 0, dwBufferLength * sizeof(WCHAR));
|
||||
if (GetPrivateProfileSectionW(drv32, pszBuffer, dwBufferLength, sys))
|
||||
{
|
||||
LPWSTR s = pszBuffer, s2;
|
||||
|
||||
while (*s)
|
||||
{
|
||||
CharUpperBuffW(s, 6);
|
||||
if (memcmp(s, msacmW, 6 * sizeof(WCHAR)) == 0)
|
||||
{
|
||||
s2 = s;
|
||||
while (*s2 != '\0' && *s2 != '=') s2++;
|
||||
if (*s2)
|
||||
{
|
||||
*s2 = '\0';
|
||||
MSACM_RegisterDriver(s, s2 + 1, 0);
|
||||
*s2 = '=';
|
||||
}
|
||||
}
|
||||
s += strlenW(s) + 1; /* Either next char or \0 */
|
||||
}
|
||||
}
|
||||
|
||||
HeapFree(MSACM_hHeap, 0, pszBuffer);
|
||||
|
||||
MSACM_RegisterDriver(msacm32, msacm32, 0);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* MSACM_UnregisterDriver()
|
||||
*/
|
||||
PWINE_ACMDRIVERID MSACM_UnregisterDriver(PWINE_ACMDRIVERID p)
|
||||
{
|
||||
PWINE_ACMDRIVERID pNextACMDriverID;
|
||||
|
||||
while (p->pACMDriverList)
|
||||
acmDriverClose((HACMDRIVER) p->pACMDriverList, 0);
|
||||
|
||||
if (p->pszDriverAlias)
|
||||
HeapFree(MSACM_hHeap, 0, p->pszDriverAlias);
|
||||
if (p->pszFileName)
|
||||
HeapFree(MSACM_hHeap, 0, p->pszFileName);
|
||||
HeapFree(MSACM_hHeap, 0, p->aFormatTag);
|
||||
|
||||
if (p == MSACM_pFirstACMDriverID)
|
||||
MSACM_pFirstACMDriverID = p->pNextACMDriverID;
|
||||
if (p == MSACM_pLastACMDriverID)
|
||||
MSACM_pLastACMDriverID = p->pPrevACMDriverID;
|
||||
|
||||
if (p->pPrevACMDriverID)
|
||||
p->pPrevACMDriverID->pNextACMDriverID = p->pNextACMDriverID;
|
||||
if (p->pNextACMDriverID)
|
||||
p->pNextACMDriverID->pPrevACMDriverID = p->pPrevACMDriverID;
|
||||
|
||||
pNextACMDriverID = p->pNextACMDriverID;
|
||||
|
||||
HeapFree(MSACM_hHeap, 0, p);
|
||||
|
||||
return pNextACMDriverID;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* MSACM_UnregisterAllDrivers()
|
||||
*/
|
||||
void MSACM_UnregisterAllDrivers(void)
|
||||
{
|
||||
PWINE_ACMDRIVERID p = MSACM_pFirstACMDriverID;
|
||||
|
||||
while (p) {
|
||||
MSACM_WriteCache(p);
|
||||
p = MSACM_UnregisterDriver(p);
|
||||
}
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* MSACM_GetObj()
|
||||
*/
|
||||
PWINE_ACMOBJ MSACM_GetObj(HACMOBJ hObj, DWORD type)
|
||||
{
|
||||
PWINE_ACMOBJ pao = (PWINE_ACMOBJ)hObj;
|
||||
|
||||
if (pao == NULL || IsBadReadPtr(pao, sizeof(WINE_ACMOBJ)) ||
|
||||
((type != WINE_ACMOBJ_DONTCARE) && (type != pao->dwType)))
|
||||
return NULL;
|
||||
return pao;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* MSACM_GetDriverID()
|
||||
*/
|
||||
PWINE_ACMDRIVERID MSACM_GetDriverID(HACMDRIVERID hDriverID)
|
||||
{
|
||||
return (PWINE_ACMDRIVERID)MSACM_GetObj((HACMOBJ)hDriverID, WINE_ACMOBJ_DRIVERID);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* MSACM_GetDriver()
|
||||
*/
|
||||
PWINE_ACMDRIVER MSACM_GetDriver(HACMDRIVER hDriver)
|
||||
{
|
||||
return (PWINE_ACMDRIVER)MSACM_GetObj((HACMOBJ)hDriver, WINE_ACMOBJ_DRIVER);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* MSACM_Message()
|
||||
*/
|
||||
MMRESULT MSACM_Message(HACMDRIVER had, UINT uMsg, LPARAM lParam1, LPARAM lParam2)
|
||||
{
|
||||
PWINE_ACMDRIVER pad = MSACM_GetDriver(had);
|
||||
|
||||
return pad ? SendDriverMessage(pad->hDrvr, uMsg, lParam1, lParam2) : MMSYSERR_INVALHANDLE;
|
||||
}
|
23
reactos/lib/msacm/makefile
Normal file
23
reactos/lib/msacm/makefile
Normal file
|
@ -0,0 +1,23 @@
|
|||
# $Id: makefile
|
||||
|
||||
PATH_TO_TOP = ../..
|
||||
|
||||
TARGET_TYPE = winedll
|
||||
|
||||
TARGET_NAME = msacm32
|
||||
|
||||
TARGET_BASE = 0x777c0000
|
||||
|
||||
TARGET_CFLAGS += -DYDEBUG -DUNICODE -D_UNICODE -D__USE_W32API -D__REACTOS__ -Wall -Werror
|
||||
# -D_WIN32_WINNT=0x0500
|
||||
|
||||
TARGET_SDKLIBS = ntdll.a winmm.a
|
||||
|
||||
DEP_OBJECTS = $(TARGET_OBJECTS)
|
||||
|
||||
include $(PATH_TO_TOP)/rules.mak
|
||||
|
||||
include $(TOOLS_PATH)/helper.mk
|
||||
|
||||
include $(TOOLS_PATH)/depend.mk
|
||||
|
30
reactos/lib/msacm/msacm.rc
Normal file
30
reactos/lib/msacm/msacm.rc
Normal file
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* Top level resource file for MS ACM
|
||||
*
|
||||
* Copyright 2000 Eric Pouech
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "winuser.h"
|
||||
#include "wineacm.h"
|
||||
|
||||
#include "msacm_En.rc"
|
||||
#include "msacm_Fr.rc"
|
||||
#include "msacm_It.rc"
|
||||
#include "msacm_Nl.rc"
|
||||
#include "msacm_Pt.rc"
|
40
reactos/lib/msacm/msacm.spec
Normal file
40
reactos/lib/msacm/msacm.spec
Normal file
|
@ -0,0 +1,40 @@
|
|||
1 stub WEP
|
||||
2 stub DRIVERPROC
|
||||
3 stub ___EXPORTEDSTUB
|
||||
7 pascal acmGetVersion() acmGetVersion16
|
||||
8 pascal -ret16 acmMetrics(word word ptr) acmMetrics16
|
||||
10 pascal -ret16 acmDriverEnum(ptr long long) acmDriverEnum16
|
||||
11 pascal -ret16 acmDriverDetails(word ptr long) acmDriverDetails16
|
||||
12 pascal -ret16 acmDriverAdd(ptr word long long long) acmDriverAdd16
|
||||
13 pascal -ret16 acmDriverRemove(word long) acmDriverRemove16
|
||||
14 pascal -ret16 acmDriverOpen(ptr word long) acmDriverOpen16
|
||||
15 pascal -ret16 acmDriverClose(word long) acmDriverClose16
|
||||
16 pascal acmDriverMessage(word word long long) acmDriverMessage16
|
||||
17 pascal -ret16 acmDriverID(word ptr long) acmDriverID16
|
||||
18 pascal -ret16 acmDriverPriority(word long long) acmDriverPriority16
|
||||
30 pascal -ret16 acmFormatTagDetails(word ptr long) acmFormatTagDetails16
|
||||
31 pascal -ret16 acmFormatTagEnum(word ptr ptr long long) acmFormatTagEnum16
|
||||
40 pascal -ret16 acmFormatChoose(ptr) acmFormatChoose16
|
||||
41 pascal -ret16 acmFormatDetails(word ptr long) acmFormatDetails16
|
||||
42 pascal -ret16 acmFormatEnum(word ptr ptr long long) acmFormatEnum16
|
||||
45 pascal -ret16 acmFormatSuggest(word ptr ptr long long) acmFormatSuggest16
|
||||
50 pascal -ret16 acmFilterTagDetails(word ptr long) acmFilterTagDetails16
|
||||
51 pascal -ret16 acmFilterTagEnum(word ptr ptr long long) acmFilterTagEnum16
|
||||
60 pascal -ret16 acmFilterChoose(ptr) acmFilterChoose16
|
||||
61 pascal -ret16 acmFilterDetails(word ptr long) acmFilterDetails16
|
||||
62 pascal -ret16 acmFilterEnum(word ptr ptr long long) acmFilterEnum16
|
||||
70 pascal -ret16 acmStreamOpen(ptr word ptr ptr ptr long long long) acmStreamOpen16
|
||||
71 pascal -ret16 acmStreamClose(word long) acmStreamClose16
|
||||
72 pascal -ret16 acmStreamSize(word long ptr long) acmStreamSize16
|
||||
75 pascal -ret16 acmStreamConvert(word ptr long) acmStreamConvert16
|
||||
76 pascal -ret16 acmStreamReset(word long) acmStreamReset16
|
||||
77 pascal -ret16 acmStreamPrepareHeader(word ptr long) acmStreamPrepareHeader16
|
||||
78 pascal -ret16 acmStreamUnprepareHeader(word ptr long) acmStreamUnprepareHeader16
|
||||
150 stub ACMAPPLICATIONEXIT
|
||||
175 stub ACMHUGEPAGELOCK
|
||||
176 stub ACMHUGEPAGEUNLOCK
|
||||
200 stub ACMOPENCONVERSION
|
||||
201 stub ACMCLOSECONVERSION
|
||||
202 stub ACMCONVERT
|
||||
203 stub ACMCHOOSEFORMAT
|
||||
255 pascal DllEntryPoint(long word word word long word) MSACM_DllEntryPoint
|
0
reactos/lib/msacm/msacm.spec.def
Normal file
0
reactos/lib/msacm/msacm.spec.def
Normal file
46
reactos/lib/msacm/msacm32.spec
Normal file
46
reactos/lib/msacm/msacm32.spec
Normal file
|
@ -0,0 +1,46 @@
|
|||
@ stdcall acmDriverAddA(ptr long long long long)
|
||||
@ stdcall acmDriverAddW(ptr long long long long)
|
||||
@ stdcall acmDriverClose(long long)
|
||||
@ stdcall acmDriverDetailsA(long ptr long)
|
||||
@ stdcall acmDriverDetailsW(long ptr long)
|
||||
@ stdcall acmDriverEnum(ptr long long)
|
||||
@ stdcall acmDriverID(long ptr long)
|
||||
@ stdcall acmDriverMessage(long long long long)
|
||||
@ stdcall acmDriverOpen(ptr long long)
|
||||
@ stdcall acmDriverPriority(long long long)
|
||||
@ stdcall acmDriverRemove(long long)
|
||||
@ stdcall acmFilterChooseA(ptr)
|
||||
@ stdcall acmFilterChooseW(ptr)
|
||||
@ stdcall acmFilterDetailsA(long ptr long)
|
||||
@ stdcall acmFilterDetailsW(long ptr long)
|
||||
@ stdcall acmFilterEnumA(long ptr ptr long long)
|
||||
@ stdcall acmFilterEnumW(long ptr ptr long long)
|
||||
@ stdcall acmFilterTagDetailsA(long ptr long)
|
||||
@ stdcall acmFilterTagDetailsW(long ptr long)
|
||||
@ stdcall acmFilterTagEnumA(long ptr ptr long long)
|
||||
@ stdcall acmFilterTagEnumW(long ptr ptr long long)
|
||||
@ stdcall acmFormatChooseA(ptr)
|
||||
@ stdcall acmFormatChooseW(ptr)
|
||||
@ stdcall acmFormatDetailsA(long ptr long)
|
||||
@ stdcall acmFormatDetailsW(long ptr long)
|
||||
@ stdcall acmFormatEnumA(long ptr ptr long long)
|
||||
@ stdcall acmFormatEnumW(long ptr ptr long long)
|
||||
@ stdcall acmFormatSuggest(long ptr ptr long long)
|
||||
@ stdcall acmFormatTagDetailsA(long ptr long)
|
||||
@ stdcall acmFormatTagDetailsW(long ptr long)
|
||||
@ stdcall acmFormatTagEnumA(long ptr ptr long long)
|
||||
@ stdcall acmFormatTagEnumW(long ptr ptr long long)
|
||||
@ stdcall acmGetVersion()
|
||||
@ stub acmMessage32
|
||||
@ stdcall acmMetrics(long long ptr)
|
||||
@ stdcall acmStreamClose(long long)
|
||||
@ stdcall acmStreamConvert(long ptr long)
|
||||
@ stdcall acmStreamMessage(long long long long)
|
||||
@ stdcall acmStreamOpen(ptr long ptr ptr ptr long long long)
|
||||
@ stdcall acmStreamPrepareHeader(long ptr long)
|
||||
@ stdcall acmStreamReset(long long)
|
||||
@ stdcall acmStreamSize(long long ptr long)
|
||||
@ stdcall acmStreamUnprepareHeader(long ptr long)
|
||||
|
||||
# this is wine only
|
||||
@ stdcall DriverProc(long long long long long) PCM_DriverProc
|
48
reactos/lib/msacm/msacm32.spec.def
Normal file
48
reactos/lib/msacm/msacm32.spec.def
Normal file
|
@ -0,0 +1,48 @@
|
|||
; File generated automatically from msacm32.spec; do not edit!
|
||||
|
||||
LIBRARY msacm32.dll
|
||||
|
||||
EXPORTS
|
||||
acmDriverAddA@20 @2
|
||||
acmDriverAddW@20 @3
|
||||
acmDriverClose@8 @4
|
||||
acmDriverDetailsA@12 @5
|
||||
acmDriverDetailsW@12 @6
|
||||
acmDriverEnum@12 @7
|
||||
acmDriverID@12 @8
|
||||
acmDriverMessage@16 @9
|
||||
acmDriverOpen@12 @10
|
||||
acmDriverPriority@12 @11
|
||||
acmDriverRemove@8 @12
|
||||
acmFilterChooseA@4 @13
|
||||
acmFilterChooseW@4 @14
|
||||
acmFilterDetailsA@12 @15
|
||||
acmFilterDetailsW@12 @16
|
||||
acmFilterEnumA@20 @17
|
||||
acmFilterEnumW@20 @18
|
||||
acmFilterTagDetailsA@12 @19
|
||||
acmFilterTagDetailsW@12 @20
|
||||
acmFilterTagEnumA@20 @21
|
||||
acmFilterTagEnumW@20 @22
|
||||
acmFormatChooseA@4 @23
|
||||
acmFormatChooseW@4 @24
|
||||
acmFormatDetailsA@12 @25
|
||||
acmFormatDetailsW@12 @26
|
||||
acmFormatEnumA@20 @27
|
||||
acmFormatEnumW@20 @28
|
||||
acmFormatSuggest@20 @29
|
||||
acmFormatTagDetailsA@12 @30
|
||||
acmFormatTagDetailsW@12 @31
|
||||
acmFormatTagEnumA@20 @32
|
||||
acmFormatTagEnumW@20 @33
|
||||
acmGetVersion@0 @34
|
||||
acmMetrics@12 @36
|
||||
acmStreamClose@8 @37
|
||||
acmStreamConvert@12 @38
|
||||
acmStreamMessage@16 @39
|
||||
acmStreamOpen@32 @40
|
||||
acmStreamPrepareHeader@12 @41
|
||||
acmStreamReset@8 @42
|
||||
acmStreamSize@16 @43
|
||||
acmStreamUnprepareHeader@12 @44
|
||||
DriverProc@20=PCM_DriverProc@20 @1
|
221
reactos/lib/msacm/msacm32_main.c
Normal file
221
reactos/lib/msacm/msacm32_main.c
Normal file
|
@ -0,0 +1,221 @@
|
|||
/* -*- tab-width: 8; c-basic-offset: 4 -*- */
|
||||
|
||||
/*
|
||||
* MSACM32 library
|
||||
*
|
||||
* Copyright 1998 Patrik Stridvall
|
||||
* 1999 Eric Pouech
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "winerror.h"
|
||||
#include "wine/debug.h"
|
||||
#include "mmsystem.h"
|
||||
#include "mmreg.h"
|
||||
#include "msacm.h"
|
||||
#include "msacmdrv.h"
|
||||
#include "wineacm.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(msacm);
|
||||
|
||||
/**********************************************************************/
|
||||
|
||||
HINSTANCE MSACM_hInstance32 = 0;
|
||||
|
||||
/***********************************************************************
|
||||
* DllMain (MSACM32.init)
|
||||
*/
|
||||
BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpvReserved)
|
||||
{
|
||||
TRACE("%p 0x%lx %p\n", hInstDLL, fdwReason, lpvReserved);
|
||||
|
||||
switch (fdwReason) {
|
||||
case DLL_PROCESS_ATTACH:
|
||||
DisableThreadLibraryCalls(hInstDLL);
|
||||
MSACM_hHeap = HeapCreate(0, 0x10000, 0);
|
||||
MSACM_hInstance32 = hInstDLL;
|
||||
MSACM_RegisterAllDrivers();
|
||||
break;
|
||||
case DLL_PROCESS_DETACH:
|
||||
MSACM_UnregisterAllDrivers();
|
||||
HeapDestroy(MSACM_hHeap);
|
||||
MSACM_hHeap = NULL;
|
||||
MSACM_hInstance32 = NULL;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* XRegThunkEntry (MSACM32.1)
|
||||
* FIXME
|
||||
* No documentation found.
|
||||
*/
|
||||
|
||||
/***********************************************************************
|
||||
* acmGetVersion (MSACM32.@)
|
||||
*/
|
||||
DWORD WINAPI acmGetVersion(void)
|
||||
{
|
||||
OSVERSIONINFOA version;
|
||||
|
||||
version.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA);
|
||||
if (!GetVersionExA( &version ))
|
||||
return 0x04030000;
|
||||
|
||||
switch (version.dwPlatformId) {
|
||||
case VER_PLATFORM_WIN32_NT:
|
||||
return 0x04000565; /* 4.0.1381 */
|
||||
default:
|
||||
FIXME("%lx not supported\n", version.dwPlatformId);
|
||||
case VER_PLATFORM_WIN32_WINDOWS:
|
||||
return 0x04030000; /* 4.3.0 */
|
||||
}
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* acmMessage32 (MSACM32.35)
|
||||
* FIXME
|
||||
* No documentation found.
|
||||
*/
|
||||
|
||||
/***********************************************************************
|
||||
* acmMetrics (MSACM32.@)
|
||||
*/
|
||||
MMRESULT WINAPI acmMetrics(HACMOBJ hao, UINT uMetric, LPVOID pMetric)
|
||||
{
|
||||
PWINE_ACMOBJ pao = MSACM_GetObj(hao, WINE_ACMOBJ_DONTCARE);
|
||||
BOOL bLocal = TRUE;
|
||||
PWINE_ACMDRIVERID padid;
|
||||
DWORD val = 0;
|
||||
int i;
|
||||
MMRESULT mmr = MMSYSERR_NOERROR;
|
||||
|
||||
TRACE("(%p, %d, %p);\n", hao, uMetric, pMetric);
|
||||
|
||||
#define CheckLocal(padid) (!bLocal || ((padid)->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_LOCAL))
|
||||
|
||||
switch (uMetric) {
|
||||
case ACM_METRIC_COUNT_DRIVERS:
|
||||
bLocal = FALSE;
|
||||
/* fall through */
|
||||
case ACM_METRIC_COUNT_LOCAL_DRIVERS:
|
||||
if (hao) return MMSYSERR_INVALHANDLE;
|
||||
for (padid = MSACM_pFirstACMDriverID; padid; padid = padid->pNextACMDriverID)
|
||||
if (!(padid->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_DISABLED) && CheckLocal(padid))
|
||||
val++;
|
||||
*(LPDWORD)pMetric = val;
|
||||
break;
|
||||
|
||||
case ACM_METRIC_COUNT_CODECS:
|
||||
bLocal = FALSE;
|
||||
/* fall through */
|
||||
case ACM_METRIC_COUNT_LOCAL_CODECS:
|
||||
if (hao) return MMSYSERR_INVALHANDLE;
|
||||
for (padid = MSACM_pFirstACMDriverID; padid; padid = padid->pNextACMDriverID)
|
||||
if (!(padid->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_DISABLED) &&
|
||||
(padid->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_CODEC) &&
|
||||
CheckLocal(padid))
|
||||
val++;
|
||||
*(LPDWORD)pMetric = val;
|
||||
break;
|
||||
|
||||
case ACM_METRIC_COUNT_CONVERTERS:
|
||||
bLocal = FALSE;
|
||||
/* fall through */
|
||||
case ACM_METRIC_COUNT_LOCAL_CONVERTERS:
|
||||
if (hao) return MMSYSERR_INVALHANDLE;
|
||||
for (padid = MSACM_pFirstACMDriverID; padid; padid = padid->pNextACMDriverID)
|
||||
if (!(padid->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_DISABLED) &&
|
||||
(padid->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_CONVERTER) &&
|
||||
CheckLocal(padid))
|
||||
val++;
|
||||
*(LPDWORD)pMetric = val;
|
||||
break;
|
||||
|
||||
case ACM_METRIC_COUNT_FILTERS:
|
||||
bLocal = FALSE;
|
||||
/* fall through */
|
||||
case ACM_METRIC_COUNT_LOCAL_FILTERS:
|
||||
if (hao) return MMSYSERR_INVALHANDLE;
|
||||
for (padid = MSACM_pFirstACMDriverID; padid; padid = padid->pNextACMDriverID)
|
||||
if (!(padid->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_DISABLED) &&
|
||||
(padid->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_FILTER) &&
|
||||
CheckLocal(padid))
|
||||
val++;
|
||||
*(LPDWORD)pMetric = val;
|
||||
break;
|
||||
|
||||
case ACM_METRIC_COUNT_DISABLED:
|
||||
bLocal = FALSE;
|
||||
/* fall through */
|
||||
case ACM_METRIC_COUNT_LOCAL_DISABLED:
|
||||
if (hao) return MMSYSERR_INVALHANDLE;
|
||||
for (padid = MSACM_pFirstACMDriverID; padid; padid = padid->pNextACMDriverID)
|
||||
if ((padid->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_DISABLED) && CheckLocal(padid))
|
||||
val++;
|
||||
*(LPDWORD)pMetric = val;
|
||||
break;
|
||||
|
||||
case ACM_METRIC_MAX_SIZE_FORMAT:
|
||||
if (hao == NULL) {
|
||||
for (padid = MSACM_pFirstACMDriverID; padid; padid = padid->pNextACMDriverID) {
|
||||
if (!(padid->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_DISABLED)) {
|
||||
for (i = 0; i < padid->cFormatTags; i++) {
|
||||
if (val < padid->aFormatTag[i].cbwfx)
|
||||
val = padid->aFormatTag[i].cbwfx;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (pao != NULL) {
|
||||
switch (pao->dwType) {
|
||||
case WINE_ACMOBJ_DRIVER:
|
||||
case WINE_ACMOBJ_DRIVERID:
|
||||
padid = pao->pACMDriverID;
|
||||
break;
|
||||
default:
|
||||
return MMSYSERR_INVALHANDLE;
|
||||
}
|
||||
if (!(padid->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_DISABLED)) {
|
||||
for (i = 0; i < padid->cFormatTags; i++) {
|
||||
if (val < padid->aFormatTag[i].cbwfx)
|
||||
val = padid->aFormatTag[i].cbwfx;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return MMSYSERR_INVALHANDLE;
|
||||
}
|
||||
*(LPDWORD)pMetric = val;
|
||||
break;
|
||||
|
||||
case ACM_METRIC_COUNT_HARDWARE:
|
||||
case ACM_METRIC_HARDWARE_WAVE_INPUT:
|
||||
case ACM_METRIC_HARDWARE_WAVE_OUTPUT:
|
||||
case ACM_METRIC_MAX_SIZE_FILTER:
|
||||
case ACM_METRIC_DRIVER_SUPPORT:
|
||||
case ACM_METRIC_DRIVER_PRIORITY:
|
||||
default:
|
||||
FIXME("(%p, %d, %p): stub\n", hao, uMetric, pMetric);
|
||||
mmr = MMSYSERR_NOTSUPPORTED;
|
||||
}
|
||||
return mmr;
|
||||
}
|
56
reactos/lib/msacm/msacm_En.rc
Normal file
56
reactos/lib/msacm/msacm_En.rc
Normal file
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* English resource file for MS ACM
|
||||
*
|
||||
* Copyright 2000 Eric Pouech
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
LANGUAGE LANG_ENGLISH, SUBLANG_DEFAULT
|
||||
|
||||
DLG_ACMFORMATCHOOSE_ID DIALOG DISCARDABLE 10, 20, 225, 100
|
||||
STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
|
||||
CAPTION "Sound Selection"
|
||||
FONT 8, "MS Shell Dlg"
|
||||
BEGIN
|
||||
|
||||
LTEXT "&Name:", -1, 5, 5, 115, 8, NOT WS_GROUP
|
||||
|
||||
COMBOBOX IDD_ACMFORMATCHOOSE_CMB_CUSTOM, 5, 15, 115, 60,
|
||||
CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP
|
||||
|
||||
PUSHBUTTON "&Save As...", IDD_ACMFORMATCHOOSE_BTN_SETNAME, 125, 14, 45, 14
|
||||
PUSHBUTTON "&Remove", IDD_ACMFORMATCHOOSE_BTN_DELNAME, 175, 14, 45, 14
|
||||
|
||||
LTEXT "&Format:", -1, 5, 41, 44, 8, NOT WS_GROUP
|
||||
|
||||
COMBOBOX IDD_ACMFORMATCHOOSE_CMB_FORMATTAG, 50, 39, 170, 60,
|
||||
CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP
|
||||
|
||||
LTEXT "&Attributes:", -1, 5, 59, 44, 8, NOT WS_GROUP
|
||||
|
||||
#if 0
|
||||
COMBOBOX IDD_ACMFORMATCHOOSE_CMB_FORMAT, 50, 57, 170, 60,
|
||||
CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP |
|
||||
CBS_OWNERDRAWFIXED | CBS_HASSTRINGS
|
||||
#else
|
||||
COMBOBOX IDD_ACMFORMATCHOOSE_CMB_FORMAT, 50, 57, 170, 60,
|
||||
CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
|
||||
#endif
|
||||
DEFPUSHBUTTON "OK", IDOK, 48, 80, 40, 14
|
||||
PUSHBUTTON "Cancel", IDCANCEL, 92, 80, 40, 14
|
||||
PUSHBUTTON "&Help", IDD_ACMFORMATCHOOSE_BTN_HELP, 136, 80, 40, 14
|
||||
|
||||
END
|
57
reactos/lib/msacm/msacm_Fr.rc
Normal file
57
reactos/lib/msacm/msacm_Fr.rc
Normal file
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* French resource file for MS ACM
|
||||
*
|
||||
* Copyright 2000 Eric Pouech
|
||||
* Copyright 2003 Vincent Béron
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
LANGUAGE LANG_FRENCH, SUBLANG_NEUTRAL
|
||||
|
||||
DLG_ACMFORMATCHOOSE_ID DIALOG DISCARDABLE 10, 20, 225, 100
|
||||
STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
|
||||
CAPTION "Sélection du son"
|
||||
FONT 8, "MS Shell Dlg"
|
||||
BEGIN
|
||||
|
||||
LTEXT "&Nom :", -1, 5, 5, 115, 8, NOT WS_GROUP
|
||||
|
||||
COMBOBOX IDD_ACMFORMATCHOOSE_CMB_CUSTOM, 5, 15, 115, 60,
|
||||
CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP
|
||||
|
||||
PUSHBUTTON "&Enregistrer sous...", IDD_ACMFORMATCHOOSE_BTN_SETNAME, 125, 14, 45, 14
|
||||
PUSHBUTTON "&Retirer", IDD_ACMFORMATCHOOSE_BTN_DELNAME, 175, 14, 45, 14
|
||||
|
||||
LTEXT "&Format :", -1, 5, 41, 44, 8, NOT WS_GROUP
|
||||
|
||||
COMBOBOX IDD_ACMFORMATCHOOSE_CMB_FORMATTAG, 50, 39, 170, 60,
|
||||
CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP
|
||||
|
||||
LTEXT "&Attributs :", -1, 5, 59, 44, 8, NOT WS_GROUP
|
||||
|
||||
#if 0
|
||||
COMBOBOX IDD_ACMFORMATCHOOSE_CMB_FORMAT, 50, 57, 170, 60,
|
||||
CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP |
|
||||
CBS_OWNERDRAWFIXED | CBS_HASSTRINGS
|
||||
#else
|
||||
COMBOBOX IDD_ACMFORMATCHOOSE_CMB_FORMAT, 50, 57, 170, 60,
|
||||
CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
|
||||
#endif
|
||||
DEFPUSHBUTTON "OK", IDOK, 48, 80, 40, 14
|
||||
PUSHBUTTON "Annuler", IDCANCEL, 92, 80, 40, 14
|
||||
PUSHBUTTON "&Aide", IDD_ACMFORMATCHOOSE_BTN_HELP, 136, 80, 40, 14
|
||||
|
||||
END
|
57
reactos/lib/msacm/msacm_It.rc
Normal file
57
reactos/lib/msacm/msacm_It.rc
Normal file
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* Italian resource file for MS ACM
|
||||
*
|
||||
* Copyright 2000 Eric Pouech
|
||||
* Copyright 2003 Ivan Leo Murray-Smith
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
LANGUAGE LANG_ITALIAN, SUBLANG_DEFAULT
|
||||
|
||||
DLG_ACMFORMATCHOOSE_ID DIALOG DISCARDABLE 10, 20, 225, 100
|
||||
STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
|
||||
CAPTION "Selezione dell'audio"
|
||||
FONT 8, "MS Shell Dlg"
|
||||
BEGIN
|
||||
|
||||
LTEXT "&Nome:", -1, 5, 5, 115, 8, NOT WS_GROUP
|
||||
|
||||
COMBOBOX IDD_ACMFORMATCHOOSE_CMB_CUSTOM, 5, 15, 115, 60,
|
||||
CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP
|
||||
|
||||
PUSHBUTTON "&Salva con nome...", IDD_ACMFORMATCHOOSE_BTN_SETNAME, 125, 14, 45, 14
|
||||
PUSHBUTTON "&Rimuovi", IDD_ACMFORMATCHOOSE_BTN_DELNAME, 175, 14, 45, 14
|
||||
|
||||
LTEXT "&Formato:", -1, 5, 41, 44, 8, NOT WS_GROUP
|
||||
|
||||
COMBOBOX IDD_ACMFORMATCHOOSE_CMB_FORMATTAG, 50, 39, 170, 60,
|
||||
CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP
|
||||
|
||||
LTEXT "&Attributi:", -1, 5, 59, 44, 8, NOT WS_GROUP
|
||||
|
||||
#if 0
|
||||
COMBOBOX IDD_ACMFORMATCHOOSE_CMB_FORMAT, 50, 57, 170, 60,
|
||||
CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP |
|
||||
CBS_OWNERDRAWFIXED | CBS_HASSTRINGS
|
||||
#else
|
||||
COMBOBOX IDD_ACMFORMATCHOOSE_CMB_FORMAT, 50, 57, 170, 60,
|
||||
CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
|
||||
#endif
|
||||
DEFPUSHBUTTON "OK", IDOK, 48, 80, 40, 14
|
||||
PUSHBUTTON "Anulla", IDCANCEL, 92, 80, 40, 14
|
||||
PUSHBUTTON "&Aiuto", IDD_ACMFORMATCHOOSE_BTN_HELP, 136, 80, 40, 14
|
||||
|
||||
END
|
56
reactos/lib/msacm/msacm_Nl.rc
Normal file
56
reactos/lib/msacm/msacm_Nl.rc
Normal file
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* msacm (Dutch resources)
|
||||
*
|
||||
* Copyright 2003 Hans Leidekker
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
LANGUAGE LANG_DUTCH, SUBLANG_DEFAULT
|
||||
|
||||
DLG_ACMFORMATCHOOSE_ID DIALOG DISCARDABLE 10, 20, 225, 100
|
||||
STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
|
||||
CAPTION "Geluidskeuze"
|
||||
FONT 8, "MS Shell Dlg"
|
||||
BEGIN
|
||||
|
||||
LTEXT "&Naam:", -1, 5, 5, 115, 8, NOT WS_GROUP
|
||||
|
||||
COMBOBOX IDD_ACMFORMATCHOOSE_CMB_CUSTOM, 5, 15, 115, 60,
|
||||
CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP
|
||||
|
||||
PUSHBUTTON "&Opslaan als...", IDD_ACMFORMATCHOOSE_BTN_SETNAME, 125, 14, 45, 14
|
||||
PUSHBUTTON "&Verwijderen", IDD_ACMFORMATCHOOSE_BTN_DELNAME, 175, 14, 45, 14
|
||||
|
||||
LTEXT "&Formaat:", -1, 5, 41, 44, 8, NOT WS_GROUP
|
||||
|
||||
COMBOBOX IDD_ACMFORMATCHOOSE_CMB_FORMATTAG, 50, 39, 170, 60,
|
||||
CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP
|
||||
|
||||
LTEXT "&Attributen:", -1, 5, 59, 44, 8, NOT WS_GROUP
|
||||
|
||||
#if 0
|
||||
COMBOBOX IDD_ACMFORMATCHOOSE_CMB_FORMAT, 50, 57, 170, 60,
|
||||
CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP |
|
||||
CBS_OWNERDRAWFIXED | CBS_HASSTRINGS
|
||||
#else
|
||||
COMBOBOX IDD_ACMFORMATCHOOSE_CMB_FORMAT, 50, 57, 170, 60,
|
||||
CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
|
||||
#endif
|
||||
DEFPUSHBUTTON "OK", IDOK, 48, 80, 40, 14
|
||||
PUSHBUTTON "Annuleren", IDCANCEL, 92, 80, 40, 14
|
||||
PUSHBUTTON "&Help", IDD_ACMFORMATCHOOSE_BTN_HELP, 136, 80, 40, 14
|
||||
|
||||
END
|
56
reactos/lib/msacm/msacm_Pt.rc
Normal file
56
reactos/lib/msacm/msacm_Pt.rc
Normal file
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* Portuguese resource file for MS ACM
|
||||
*
|
||||
* Copyright 2003 Marcelo Duarte
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
LANGUAGE LANG_PORTUGUESE, SUBLANG_DEFAULT
|
||||
|
||||
DLG_ACMFORMATCHOOSE_ID DIALOG DISCARDABLE 10, 20, 225, 100
|
||||
STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
|
||||
CAPTION "Seleção de som"
|
||||
FONT 8, "MS Shell Dlg"
|
||||
BEGIN
|
||||
|
||||
LTEXT "&Nome:", -1, 5, 5, 115, 8, NOT WS_GROUP
|
||||
|
||||
COMBOBOX IDD_ACMFORMATCHOOSE_CMB_CUSTOM, 5, 15, 115, 60,
|
||||
CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP
|
||||
|
||||
PUSHBUTTON "&Salvar como...", IDD_ACMFORMATCHOOSE_BTN_SETNAME, 125, 14, 45, 14
|
||||
PUSHBUTTON "&Remover", IDD_ACMFORMATCHOOSE_BTN_DELNAME, 175, 14, 45, 14
|
||||
|
||||
LTEXT "&Formato:", -1, 5, 41, 44, 8, NOT WS_GROUP
|
||||
|
||||
COMBOBOX IDD_ACMFORMATCHOOSE_CMB_FORMATTAG, 50, 39, 170, 60,
|
||||
CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP
|
||||
|
||||
LTEXT "&Atributos:", -1, 5, 59, 44, 8, NOT WS_GROUP
|
||||
|
||||
#if 0
|
||||
COMBOBOX IDD_ACMFORMATCHOOSE_CMB_FORMAT, 50, 57, 170, 60,
|
||||
CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP |
|
||||
CBS_OWNERDRAWFIXED | CBS_HASSTRINGS
|
||||
#else
|
||||
COMBOBOX IDD_ACMFORMATCHOOSE_CMB_FORMAT, 50, 57, 170, 60,
|
||||
CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
|
||||
#endif
|
||||
DEFPUSHBUTTON "OK", IDOK, 48, 80, 40, 14
|
||||
PUSHBUTTON "Cancelar", IDCANCEL, 92, 80, 40, 14
|
||||
PUSHBUTTON "Aj&uda", IDD_ACMFORMATCHOOSE_BTN_HELP, 136, 80, 40, 14
|
||||
|
||||
END
|
463
reactos/lib/msacm/msacm_main.c
Normal file
463
reactos/lib/msacm/msacm_main.c
Normal file
|
@ -0,0 +1,463 @@
|
|||
/*
|
||||
* MSACM library
|
||||
*
|
||||
* Copyright 1998 Patrik Stridvall
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "winerror.h"
|
||||
#include "mmsystem.h"
|
||||
#include "mmreg.h"
|
||||
#include "msacm.h"
|
||||
#include "msacmdrv.h"
|
||||
#include "wineacm.h"
|
||||
#include "wine/debug.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(msacm);
|
||||
|
||||
/**************************************************************************
|
||||
* DllEntryPoint (MSACM.255)
|
||||
*
|
||||
* MSACM DLL entry point
|
||||
*
|
||||
*/
|
||||
BOOL WINAPI MSACM_DllEntryPoint(DWORD fdwReason, HINSTANCE16 hinstDLL, WORD ds,
|
||||
WORD wHeapSize, DWORD dwReserved1, WORD wReserved2)
|
||||
{
|
||||
static HANDLE hndl;
|
||||
|
||||
TRACE("0x%x 0x%lx\n", hinstDLL, fdwReason);
|
||||
|
||||
switch (fdwReason) {
|
||||
case DLL_PROCESS_ATTACH:
|
||||
if (!hndl && !(hndl = LoadLibraryA("MSACM32.DLL"))) {
|
||||
ERR("Could not load sibling MsAcm32.dll\n");
|
||||
return FALSE;
|
||||
}
|
||||
break;
|
||||
case DLL_PROCESS_DETACH:
|
||||
FreeLibrary(hndl);
|
||||
hndl = 0;
|
||||
break;
|
||||
case DLL_THREAD_ATTACH:
|
||||
case DLL_THREAD_DETACH:
|
||||
break;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* acmGetVersion (MSACM.7)
|
||||
*/
|
||||
DWORD WINAPI acmGetVersion16(void)
|
||||
{
|
||||
return acmGetVersion();
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* acmMetrics (MSACM.8)
|
||||
*/
|
||||
|
||||
MMRESULT16 WINAPI acmMetrics16(
|
||||
HACMOBJ16 hao, UINT16 uMetric, LPVOID pMetric)
|
||||
{
|
||||
FIXME("(0x%04x, %d, %p): semi-stub\n", hao, uMetric, pMetric);
|
||||
|
||||
if(!hao) return acmMetrics(0, uMetric, pMetric);
|
||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
return MMSYSERR_ERROR;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* acmDriverEnum (MSACM.10)
|
||||
*/
|
||||
MMRESULT16 WINAPI acmDriverEnum16(
|
||||
ACMDRIVERENUMCB16 fnCallback, DWORD dwInstance, DWORD fdwEnum)
|
||||
{
|
||||
FIXME("(%p, %ld, %ld): stub\n",
|
||||
fnCallback, dwInstance, fdwEnum
|
||||
);
|
||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
return MMSYSERR_ERROR;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* acmDriverDetails (MSACM.11)
|
||||
*/
|
||||
|
||||
MMRESULT16 WINAPI acmDriverDetails16(
|
||||
HACMDRIVERID16 hadid, LPACMDRIVERDETAILS16 padd, DWORD fdwDetails)
|
||||
{
|
||||
FIXME("(0x%04x, %p, %ld): stub\n", hadid, padd, fdwDetails);
|
||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
return MMSYSERR_ERROR;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* acmDriverAdd (MSACM.12)
|
||||
*/
|
||||
MMRESULT16 WINAPI acmDriverAdd16(
|
||||
LPHACMDRIVERID16 phadid, HINSTANCE16 hinstModule,
|
||||
LPARAM lParam, DWORD dwPriority, DWORD fdwAdd)
|
||||
{
|
||||
FIXME("(%p, 0x%04x, %ld, %ld, %ld): stub\n",
|
||||
phadid, hinstModule, lParam, dwPriority, fdwAdd
|
||||
);
|
||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
return MMSYSERR_ERROR;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* acmDriverRemove (MSACM.13)
|
||||
*/
|
||||
MMRESULT16 WINAPI acmDriverRemove16(
|
||||
HACMDRIVERID16 hadid, DWORD fdwRemove)
|
||||
{
|
||||
FIXME("(0x%04x, %ld): stub\n", hadid, fdwRemove);
|
||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
return MMSYSERR_ERROR;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* acmDriverOpen (MSACM.14)
|
||||
*/
|
||||
MMRESULT16 WINAPI acmDriverOpen16(
|
||||
LPHACMDRIVER16 phad, HACMDRIVERID16 hadid, DWORD fdwOpen)
|
||||
{
|
||||
FIXME("(%p, 0x%04x, %ld): stub\n", phad, hadid, fdwOpen);
|
||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
return MMSYSERR_ERROR;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* acmDriverClose (MSACM.15)
|
||||
*/
|
||||
MMRESULT16 WINAPI acmDriverClose16(
|
||||
HACMDRIVER16 had, DWORD fdwClose)
|
||||
{
|
||||
FIXME("(0x%04x, %ld): stub\n", had, fdwClose);
|
||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
return MMSYSERR_ERROR;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* acmDriverMessage (MSACM.16)
|
||||
*/
|
||||
LRESULT WINAPI acmDriverMessage16(
|
||||
HACMDRIVER16 had, UINT16 uMsg, LPARAM lParam1, LPARAM lParam2)
|
||||
{
|
||||
FIXME("(0x%04x, %d, %ld, %ld): stub\n",
|
||||
had, uMsg, lParam1, lParam2
|
||||
);
|
||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* acmDriverID (MSACM.17)
|
||||
*/
|
||||
MMRESULT16 WINAPI acmDriverID16(
|
||||
HACMOBJ16 hao, LPHACMDRIVERID16 phadid, DWORD fdwDriverID)
|
||||
{
|
||||
FIXME("(0x%04x, %p, %ld): stub\n", hao, phadid, fdwDriverID);
|
||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
return MMSYSERR_ERROR;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* acmDriverPriority (MSACM.18)
|
||||
*/
|
||||
MMRESULT16 WINAPI acmDriverPriority16(
|
||||
HACMDRIVERID16 hadid, DWORD dwPriority, DWORD fdwPriority)
|
||||
{
|
||||
FIXME("(0x%04x, %ld, %ld): stub\n",
|
||||
hadid, dwPriority, fdwPriority
|
||||
);
|
||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
return MMSYSERR_ERROR;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* acmFormatTagDetails (MSACM.30)
|
||||
*/
|
||||
MMRESULT16 WINAPI acmFormatTagDetails16(
|
||||
HACMDRIVER16 had, LPACMFORMATTAGDETAILS16 paftd, DWORD fdwDetails)
|
||||
{
|
||||
FIXME("(0x%04x, %p, %ld): stub\n", had, paftd, fdwDetails);
|
||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
return MMSYSERR_ERROR;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* acmFormatTagEnum (MSACM.31)
|
||||
*/
|
||||
MMRESULT16 WINAPI acmFormatTagEnum16(
|
||||
HACMDRIVER16 had, LPACMFORMATTAGDETAILS16 paftd,
|
||||
ACMFORMATTAGENUMCB16 fnCallback, DWORD dwInstance, DWORD fdwEnum)
|
||||
{
|
||||
FIXME("(0x%04x, %p, %p, %ld, %ld): stub\n",
|
||||
had, paftd, fnCallback, dwInstance, fdwEnum
|
||||
);
|
||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
return MMSYSERR_ERROR;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* acmFormatChoose (MSACM.40)
|
||||
*/
|
||||
MMRESULT16 WINAPI acmFormatChoose16(
|
||||
LPACMFORMATCHOOSE16 pafmtc)
|
||||
{
|
||||
FIXME("(%p): stub\n", pafmtc);
|
||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
return MMSYSERR_ERROR;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* acmFormatDetails (MSACM.41)
|
||||
*/
|
||||
MMRESULT16 WINAPI acmFormatDetails16(
|
||||
HACMDRIVER16 had, LPACMFORMATDETAILS16 pafd, DWORD fdwDetails)
|
||||
{
|
||||
FIXME("(0x%04x, %p, %ld): stub\n", had, pafd, fdwDetails);
|
||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
return MMSYSERR_ERROR;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* acmFormatEnum (MSACM.42)
|
||||
*/
|
||||
MMRESULT16 WINAPI acmFormatEnum16(
|
||||
HACMDRIVER16 had, LPACMFORMATDETAILS16 pafd,
|
||||
ACMFORMATENUMCB16 fnCallback, DWORD dwInstance, DWORD fdwEnum)
|
||||
{
|
||||
FIXME("(0x%04x, %p, %p, %ld, %ld): stub\n",
|
||||
had, pafd, fnCallback, dwInstance, fdwEnum
|
||||
);
|
||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
return MMSYSERR_ERROR;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* acmFormatSuggest (MSACM.45)
|
||||
*/
|
||||
MMRESULT16 WINAPI acmFormatSuggest16(
|
||||
HACMDRIVER16 had, LPWAVEFORMATEX pwfxSrc,
|
||||
LPWAVEFORMATEX pwfxDst, DWORD cbwfxDst, DWORD fdwSuggest)
|
||||
{
|
||||
FIXME("(0x%04x, %p, %p, %ld, %ld): stub\n",
|
||||
had, pwfxSrc, pwfxDst, cbwfxDst, fdwSuggest
|
||||
);
|
||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
return MMSYSERR_ERROR;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* acmFilterTagDetails (MSACM.50)
|
||||
*/
|
||||
MMRESULT16 WINAPI acmFilterTagDetails16(
|
||||
HACMDRIVER16 had, LPACMFILTERTAGDETAILS16 paftd, DWORD fdwDetails)
|
||||
{
|
||||
FIXME("(0x%04x, %p, %ld): stub\n", had, paftd, fdwDetails);
|
||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
return MMSYSERR_ERROR;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* acmFilterTagEnum (MSACM.51)
|
||||
*/
|
||||
MMRESULT16 WINAPI acmFilterTagEnum16(
|
||||
HACMDRIVER16 had, LPACMFILTERTAGDETAILS16 paftd,
|
||||
ACMFILTERTAGENUMCB16 fnCallback, DWORD dwInstance, DWORD fdwEnum)
|
||||
{
|
||||
FIXME("(0x%04x, %p, %p, %ld, %ld): stub\n",
|
||||
had, paftd, fnCallback, dwInstance, fdwEnum
|
||||
);
|
||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
return MMSYSERR_ERROR;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* acmFilterChoose (MSACM.60)
|
||||
*/
|
||||
MMRESULT16 WINAPI acmFilterChoose16(
|
||||
LPACMFILTERCHOOSE16 pafltrc)
|
||||
{
|
||||
FIXME("(%p): stub\n", pafltrc);
|
||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
return MMSYSERR_ERROR;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* acmFilterDetails (MSACM.61)
|
||||
*/
|
||||
MMRESULT16 WINAPI acmFilterDetails16(
|
||||
HACMDRIVER16 had, LPACMFILTERDETAILS16 pafd, DWORD fdwDetails)
|
||||
{
|
||||
FIXME("(0x%04x, %p, %ld): stub\n", had, pafd, fdwDetails);
|
||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
return MMSYSERR_ERROR;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* acmFilterEnum (MSACM.62)
|
||||
*/
|
||||
MMRESULT16 WINAPI acmFilterEnum16(
|
||||
HACMDRIVER16 had, LPACMFILTERDETAILS16 pafd,
|
||||
ACMFILTERENUMCB16 fnCallback, DWORD dwInstance, DWORD fdwEnum)
|
||||
{
|
||||
FIXME("(0x%04x, %p, %p, %ld, %ld): stub\n",
|
||||
had, pafd, fnCallback, dwInstance, fdwEnum
|
||||
);
|
||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
return MMSYSERR_ERROR;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* acmStreamOpen (MSACM.70)
|
||||
*/
|
||||
MMRESULT16 WINAPI acmStreamOpen16(
|
||||
LPHACMSTREAM16 phas, HACMDRIVER16 had,
|
||||
LPWAVEFORMATEX pwfxSrc, LPWAVEFORMATEX pwfxDst,
|
||||
LPWAVEFILTER pwfltr, DWORD dwCallback,
|
||||
DWORD dwInstance, DWORD fdwOpen)
|
||||
{
|
||||
FIXME("(%p, 0x%04x, %p, %p, %p, %ld, %ld, %ld): stub\n",
|
||||
phas, had, pwfxSrc, pwfxDst, pwfltr,
|
||||
dwCallback, dwInstance, fdwOpen
|
||||
);
|
||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
return MMSYSERR_ERROR;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* acmStreamClose (MSACM.71)
|
||||
*/
|
||||
MMRESULT16 WINAPI acmStreamClose16(
|
||||
HACMSTREAM16 has, DWORD fdwClose)
|
||||
{
|
||||
FIXME("(0x%04x, %ld): stub\n", has, fdwClose);
|
||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
return MMSYSERR_ERROR;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* acmStreamSize (MSACM.72)
|
||||
*/
|
||||
MMRESULT16 WINAPI acmStreamSize16(
|
||||
HACMSTREAM16 has, DWORD cbInput,
|
||||
LPDWORD pdwOutputBytes, DWORD fdwSize)
|
||||
{
|
||||
FIXME("(0x%04x, %ld, %p, %ld): stub\n",
|
||||
has, cbInput, pdwOutputBytes, fdwSize
|
||||
);
|
||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
return MMSYSERR_ERROR;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* acmStreamConvert (MSACM.75)
|
||||
*/
|
||||
MMRESULT16 WINAPI acmStreamConvert16(
|
||||
HACMSTREAM16 has, LPACMSTREAMHEADER16 pash, DWORD fdwConvert)
|
||||
{
|
||||
FIXME("(0x%04x, %p, %ld): stub\n", has, pash, fdwConvert);
|
||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
return MMSYSERR_ERROR;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* acmStreamReset (MSACM.76)
|
||||
*/
|
||||
MMRESULT16 WINAPI acmStreamReset16(
|
||||
HACMSTREAM16 has, DWORD fdwReset)
|
||||
{
|
||||
FIXME("(0x%04x, %ld): stub\n", has, fdwReset);
|
||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
return MMSYSERR_ERROR;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* acmStreamPrepareHeader (MSACM.77)
|
||||
*/
|
||||
MMRESULT16 WINAPI acmStreamPrepareHeader16(
|
||||
HACMSTREAM16 has, LPACMSTREAMHEADER16 pash, DWORD fdwPrepare)
|
||||
{
|
||||
FIXME("(0x%04x, %p, %ld): stub\n", has, pash, fdwPrepare);
|
||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
return MMSYSERR_ERROR;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* acmStreamUnprepareHeader (MSACM.78)
|
||||
*/
|
||||
MMRESULT16 WINAPI acmStreamUnprepareHeader16(
|
||||
HACMSTREAM16 has, LPACMSTREAMHEADER16 pash, DWORD fdwUnprepare)
|
||||
{
|
||||
FIXME("(0x%04x, %p, %ld): stub\n",
|
||||
has, pash, fdwUnprepare
|
||||
);
|
||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
return MMSYSERR_ERROR;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* ACMAPPLICATIONEXIT (MSACM.150)
|
||||
* FIXME
|
||||
* No documentation found.
|
||||
*/
|
||||
|
||||
/***********************************************************************
|
||||
* ACMHUGEPAGELOCK (MSACM.175)
|
||||
*FIXME
|
||||
* No documentation found.
|
||||
*/
|
||||
|
||||
/***********************************************************************
|
||||
* ACMHUGEPAGEUNLOCK (MSACM.176)
|
||||
* FIXME
|
||||
* No documentation found.
|
||||
*/
|
||||
|
||||
/***********************************************************************
|
||||
* ACMOPENCONVERSION (MSACM.200)
|
||||
* FIXME
|
||||
* No documentation found.
|
||||
*/
|
||||
|
||||
/***********************************************************************
|
||||
* ACMCLOSECONVERSION (MSACM.201)
|
||||
* FIXME
|
||||
* No documentation found.
|
||||
*/
|
||||
|
||||
/***********************************************************************
|
||||
* ACMCONVERT (MSACM.202)
|
||||
* FIXME
|
||||
* No documentation found.
|
||||
*/
|
||||
|
||||
/***********************************************************************
|
||||
* ACMCHOOSEFORMAT (MSACM.203)
|
||||
* FIXME
|
||||
* No documentation found.
|
||||
*/
|
||||
|
||||
|
3
reactos/lib/msacm/msadp32/.cvsignore
Normal file
3
reactos/lib/msacm/msadp32/.cvsignore
Normal file
|
@ -0,0 +1,3 @@
|
|||
Makefile
|
||||
msadp32.acm.dbg.c
|
||||
msadp32.acm.spec.c
|
12
reactos/lib/msacm/msadp32/Makefile.in
Normal file
12
reactos/lib/msacm/msadp32/Makefile.in
Normal file
|
@ -0,0 +1,12 @@
|
|||
TOPSRCDIR = @top_srcdir@
|
||||
TOPOBJDIR = ../../..
|
||||
SRCDIR = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
MODULE = msadp32.acm
|
||||
IMPORTS = winmm user32 kernel32
|
||||
|
||||
C_SRCS = msadp32.c
|
||||
|
||||
@MAKE_DLL_RULES@
|
||||
|
||||
### Dependencies:
|
1
reactos/lib/msacm/msadp32/msadp32.acm.spec
Normal file
1
reactos/lib/msacm/msadp32/msadp32.acm.spec
Normal file
|
@ -0,0 +1 @@
|
|||
@ stdcall DriverProc (long long long long long) ADPCM_DriverProc
|
781
reactos/lib/msacm/msadp32/msadp32.c
Normal file
781
reactos/lib/msacm/msadp32/msadp32.c
Normal file
|
@ -0,0 +1,781 @@
|
|||
/*
|
||||
* MS ADPCM handling
|
||||
*
|
||||
* Copyright (C) 2002 Eric Pouech
|
||||
*
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "wingdi.h"
|
||||
#include "winuser.h"
|
||||
#include "winnls.h"
|
||||
#include "mmsystem.h"
|
||||
#include "mmreg.h"
|
||||
#include "msacm.h"
|
||||
#include "msacmdrv.h"
|
||||
#include "wine/debug.h"
|
||||
|
||||
/* see http://www.pcisys.net/~melanson/codecs/adpcm.txt for the details */
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(adpcm);
|
||||
|
||||
/***********************************************************************
|
||||
* ADPCM_drvOpen
|
||||
*/
|
||||
static DWORD ADPCM_drvOpen(LPCSTR str)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* ADPCM_drvClose
|
||||
*/
|
||||
static DWORD ADPCM_drvClose(DWORD dwDevID)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
typedef struct tagAcmAdpcmData
|
||||
{
|
||||
void (*convert)(PACMDRVSTREAMINSTANCE adsi,
|
||||
const unsigned char*, LPDWORD, unsigned char*, LPDWORD);
|
||||
} AcmAdpcmData;
|
||||
|
||||
/* table to list all supported formats... those are the basic ones. this
|
||||
* also helps given a unique index to each of the supported formats
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
int nChannels;
|
||||
int nBits;
|
||||
int rate;
|
||||
} Format;
|
||||
|
||||
static Format PCM_Formats[] =
|
||||
{
|
||||
{1, 8, 8000}, {2, 8, 8000}, {1, 16, 8000}, {2, 16, 8000},
|
||||
{1, 8, 11025}, {2, 8, 11025}, {1, 16, 11025}, {2, 16, 11025},
|
||||
{1, 8, 22050}, {2, 8, 22050}, {1, 16, 22050}, {2, 16, 22050},
|
||||
{1, 8, 44100}, {2, 8, 44100}, {1, 16, 44100}, {2, 16, 44100},
|
||||
};
|
||||
|
||||
static Format ADPCM_Formats[] =
|
||||
{
|
||||
{1, 4, 8000}, {2, 4, 8000}, {1, 4, 11025}, {2, 4, 11025},
|
||||
{1, 4, 22050}, {2, 4, 22050}, {1, 4, 44100}, {2, 4, 44100},
|
||||
};
|
||||
|
||||
#define NUM_PCM_FORMATS (sizeof(PCM_Formats) / sizeof(PCM_Formats[0]))
|
||||
#define NUM_ADPCM_FORMATS (sizeof(ADPCM_Formats) / sizeof(ADPCM_Formats[0]))
|
||||
|
||||
static int MS_Delta[] =
|
||||
{
|
||||
230, 230, 230, 230, 307, 409, 512, 614,
|
||||
768, 614, 512, 409, 307, 230, 230, 230
|
||||
};
|
||||
|
||||
|
||||
static ADPCMCOEFSET MSADPCM_CoeffSet[] =
|
||||
{
|
||||
{256, 0}, {512, -256}, {0, 0}, {192, 64}, {240, 0}, {460, -208}, {392, -232}
|
||||
};
|
||||
|
||||
/***********************************************************************
|
||||
* ADPCM_GetFormatIndex
|
||||
*/
|
||||
static DWORD ADPCM_GetFormatIndex(WAVEFORMATEX* wfx)
|
||||
{
|
||||
int i, hi;
|
||||
Format* fmts;
|
||||
|
||||
switch (wfx->wFormatTag)
|
||||
{
|
||||
case WAVE_FORMAT_PCM:
|
||||
hi = NUM_PCM_FORMATS;
|
||||
fmts = PCM_Formats;
|
||||
break;
|
||||
case WAVE_FORMAT_ADPCM:
|
||||
hi = NUM_ADPCM_FORMATS;
|
||||
fmts = ADPCM_Formats;
|
||||
break;
|
||||
default:
|
||||
return 0xFFFFFFFF;
|
||||
}
|
||||
|
||||
for (i = 0; i < hi; i++)
|
||||
{
|
||||
if (wfx->nChannels == fmts[i].nChannels &&
|
||||
wfx->nSamplesPerSec == fmts[i].rate &&
|
||||
wfx->wBitsPerSample == fmts[i].nBits)
|
||||
return i;
|
||||
}
|
||||
|
||||
return 0xFFFFFFFF;
|
||||
}
|
||||
|
||||
static void init_wfx_adpcm(ADPCMWAVEFORMAT* awfx)
|
||||
{
|
||||
register WAVEFORMATEX* pwfx = &awfx->wfx;
|
||||
|
||||
/* we assume wFormatTag, nChannels, nSamplesPerSec and wBitsPerSample
|
||||
* have been initialized... */
|
||||
|
||||
if (pwfx->wFormatTag != WAVE_FORMAT_ADPCM) {FIXME("wrong FT\n"); return;}
|
||||
if (ADPCM_GetFormatIndex(pwfx) == 0xFFFFFFFF) {FIXME("wrong fmt\n"); return;}
|
||||
|
||||
switch (pwfx->nSamplesPerSec)
|
||||
{
|
||||
case 8000: pwfx->nBlockAlign = 256; break;
|
||||
case 11025: pwfx->nBlockAlign = 256; break;
|
||||
case 22050: pwfx->nBlockAlign = 512; break;
|
||||
default:
|
||||
case 44100: pwfx->nBlockAlign = 1024; break;
|
||||
}
|
||||
pwfx->cbSize = 2 * sizeof(WORD) + 7 * sizeof(ADPCMCOEFSET);
|
||||
/* 7 is the size of the block head (which contains two samples) */
|
||||
|
||||
awfx->wSamplesPerBlock = (pwfx->nBlockAlign - (7 * pwfx->nChannels)) * (2 / pwfx->nChannels) + 2;
|
||||
pwfx->nAvgBytesPerSec = (pwfx->nSamplesPerSec * pwfx->nBlockAlign) / awfx->wSamplesPerBlock;
|
||||
awfx->wNumCoef = 7;
|
||||
memcpy(awfx->aCoef, MSADPCM_CoeffSet, 7 * sizeof(ADPCMCOEFSET));
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* R16
|
||||
*
|
||||
* Read a 16 bit sample (correctly handles endianess)
|
||||
*/
|
||||
static inline short R16(const unsigned char* src)
|
||||
{
|
||||
return (short)((unsigned short)src[0] | ((unsigned short)src[1] << 8));
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* W16
|
||||
*
|
||||
* Write a 16 bit sample (correctly handles endianess)
|
||||
*/
|
||||
static inline void W16(unsigned char* dst, short s)
|
||||
{
|
||||
dst[0] = LOBYTE(s);
|
||||
dst[1] = HIBYTE(s);
|
||||
}
|
||||
|
||||
static inline void clamp_sample(int* sample)
|
||||
{
|
||||
if (*sample < -32768) *sample = -32768;
|
||||
if (*sample > 32767) *sample = 32767;
|
||||
}
|
||||
|
||||
static inline void process_nibble(unsigned nibble, int* idelta,
|
||||
int* sample1, int* sample2,
|
||||
const ADPCMCOEFSET* coeff)
|
||||
{
|
||||
int sample;
|
||||
int snibble;
|
||||
|
||||
/* nibble is in fact a signed 4 bit integer => propagate sign if needed */
|
||||
snibble = (nibble & 0x08) ? (nibble - 16) : nibble;
|
||||
sample = ((*sample1 * coeff->iCoef1) + (*sample2 * coeff->iCoef2)) / 256 +
|
||||
snibble * *idelta;
|
||||
clamp_sample(&sample);
|
||||
|
||||
*sample2 = *sample1;
|
||||
*sample1 = sample;
|
||||
*idelta = ((MS_Delta[nibble] * *idelta) / 256);
|
||||
if (*idelta < 16) *idelta = 16;
|
||||
}
|
||||
|
||||
static void cvtSSms16K(PACMDRVSTREAMINSTANCE adsi,
|
||||
const unsigned char* src, LPDWORD nsrc,
|
||||
unsigned char* dst, LPDWORD ndst)
|
||||
{
|
||||
int ideltaL, ideltaR;
|
||||
int sample1L, sample2L;
|
||||
int sample1R, sample2R;
|
||||
ADPCMCOEFSET coeffL, coeffR;
|
||||
int nsamp;
|
||||
int nsamp_blk = ((ADPCMWAVEFORMAT*)adsi->pwfxSrc)->wSamplesPerBlock;
|
||||
DWORD nblock = min(*nsrc / adsi->pwfxSrc->nBlockAlign,
|
||||
*ndst / (nsamp_blk * 2 * 2));
|
||||
|
||||
*nsrc = nblock * adsi->pwfxSrc->nBlockAlign;
|
||||
*ndst = nblock * nsamp_blk * 2 * 2;
|
||||
|
||||
nsamp_blk -= 2; /* see below for samples from block head */
|
||||
for (; nblock > 0; nblock--)
|
||||
{
|
||||
const unsigned char* in_src = src;
|
||||
|
||||
assert(*src <= 6);
|
||||
coeffL = MSADPCM_CoeffSet[*src++];
|
||||
assert(*src <= 6);
|
||||
coeffR = MSADPCM_CoeffSet[*src++];
|
||||
|
||||
ideltaL = R16(src); src += 2;
|
||||
ideltaR = R16(src); src += 2;
|
||||
sample1L = R16(src); src += 2;
|
||||
sample1R = R16(src); src += 2;
|
||||
sample2L = R16(src); src += 2;
|
||||
sample2R = R16(src); src += 2;
|
||||
|
||||
/* store samples from block head */
|
||||
W16(dst, sample2L); dst += 2;
|
||||
W16(dst, sample2R); dst += 2;
|
||||
W16(dst, sample1L); dst += 2;
|
||||
W16(dst, sample1R); dst += 2;
|
||||
|
||||
for (nsamp = nsamp_blk; nsamp > 0; nsamp--)
|
||||
{
|
||||
process_nibble(*src >> 4, &ideltaL, &sample1L, &sample2L, &coeffL);
|
||||
W16(dst, sample1L); dst += 2;
|
||||
process_nibble(*src++ & 0x0F, &ideltaR, &sample1R, &sample2R, &coeffR);
|
||||
W16(dst, sample1R); dst += 2;
|
||||
}
|
||||
src = in_src + adsi->pwfxSrc->nBlockAlign;
|
||||
}
|
||||
}
|
||||
|
||||
static void cvtMMms16K(PACMDRVSTREAMINSTANCE adsi,
|
||||
const unsigned char* src, LPDWORD nsrc,
|
||||
unsigned char* dst, LPDWORD ndst)
|
||||
{
|
||||
int idelta;
|
||||
int sample1, sample2;
|
||||
ADPCMCOEFSET coeff;
|
||||
int nsamp;
|
||||
int nsamp_blk = ((ADPCMWAVEFORMAT*)adsi->pwfxSrc)->wSamplesPerBlock;
|
||||
DWORD nblock = min(*nsrc / adsi->pwfxSrc->nBlockAlign,
|
||||
*ndst / (nsamp_blk * 2));
|
||||
|
||||
*nsrc = nblock * adsi->pwfxSrc->nBlockAlign;
|
||||
*ndst = nblock * nsamp_blk * 2;
|
||||
|
||||
nsamp_blk -= 2; /* see below for samples from block head */
|
||||
for (; nblock > 0; nblock--)
|
||||
{
|
||||
const unsigned char* in_src = src;
|
||||
|
||||
assert(*src <= 6);
|
||||
coeff = MSADPCM_CoeffSet[*src++];
|
||||
|
||||
idelta = R16(src); src += 2;
|
||||
sample1 = R16(src); src += 2;
|
||||
sample2 = R16(src); src += 2;
|
||||
|
||||
/* store samples from block head */
|
||||
W16(dst, sample2); dst += 2;
|
||||
W16(dst, sample1); dst += 2;
|
||||
|
||||
for (nsamp = nsamp_blk; nsamp > 0; nsamp -= 2)
|
||||
{
|
||||
process_nibble(*src >> 4, &idelta, &sample1, &sample2, &coeff);
|
||||
W16(dst, sample1); dst += 2;
|
||||
process_nibble(*src++ & 0x0F, &idelta, &sample1, &sample2, &coeff);
|
||||
W16(dst, sample1); dst += 2;
|
||||
}
|
||||
src = in_src + adsi->pwfxSrc->nBlockAlign;
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
static void cvtSS16msK(PACMDRVSTREAMINSTANCE adsi,
|
||||
const unsigned char* src, LPDWORD nsrc,
|
||||
unsigned char* dst, LPDWORD ndst)
|
||||
{
|
||||
}
|
||||
|
||||
static void cvtMM16msK(PACMDRVSTREAMINSTANCE adsi,
|
||||
const unsigned char* src, LPDWORD nsrc,
|
||||
unsigned char* dst, LPDWORD ndst)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
/***********************************************************************
|
||||
* ADPCM_DriverDetails
|
||||
*
|
||||
*/
|
||||
static LRESULT ADPCM_DriverDetails(PACMDRIVERDETAILSW add)
|
||||
{
|
||||
add->fccType = ACMDRIVERDETAILS_FCCTYPE_AUDIOCODEC;
|
||||
add->fccComp = ACMDRIVERDETAILS_FCCCOMP_UNDEFINED;
|
||||
add->wMid = 0xFF;
|
||||
add->wPid = 0x00;
|
||||
add->vdwACM = 0x01000000;
|
||||
add->vdwDriver = 0x01000000;
|
||||
add->fdwSupport = ACMDRIVERDETAILS_SUPPORTF_CODEC;
|
||||
add->cFormatTags = 2; /* PCM, MS ADPCM */
|
||||
add->cFilterTags = 0;
|
||||
add->hicon = NULL;
|
||||
MultiByteToWideChar( CP_ACP, 0, "WINE-MS ADPCM", -1,
|
||||
add->szShortName, sizeof(add->szShortName)/sizeof(WCHAR) );
|
||||
MultiByteToWideChar( CP_ACP, 0, "Wine MS ADPCM converter", -1,
|
||||
add->szLongName, sizeof(add->szLongName)/sizeof(WCHAR) );
|
||||
MultiByteToWideChar( CP_ACP, 0, "Brought to you by the Wine team...", -1,
|
||||
add->szCopyright, sizeof(add->szCopyright)/sizeof(WCHAR) );
|
||||
MultiByteToWideChar( CP_ACP, 0, "Refer to LICENSE file", -1,
|
||||
add->szLicensing, sizeof(add->szLicensing)/sizeof(WCHAR) );
|
||||
add->szFeatures[0] = 0;
|
||||
|
||||
return MMSYSERR_NOERROR;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* ADPCM_FormatTagDetails
|
||||
*
|
||||
*/
|
||||
static LRESULT ADPCM_FormatTagDetails(PACMFORMATTAGDETAILSW aftd, DWORD dwQuery)
|
||||
{
|
||||
static WCHAR szPcm[]={'P','C','M',0};
|
||||
static WCHAR szMsAdPcm[]={'M','S',' ','A','d','P','C','M',0};
|
||||
|
||||
switch (dwQuery)
|
||||
{
|
||||
case ACM_FORMATTAGDETAILSF_INDEX:
|
||||
if (aftd->dwFormatTagIndex >= 2) return ACMERR_NOTPOSSIBLE;
|
||||
break;
|
||||
case ACM_FORMATTAGDETAILSF_LARGESTSIZE:
|
||||
if (aftd->dwFormatTag == WAVE_FORMAT_UNKNOWN)
|
||||
{
|
||||
aftd->dwFormatTagIndex = 1; /* WAVE_FORMAT_ADPCM is bigger than PCM */
|
||||
break;
|
||||
}
|
||||
/* fall thru */
|
||||
case ACM_FORMATTAGDETAILSF_FORMATTAG:
|
||||
switch (aftd->dwFormatTag)
|
||||
{
|
||||
case WAVE_FORMAT_PCM: aftd->dwFormatTagIndex = 0; break;
|
||||
case WAVE_FORMAT_ADPCM: aftd->dwFormatTagIndex = 1; break;
|
||||
default: return ACMERR_NOTPOSSIBLE;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
WARN("Unsupported query %08lx\n", dwQuery);
|
||||
return MMSYSERR_NOTSUPPORTED;
|
||||
}
|
||||
|
||||
aftd->fdwSupport = ACMDRIVERDETAILS_SUPPORTF_CODEC;
|
||||
switch (aftd->dwFormatTagIndex)
|
||||
{
|
||||
case 0:
|
||||
aftd->dwFormatTag = WAVE_FORMAT_PCM;
|
||||
aftd->cbFormatSize = sizeof(PCMWAVEFORMAT);
|
||||
aftd->cStandardFormats = NUM_PCM_FORMATS;
|
||||
lstrcpyW(aftd->szFormatTag, szPcm);
|
||||
break;
|
||||
case 1:
|
||||
aftd->dwFormatTag = WAVE_FORMAT_ADPCM;
|
||||
aftd->cbFormatSize = sizeof(ADPCMWAVEFORMAT) + (7 - 1) * sizeof(ADPCMCOEFSET);
|
||||
aftd->cStandardFormats = NUM_ADPCM_FORMATS;
|
||||
lstrcpyW(aftd->szFormatTag, szMsAdPcm);
|
||||
break;
|
||||
}
|
||||
return MMSYSERR_NOERROR;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* ADPCM_FormatDetails
|
||||
*
|
||||
*/
|
||||
static LRESULT ADPCM_FormatDetails(PACMFORMATDETAILSW afd, DWORD dwQuery)
|
||||
{
|
||||
switch (dwQuery)
|
||||
{
|
||||
case ACM_FORMATDETAILSF_FORMAT:
|
||||
if (ADPCM_GetFormatIndex(afd->pwfx) == 0xFFFFFFFF) return ACMERR_NOTPOSSIBLE;
|
||||
break;
|
||||
case ACM_FORMATDETAILSF_INDEX:
|
||||
afd->pwfx->wFormatTag = afd->dwFormatTag;
|
||||
switch (afd->dwFormatTag)
|
||||
{
|
||||
case WAVE_FORMAT_PCM:
|
||||
if (afd->dwFormatIndex >= NUM_PCM_FORMATS) return ACMERR_NOTPOSSIBLE;
|
||||
afd->pwfx->nChannels = PCM_Formats[afd->dwFormatIndex].nChannels;
|
||||
afd->pwfx->nSamplesPerSec = PCM_Formats[afd->dwFormatIndex].rate;
|
||||
afd->pwfx->wBitsPerSample = PCM_Formats[afd->dwFormatIndex].nBits;
|
||||
/* native MSACM uses a PCMWAVEFORMAT structure, so cbSize is not accessible
|
||||
* afd->pwfx->cbSize = 0;
|
||||
*/
|
||||
afd->pwfx->nBlockAlign =
|
||||
(afd->pwfx->nChannels * afd->pwfx->wBitsPerSample) / 8;
|
||||
afd->pwfx->nAvgBytesPerSec =
|
||||
afd->pwfx->nSamplesPerSec * afd->pwfx->nBlockAlign;
|
||||
break;
|
||||
case WAVE_FORMAT_ADPCM:
|
||||
if (afd->dwFormatIndex >= NUM_ADPCM_FORMATS) return ACMERR_NOTPOSSIBLE;
|
||||
if (afd->cbwfx < sizeof(ADPCMWAVEFORMAT) + (7 - 1) * sizeof(ADPCMCOEFSET))
|
||||
return ACMERR_NOTPOSSIBLE;
|
||||
afd->pwfx->nChannels = ADPCM_Formats[afd->dwFormatIndex].nChannels;
|
||||
afd->pwfx->nSamplesPerSec = ADPCM_Formats[afd->dwFormatIndex].rate;
|
||||
afd->pwfx->wBitsPerSample = ADPCM_Formats[afd->dwFormatIndex].nBits;
|
||||
init_wfx_adpcm((ADPCMWAVEFORMAT*)afd->pwfx);
|
||||
break;
|
||||
default:
|
||||
WARN("Unsupported tag %08lx\n", afd->dwFormatTag);
|
||||
return MMSYSERR_INVALPARAM;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
WARN("Unsupported query %08lx\n", dwQuery);
|
||||
return MMSYSERR_NOTSUPPORTED;
|
||||
}
|
||||
afd->fdwSupport = ACMDRIVERDETAILS_SUPPORTF_CODEC;
|
||||
afd->szFormat[0] = 0; /* let MSACM format this for us... */
|
||||
|
||||
return MMSYSERR_NOERROR;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* ADPCM_FormatSuggest
|
||||
*
|
||||
*/
|
||||
static LRESULT ADPCM_FormatSuggest(PACMDRVFORMATSUGGEST adfs)
|
||||
{
|
||||
/* some tests ... */
|
||||
if (adfs->cbwfxSrc < sizeof(PCMWAVEFORMAT) ||
|
||||
adfs->cbwfxDst < sizeof(PCMWAVEFORMAT) ||
|
||||
ADPCM_GetFormatIndex(adfs->pwfxSrc) == 0xFFFFFFFF) return ACMERR_NOTPOSSIBLE;
|
||||
/* FIXME: should do those tests against the real size (according to format tag */
|
||||
|
||||
/* If no suggestion for destination, then copy source value */
|
||||
if (!(adfs->fdwSuggest & ACM_FORMATSUGGESTF_NCHANNELS))
|
||||
adfs->pwfxDst->nChannels = adfs->pwfxSrc->nChannels;
|
||||
if (!(adfs->fdwSuggest & ACM_FORMATSUGGESTF_NSAMPLESPERSEC))
|
||||
adfs->pwfxDst->nSamplesPerSec = adfs->pwfxSrc->nSamplesPerSec;
|
||||
|
||||
if (!(adfs->fdwSuggest & ACM_FORMATSUGGESTF_WBITSPERSAMPLE))
|
||||
{
|
||||
if (adfs->pwfxSrc->wFormatTag == WAVE_FORMAT_PCM)
|
||||
adfs->pwfxDst->wBitsPerSample = 4;
|
||||
else
|
||||
adfs->pwfxDst->wBitsPerSample = 16;
|
||||
}
|
||||
if (!(adfs->fdwSuggest & ACM_FORMATSUGGESTF_WFORMATTAG))
|
||||
{
|
||||
if (adfs->pwfxSrc->wFormatTag == WAVE_FORMAT_PCM)
|
||||
adfs->pwfxDst->wFormatTag = WAVE_FORMAT_ADPCM;
|
||||
else
|
||||
adfs->pwfxDst->wFormatTag = WAVE_FORMAT_PCM;
|
||||
}
|
||||
|
||||
/* check if result is ok */
|
||||
if (ADPCM_GetFormatIndex(adfs->pwfxDst) == 0xFFFFFFFF) return ACMERR_NOTPOSSIBLE;
|
||||
|
||||
/* recompute other values */
|
||||
switch (adfs->pwfxDst->wFormatTag)
|
||||
{
|
||||
case WAVE_FORMAT_PCM:
|
||||
adfs->pwfxDst->nBlockAlign = (adfs->pwfxDst->nChannels * adfs->pwfxDst->wBitsPerSample) / 8;
|
||||
adfs->pwfxDst->nAvgBytesPerSec = adfs->pwfxDst->nSamplesPerSec * adfs->pwfxDst->nBlockAlign;
|
||||
break;
|
||||
case WAVE_FORMAT_ADPCM:
|
||||
init_wfx_adpcm((ADPCMWAVEFORMAT*)adfs->pwfxDst);
|
||||
break;
|
||||
default:
|
||||
FIXME("\n");
|
||||
break;
|
||||
}
|
||||
|
||||
return MMSYSERR_NOERROR;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* ADPCM_Reset
|
||||
*
|
||||
*/
|
||||
static void ADPCM_Reset(PACMDRVSTREAMINSTANCE adsi, AcmAdpcmData* aad)
|
||||
{
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* ADPCM_StreamOpen
|
||||
*
|
||||
*/
|
||||
static LRESULT ADPCM_StreamOpen(PACMDRVSTREAMINSTANCE adsi)
|
||||
{
|
||||
AcmAdpcmData* aad;
|
||||
|
||||
assert(!(adsi->fdwOpen & ACM_STREAMOPENF_ASYNC));
|
||||
|
||||
if (ADPCM_GetFormatIndex(adsi->pwfxSrc) == 0xFFFFFFFF ||
|
||||
ADPCM_GetFormatIndex(adsi->pwfxDst) == 0xFFFFFFFF)
|
||||
return ACMERR_NOTPOSSIBLE;
|
||||
|
||||
aad = HeapAlloc(GetProcessHeap(), 0, sizeof(AcmAdpcmData));
|
||||
if (aad == 0) return MMSYSERR_NOMEM;
|
||||
|
||||
adsi->dwDriver = (DWORD)aad;
|
||||
|
||||
if (adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_PCM &&
|
||||
adsi->pwfxDst->wFormatTag == WAVE_FORMAT_PCM)
|
||||
{
|
||||
goto theEnd;
|
||||
}
|
||||
else if (adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_ADPCM &&
|
||||
adsi->pwfxDst->wFormatTag == WAVE_FORMAT_PCM)
|
||||
{
|
||||
/* resampling or mono <=> stereo not available
|
||||
* ADPCM algo only define 16 bit per sample output
|
||||
*/
|
||||
if (adsi->pwfxSrc->nSamplesPerSec != adsi->pwfxDst->nSamplesPerSec ||
|
||||
adsi->pwfxSrc->nChannels != adsi->pwfxDst->nChannels ||
|
||||
adsi->pwfxDst->wBitsPerSample != 16)
|
||||
goto theEnd;
|
||||
|
||||
#if 0
|
||||
{
|
||||
unsigned int nspb = ((IMAADPCMWAVEFORMAT*)adsi->pwfxSrc)->wSamplesPerBlock;
|
||||
FIXME("spb=%u\n", nspb);
|
||||
|
||||
/* we check that in a block, after the header, samples are present on
|
||||
* 4-sample packet pattern
|
||||
* we also check that the block alignement is bigger than the expected size
|
||||
*/
|
||||
if (((nspb - 1) & 3) != 0) goto theEnd;
|
||||
if ((((nspb - 1) / 2) + 4) * adsi->pwfxSrc->nChannels < adsi->pwfxSrc->nBlockAlign)
|
||||
goto theEnd;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* adpcm decoding... */
|
||||
if (adsi->pwfxDst->wBitsPerSample == 16 && adsi->pwfxDst->nChannels == 2)
|
||||
aad->convert = cvtSSms16K;
|
||||
if (adsi->pwfxDst->wBitsPerSample == 16 && adsi->pwfxDst->nChannels == 1)
|
||||
aad->convert = cvtMMms16K;
|
||||
}
|
||||
else if (adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_PCM &&
|
||||
adsi->pwfxDst->wFormatTag == WAVE_FORMAT_ADPCM)
|
||||
{
|
||||
if (adsi->pwfxSrc->nSamplesPerSec != adsi->pwfxDst->nSamplesPerSec ||
|
||||
adsi->pwfxSrc->nChannels != adsi->pwfxDst->nChannels ||
|
||||
adsi->pwfxSrc->wBitsPerSample != 16)
|
||||
goto theEnd;
|
||||
#if 0
|
||||
nspb = ((IMAADPCMWAVEFORMAT*)adsi->pwfxDst)->wSamplesPerBlock;
|
||||
FIXME("spb=%u\n", nspb);
|
||||
|
||||
/* we check that in a block, after the header, samples are present on
|
||||
* 4-sample packet pattern
|
||||
* we also check that the block alignement is bigger than the expected size
|
||||
*/
|
||||
if (((nspb - 1) & 3) != 0) goto theEnd;
|
||||
if ((((nspb - 1) / 2) + 4) * adsi->pwfxDst->nChannels < adsi->pwfxDst->nBlockAlign)
|
||||
goto theEnd;
|
||||
#endif
|
||||
#if 0
|
||||
/* adpcm coding... */
|
||||
if (adsi->pwfxSrc->wBitsPerSample == 16 && adsi->pwfxSrc->nChannels == 2)
|
||||
aad->convert = cvtSS16msK;
|
||||
if (adsi->pwfxSrc->wBitsPerSample == 16 && adsi->pwfxSrc->nChannels == 1)
|
||||
aad->convert = cvtMM16msK;
|
||||
#endif
|
||||
FIXME("We don't support encoding yet\n");
|
||||
goto theEnd;
|
||||
}
|
||||
else goto theEnd;
|
||||
ADPCM_Reset(adsi, aad);
|
||||
|
||||
return MMSYSERR_NOERROR;
|
||||
|
||||
theEnd:
|
||||
HeapFree(GetProcessHeap(), 0, aad);
|
||||
adsi->dwDriver = 0L;
|
||||
return MMSYSERR_NOTSUPPORTED;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* ADPCM_StreamClose
|
||||
*
|
||||
*/
|
||||
static LRESULT ADPCM_StreamClose(PACMDRVSTREAMINSTANCE adsi)
|
||||
{
|
||||
HeapFree(GetProcessHeap(), 0, (void*)adsi->dwDriver);
|
||||
return MMSYSERR_NOERROR;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* ADPCM_round
|
||||
*
|
||||
*/
|
||||
static inline DWORD ADPCM_round(DWORD a, DWORD b, DWORD c)
|
||||
{
|
||||
assert(a && b && c);
|
||||
/* to be sure, always return an entire number of c... */
|
||||
return ((double)a * (double)b + (double)c - 1) / (double)c;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* ADPCM_StreamSize
|
||||
*
|
||||
*/
|
||||
static LRESULT ADPCM_StreamSize(PACMDRVSTREAMINSTANCE adsi, PACMDRVSTREAMSIZE adss)
|
||||
{
|
||||
switch (adss->fdwSize)
|
||||
{
|
||||
case ACM_STREAMSIZEF_DESTINATION:
|
||||
/* cbDstLength => cbSrcLength */
|
||||
if (adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_PCM &&
|
||||
adsi->pwfxDst->wFormatTag == WAVE_FORMAT_ADPCM)
|
||||
{
|
||||
/* don't take block overhead into account, doesn't matter too much */
|
||||
adss->cbSrcLength = adss->cbDstLength * 4;
|
||||
}
|
||||
else if (adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_ADPCM &&
|
||||
adsi->pwfxDst->wFormatTag == WAVE_FORMAT_PCM)
|
||||
{
|
||||
FIXME("misses the block header overhead\n");
|
||||
adss->cbSrcLength = 256 + adss->cbDstLength / 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
return MMSYSERR_NOTSUPPORTED;
|
||||
}
|
||||
break;
|
||||
case ACM_STREAMSIZEF_SOURCE:
|
||||
/* cbSrcLength => cbDstLength */
|
||||
if (adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_PCM &&
|
||||
adsi->pwfxDst->wFormatTag == WAVE_FORMAT_ADPCM)
|
||||
{
|
||||
FIXME("misses the block header overhead\n");
|
||||
adss->cbDstLength = 256 + adss->cbSrcLength / 4;
|
||||
}
|
||||
else if (adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_ADPCM &&
|
||||
adsi->pwfxDst->wFormatTag == WAVE_FORMAT_PCM)
|
||||
{
|
||||
/* don't take block overhead into account, doesn't matter too much */
|
||||
adss->cbDstLength = adss->cbSrcLength * 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
return MMSYSERR_NOTSUPPORTED;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
WARN("Unsupported query %08lx\n", adss->fdwSize);
|
||||
return MMSYSERR_NOTSUPPORTED;
|
||||
}
|
||||
return MMSYSERR_NOERROR;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* ADPCM_StreamConvert
|
||||
*
|
||||
*/
|
||||
static LRESULT ADPCM_StreamConvert(PACMDRVSTREAMINSTANCE adsi, PACMDRVSTREAMHEADER adsh)
|
||||
{
|
||||
AcmAdpcmData* aad = (AcmAdpcmData*)adsi->dwDriver;
|
||||
DWORD nsrc = adsh->cbSrcLength;
|
||||
DWORD ndst = adsh->cbDstLength;
|
||||
|
||||
if (adsh->fdwConvert &
|
||||
~(ACM_STREAMCONVERTF_BLOCKALIGN|
|
||||
ACM_STREAMCONVERTF_END|
|
||||
ACM_STREAMCONVERTF_START))
|
||||
{
|
||||
FIXME("Unsupported fdwConvert (%08lx), ignoring it\n", adsh->fdwConvert);
|
||||
}
|
||||
/* ACM_STREAMCONVERTF_BLOCKALIGN
|
||||
* currently all conversions are block aligned, so do nothing for this flag
|
||||
* ACM_STREAMCONVERTF_END
|
||||
* no pending data, so do nothing for this flag
|
||||
*/
|
||||
if ((adsh->fdwConvert & ACM_STREAMCONVERTF_START))
|
||||
{
|
||||
ADPCM_Reset(adsi, aad);
|
||||
}
|
||||
|
||||
aad->convert(adsi, adsh->pbSrc, &nsrc, adsh->pbDst, &ndst);
|
||||
adsh->cbSrcLengthUsed = nsrc;
|
||||
adsh->cbDstLengthUsed = ndst;
|
||||
|
||||
return MMSYSERR_NOERROR;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* ADPCM_DriverProc [exported]
|
||||
*/
|
||||
LRESULT CALLBACK ADPCM_DriverProc(DWORD dwDevID, HDRVR hDriv, UINT wMsg,
|
||||
LPARAM dwParam1, LPARAM dwParam2)
|
||||
{
|
||||
TRACE("(%08lx %08lx %04x %08lx %08lx);\n",
|
||||
dwDevID, (DWORD)hDriv, wMsg, dwParam1, dwParam2);
|
||||
|
||||
switch (wMsg)
|
||||
{
|
||||
case DRV_LOAD: return 1;
|
||||
case DRV_FREE: return 1;
|
||||
case DRV_OPEN: return ADPCM_drvOpen((LPSTR)dwParam1);
|
||||
case DRV_CLOSE: return ADPCM_drvClose(dwDevID);
|
||||
case DRV_ENABLE: return 1;
|
||||
case DRV_DISABLE: return 1;
|
||||
case DRV_QUERYCONFIGURE: return 1;
|
||||
case DRV_CONFIGURE: MessageBoxA(0, "MSACM MS ADPCM filter !", "Wine Driver", MB_OK); return 1;
|
||||
case DRV_INSTALL: return DRVCNF_RESTART;
|
||||
case DRV_REMOVE: return DRVCNF_RESTART;
|
||||
|
||||
case ACMDM_DRIVER_NOTIFY:
|
||||
/* no caching from other ACM drivers is done so far */
|
||||
return MMSYSERR_NOERROR;
|
||||
|
||||
case ACMDM_DRIVER_DETAILS:
|
||||
return ADPCM_DriverDetails((PACMDRIVERDETAILSW)dwParam1);
|
||||
|
||||
case ACMDM_FORMATTAG_DETAILS:
|
||||
return ADPCM_FormatTagDetails((PACMFORMATTAGDETAILSW)dwParam1, dwParam2);
|
||||
|
||||
case ACMDM_FORMAT_DETAILS:
|
||||
return ADPCM_FormatDetails((PACMFORMATDETAILSW)dwParam1, dwParam2);
|
||||
|
||||
case ACMDM_FORMAT_SUGGEST:
|
||||
return ADPCM_FormatSuggest((PACMDRVFORMATSUGGEST)dwParam1);
|
||||
|
||||
case ACMDM_STREAM_OPEN:
|
||||
return ADPCM_StreamOpen((PACMDRVSTREAMINSTANCE)dwParam1);
|
||||
|
||||
case ACMDM_STREAM_CLOSE:
|
||||
return ADPCM_StreamClose((PACMDRVSTREAMINSTANCE)dwParam1);
|
||||
|
||||
case ACMDM_STREAM_SIZE:
|
||||
return ADPCM_StreamSize((PACMDRVSTREAMINSTANCE)dwParam1, (PACMDRVSTREAMSIZE)dwParam2);
|
||||
|
||||
case ACMDM_STREAM_CONVERT:
|
||||
return ADPCM_StreamConvert((PACMDRVSTREAMINSTANCE)dwParam1, (PACMDRVSTREAMHEADER)dwParam2);
|
||||
|
||||
case ACMDM_HARDWARE_WAVE_CAPS_INPUT:
|
||||
case ACMDM_HARDWARE_WAVE_CAPS_OUTPUT:
|
||||
/* this converter is not a hardware driver */
|
||||
case ACMDM_FILTERTAG_DETAILS:
|
||||
case ACMDM_FILTER_DETAILS:
|
||||
/* this converter is not a filter */
|
||||
case ACMDM_STREAM_RESET:
|
||||
/* only needed for asynchronous driver... we aren't, so just say it */
|
||||
return MMSYSERR_NOTSUPPORTED;
|
||||
case ACMDM_STREAM_PREPARE:
|
||||
case ACMDM_STREAM_UNPREPARE:
|
||||
/* nothing special to do here... so don't do anything */
|
||||
return MMSYSERR_NOERROR;
|
||||
|
||||
default:
|
||||
return DefDriverProc(dwDevID, hDriv, wMsg, dwParam1, dwParam2);
|
||||
}
|
||||
return 0;
|
||||
}
|
|
@ -746,9 +746,15 @@ static BOOL MMDRV_InitHardcoded(void)
|
|||
#ifndef __REACTOS__
|
||||
MMDRV_Install("wineoss.drv", "wineoss.drv", FALSE);
|
||||
#endif /* __REACTOS__ */
|
||||
|
||||
#ifdef __REACTOS__
|
||||
// AG: TESTING:
|
||||
MMDRV_Install("mmdrv.dll", "mmdrv.dll", FALSE);
|
||||
#endif
|
||||
|
||||
/* finish with mappers */
|
||||
MMDRV_Install("wavemapper", "msacm.drv", TRUE);
|
||||
MMDRV_Install("midimapper", "midimap.drv", TRUE);
|
||||
MMDRV_Install("wavemapper", "msacm32.dll", TRUE);
|
||||
MMDRV_Install("midimapper", "midimap.dll", TRUE);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
|
9
reactos/lib/winmm/midimap/.cvsignore
Normal file
9
reactos/lib/winmm/midimap/.cvsignore
Normal file
|
@ -0,0 +1,9 @@
|
|||
*.a
|
||||
*.d
|
||||
*.o
|
||||
*.dll
|
||||
*.coff
|
||||
*.sym
|
||||
*.map
|
||||
*.tmp
|
||||
temp.exp
|
13
reactos/lib/winmm/midimap/Makefile.in
Normal file
13
reactos/lib/winmm/midimap/Makefile.in
Normal file
|
@ -0,0 +1,13 @@
|
|||
TOPSRCDIR = @top_srcdir@
|
||||
TOPOBJDIR = ../../..
|
||||
SRCDIR = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
MODULE = midimap.drv
|
||||
IMPORTS = winmm user32 advapi32 kernel32
|
||||
|
||||
C_SRCS = \
|
||||
midimap.c
|
||||
|
||||
@MAKE_DLL_RULES@
|
||||
|
||||
### Dependencies:
|
21
reactos/lib/winmm/midimap/Makefile.ros
Normal file
21
reactos/lib/winmm/midimap/Makefile.ros
Normal file
|
@ -0,0 +1,21 @@
|
|||
# $Id: Makefile.ros,v 1.1 2004/03/10 15:22:44 silverblade Exp $
|
||||
|
||||
TARGET_NAME = midimap
|
||||
|
||||
TARGET_OBJECTS = midimap.o
|
||||
|
||||
TARGET_CFLAGS = -D__REACTOS__
|
||||
|
||||
TARGET_SDKLIBS = winmm.a libwine.a ws2_32.a wine_uuid.a ntdll.a
|
||||
|
||||
TARGET_BASE = 0x77300000
|
||||
|
||||
TARGET_RC_SRCS = midimap.rc
|
||||
TARGET_RC_BINSRC = midimap.rc
|
||||
TARGET_RC_BINARIES =
|
||||
|
||||
default: all
|
||||
|
||||
DEP_OBJECTS = $(TARGET_OBJECTS)
|
||||
|
||||
include $(TOOLS_PATH)/depend.mk
|
21
reactos/lib/winmm/midimap/Makefile.ros-template
Normal file
21
reactos/lib/winmm/midimap/Makefile.ros-template
Normal file
|
@ -0,0 +1,21 @@
|
|||
# $Id: Makefile.ros-template,v 1.1 2004/03/10 15:22:44 silverblade Exp $
|
||||
|
||||
TARGET_NAME = midimap
|
||||
|
||||
TARGET_OBJECTS = @C_SRCS@
|
||||
|
||||
TARGET_CFLAGS = @EXTRADEFS@ -D__REACTOS__
|
||||
|
||||
TARGET_SDKLIBS = @IMPORTS@ winmm.a libwine.a wine_uuid.a ntdll.a
|
||||
|
||||
TARGET_BASE = 0x76160000
|
||||
|
||||
TARGET_RC_SRCS = @RC_SRCS@
|
||||
TARGET_RC_BINSRC = @RC_BINSRC@
|
||||
TARGET_RC_BINARIES = @RC_BINARIES@
|
||||
|
||||
default: all
|
||||
|
||||
DEP_OBJECTS = $(TARGET_OBJECTS)
|
||||
|
||||
include $(TOOLS_PATH)/depend.mk
|
9
reactos/lib/winmm/midimap/makefile
Normal file
9
reactos/lib/winmm/midimap/makefile
Normal file
|
@ -0,0 +1,9 @@
|
|||
# $Id: makefile,v 1.1 2004/03/10 15:22:44 silverblade Exp $
|
||||
|
||||
PATH_TO_TOP = ../../..
|
||||
|
||||
TARGET_TYPE = winedll
|
||||
|
||||
include $(PATH_TO_TOP)/rules.mak
|
||||
|
||||
include $(TOOLS_PATH)/helper.mk
|
555
reactos/lib/winmm/midimap/midimap.c
Normal file
555
reactos/lib/winmm/midimap/midimap.c
Normal file
|
@ -0,0 +1,555 @@
|
|||
/* -*- tab-width: 8; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
* Wine MIDI mapper driver
|
||||
*
|
||||
* Copyright 1999, 2000, 2001 Eric Pouech
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* TODO:
|
||||
* notification has to be implemented
|
||||
* IDF file loading
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "wingdi.h"
|
||||
#include "winuser.h"
|
||||
#include "mmddk.h"
|
||||
#include "winreg.h"
|
||||
#include "wine/debug.h"
|
||||
|
||||
/*
|
||||
* Here's how Windows stores the midiOut mapping information.
|
||||
*
|
||||
* Full form (in HKU) is:
|
||||
*
|
||||
* [Software\\Microsoft\\Windows\\CurrentVersion\\Multimedia\\MIDIMap] 988836060
|
||||
* "AutoScheme"=dword:00000000
|
||||
* "ConfigureCount"=dword:00000004
|
||||
* "CurrentInstrument"="Wine OSS midi"
|
||||
* "CurrentScheme"="epp"
|
||||
* "DriverList"=""
|
||||
* "UseScheme"=dword:00000000
|
||||
*
|
||||
* AutoScheme: ?
|
||||
* CurrentInstrument: name of midiOut device to use when UseScheme is 0. Wine uses an extension
|
||||
* of the form #n to link to n'th midiOut device of the system
|
||||
* CurrentScheme: when UseScheme is non null, it's the scheme to use (see below)
|
||||
* DriverList: ?
|
||||
* UseScheme: trigger for simple/complex mapping
|
||||
*
|
||||
* A scheme is defined (in HKLM) as:
|
||||
*
|
||||
* [System\\CurrentControlSet\\Control\\MediaProperties\\PrivateProperties\\Midi\\Schemes\\<nameScheme>]
|
||||
* <nameScheme>: one key for each defined scheme (system wide)
|
||||
* under each one of these <nameScheme> keys, there's:
|
||||
* [...\\<nameScheme>\\<idxDevice>]
|
||||
* "Channels"="<bitMask>"
|
||||
* (the default value of this key also refers to the name of the device).
|
||||
*
|
||||
* this defines, for each midiOut device (identified by its index in <idxDevice>), which
|
||||
* channels have to be mapped onto it. The <bitMask> defines the channels (from 0 to 15)
|
||||
* will be mapped (mapping occurs for channel <ch> if bit <ch> is set in <bitMask>
|
||||
*
|
||||
* Further mapping information can also be defined in:
|
||||
* [System\\CurrentControlSet\\Control\\MediaProperties\\PrivateProperties\\Midi\\Ports\\<nameDevice>\\Instruments\\<idx>]
|
||||
* "Definition"="<.idf file>"
|
||||
* "FriendlyName"="#for .idx file#"
|
||||
* "Port"="<idxPort>"
|
||||
*
|
||||
* This last part isn't implemented (.idf file support).
|
||||
*/
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(msacm);
|
||||
|
||||
typedef struct tagMIDIOUTPORT
|
||||
{
|
||||
char name[MAXPNAMELEN];
|
||||
int loaded;
|
||||
HMIDIOUT hMidi;
|
||||
unsigned short uDevID;
|
||||
LPBYTE lpbPatch;
|
||||
unsigned int aChn[16];
|
||||
} MIDIOUTPORT;
|
||||
|
||||
typedef struct tagMIDIMAPDATA
|
||||
{
|
||||
struct tagMIDIMAPDATA* self;
|
||||
MIDIOUTPORT* ChannelMap[16];
|
||||
} MIDIMAPDATA;
|
||||
|
||||
static MIDIOUTPORT* midiOutPorts;
|
||||
static unsigned numMidiOutPorts;
|
||||
|
||||
static BOOL MIDIMAP_IsBadData(MIDIMAPDATA* mm)
|
||||
{
|
||||
if (!IsBadReadPtr(mm, sizeof(MIDIMAPDATA)) && mm->self == mm)
|
||||
return FALSE;
|
||||
TRACE("Bad midimap data (%p)\n", mm);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL MIDIMAP_FindPort(const char* name, unsigned* dev)
|
||||
{
|
||||
for (*dev = 0; *dev < numMidiOutPorts; (*dev)++)
|
||||
{
|
||||
TRACE("%s\n", midiOutPorts[*dev].name);
|
||||
if (strcmp(midiOutPorts[*dev].name, name) == 0)
|
||||
return TRUE;
|
||||
}
|
||||
/* try the form #nnn */
|
||||
if (*name == '#' && isdigit(name[1]))
|
||||
{
|
||||
*dev = atoi(name + 1);
|
||||
if (*dev < numMidiOutPorts)
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static BOOL MIDIMAP_LoadSettingsDefault(MIDIMAPDATA* mom, const char* port)
|
||||
{
|
||||
unsigned i, dev = 0;
|
||||
|
||||
if (port != NULL && !MIDIMAP_FindPort(port, &dev))
|
||||
{
|
||||
ERR("Registry glitch: couldn't find midi out (%s)\n", port);
|
||||
dev = 0;
|
||||
}
|
||||
|
||||
/* this is necessary when no midi out ports are present */
|
||||
if (dev >= numMidiOutPorts)
|
||||
return FALSE;
|
||||
/* sets default */
|
||||
for (i = 0; i < 16; i++) mom->ChannelMap[i] = &midiOutPorts[dev];
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL MIDIMAP_LoadSettingsScheme(MIDIMAPDATA* mom, const char* scheme)
|
||||
{
|
||||
HKEY hSchemesKey, hKey, hPortKey;
|
||||
unsigned i, idx, dev;
|
||||
char buffer[256], port[256];
|
||||
DWORD type, size, mask;
|
||||
|
||||
for (i = 0; i < 16; i++) mom->ChannelMap[i] = NULL;
|
||||
|
||||
if (RegOpenKeyA(HKEY_LOCAL_MACHINE,
|
||||
"System\\CurrentControlSet\\Control\\MediaProperties\\PrivateProperties\\Midi\\Schemes",
|
||||
&hSchemesKey))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
if (RegOpenKeyA(hSchemesKey, scheme, &hKey))
|
||||
{
|
||||
RegCloseKey(hSchemesKey);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
for (idx = 0; !RegEnumKeyA(hKey, idx, buffer, sizeof(buffer)); idx++)
|
||||
{
|
||||
if (RegOpenKeyA(hKey, buffer, &hPortKey)) continue;
|
||||
|
||||
size = sizeof(port);
|
||||
if (RegQueryValueExA(hPortKey, NULL, 0, &type, port, &size)) continue;
|
||||
|
||||
if (!MIDIMAP_FindPort(port, &dev)) continue;
|
||||
|
||||
size = sizeof(mask);
|
||||
if (RegQueryValueExA(hPortKey, "Channels", 0, &type, (void*)&mask, &size))
|
||||
continue;
|
||||
|
||||
for (i = 0; i < 16; i++)
|
||||
{
|
||||
if (mask & (1 << i))
|
||||
{
|
||||
if (mom->ChannelMap[i])
|
||||
ERR("Quirks in registry, channel %u is mapped twice\n", i);
|
||||
mom->ChannelMap[i] = &midiOutPorts[dev];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RegCloseKey(hSchemesKey);
|
||||
RegCloseKey(hKey);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL MIDIMAP_LoadSettings(MIDIMAPDATA* mom)
|
||||
{
|
||||
HKEY hKey;
|
||||
BOOL ret;
|
||||
|
||||
if (RegOpenKeyA(HKEY_CURRENT_USER,
|
||||
"Software\\Microsoft\\Windows\\CurrentVersion\\Multimedia\\MIDIMap", &hKey))
|
||||
{
|
||||
ret = MIDIMAP_LoadSettingsDefault(mom, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
DWORD type, size, out;
|
||||
char buffer[256];
|
||||
|
||||
ret = 2;
|
||||
size = sizeof(out);
|
||||
if (!RegQueryValueExA(hKey, "UseScheme", 0, &type, (void*)&out, &size) && out)
|
||||
{
|
||||
size = sizeof(buffer);
|
||||
if (!RegQueryValueExA(hKey, "CurrentScheme", 0, &type, buffer, &size))
|
||||
{
|
||||
if (!(ret = MIDIMAP_LoadSettingsScheme(mom, buffer)))
|
||||
ret = MIDIMAP_LoadSettingsDefault(mom, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
ERR("Wrong registry: UseScheme is active, but no CurrentScheme found\n");
|
||||
}
|
||||
}
|
||||
if (ret == 2)
|
||||
{
|
||||
size = sizeof(buffer);
|
||||
if (!RegQueryValueExA(hKey, "CurrentInstrument", 0, &type, buffer, &size) && *buffer)
|
||||
{
|
||||
ret = MIDIMAP_LoadSettingsDefault(mom, buffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = MIDIMAP_LoadSettingsDefault(mom, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
RegCloseKey(hKey);
|
||||
|
||||
if (ret && TRACE_ON(msacm))
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i < 16; i++)
|
||||
{
|
||||
TRACE("chnMap[%2d] => %d\n",
|
||||
i, mom->ChannelMap[i] ? mom->ChannelMap[i]->uDevID : -1);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static DWORD modOpen(LPDWORD lpdwUser, LPMIDIOPENDESC lpDesc, DWORD dwFlags)
|
||||
{
|
||||
MIDIMAPDATA* mom = HeapAlloc(GetProcessHeap(), 0, sizeof(MIDIMAPDATA));
|
||||
|
||||
TRACE("(%p %p %08lx)\n", lpdwUser, lpDesc, dwFlags);
|
||||
|
||||
if (!mom) return MMSYSERR_NOMEM;
|
||||
|
||||
if (MIDIMAP_LoadSettings(mom))
|
||||
{
|
||||
*lpdwUser = (DWORD)mom;
|
||||
mom->self = mom;
|
||||
|
||||
return MMSYSERR_NOERROR;
|
||||
}
|
||||
HeapFree(GetProcessHeap(), 0, mom);
|
||||
return MIDIERR_INVALIDSETUP;
|
||||
}
|
||||
|
||||
static DWORD modClose(MIDIMAPDATA* mom)
|
||||
{
|
||||
UINT i;
|
||||
DWORD ret = MMSYSERR_NOERROR;
|
||||
|
||||
if (MIDIMAP_IsBadData(mom)) return MMSYSERR_ERROR;
|
||||
|
||||
for (i = 0; i < 16; i++)
|
||||
{
|
||||
DWORD t;
|
||||
if (mom->ChannelMap[i] && mom->ChannelMap[i]->loaded > 0)
|
||||
{
|
||||
t = midiOutClose(mom->ChannelMap[i]->hMidi);
|
||||
if (t == MMSYSERR_NOERROR)
|
||||
{
|
||||
mom->ChannelMap[i]->loaded = 0;
|
||||
mom->ChannelMap[i]->hMidi = 0;
|
||||
}
|
||||
else if (ret == MMSYSERR_NOERROR)
|
||||
ret = t;
|
||||
}
|
||||
}
|
||||
if (ret == MMSYSERR_NOERROR)
|
||||
HeapFree(GetProcessHeap(), 0, mom);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static DWORD modLongData(MIDIMAPDATA* mom, LPMIDIHDR lpMidiHdr, DWORD dwParam2)
|
||||
{
|
||||
WORD chn;
|
||||
DWORD ret = MMSYSERR_NOERROR;
|
||||
MIDIHDR mh;
|
||||
|
||||
if (MIDIMAP_IsBadData(mom))
|
||||
return MMSYSERR_ERROR;
|
||||
|
||||
mh = *lpMidiHdr;
|
||||
for (chn = 0; chn < 16; chn++)
|
||||
{
|
||||
if (mom->ChannelMap[chn] && mom->ChannelMap[chn]->loaded > 0)
|
||||
{
|
||||
mh.dwFlags = 0;
|
||||
midiOutPrepareHeader(mom->ChannelMap[chn]->hMidi, &mh, sizeof(mh));
|
||||
ret = midiOutLongMsg(mom->ChannelMap[chn]->hMidi, &mh, sizeof(mh));
|
||||
midiOutUnprepareHeader(mom->ChannelMap[chn]->hMidi, &mh, sizeof(mh));
|
||||
if (ret != MMSYSERR_NOERROR) break;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static DWORD modData(MIDIMAPDATA* mom, DWORD dwParam)
|
||||
{
|
||||
BYTE lb = LOBYTE(LOWORD(dwParam));
|
||||
WORD chn = lb & 0x0F;
|
||||
DWORD ret = MMSYSERR_NOERROR;
|
||||
|
||||
if (MIDIMAP_IsBadData(mom))
|
||||
return MMSYSERR_ERROR;
|
||||
|
||||
if (!mom->ChannelMap[chn]) return MMSYSERR_NOERROR;
|
||||
|
||||
switch (lb & 0xF0)
|
||||
{
|
||||
case 0x80:
|
||||
case 0x90:
|
||||
case 0xA0:
|
||||
case 0xB0:
|
||||
case 0xC0:
|
||||
case 0xD0:
|
||||
case 0xE0:
|
||||
if (mom->ChannelMap[chn]->loaded == 0)
|
||||
{
|
||||
if (midiOutOpen(&mom->ChannelMap[chn]->hMidi, mom->ChannelMap[chn]->uDevID,
|
||||
0L, 0L, CALLBACK_NULL) == MMSYSERR_NOERROR)
|
||||
mom->ChannelMap[chn]->loaded = 1;
|
||||
else
|
||||
mom->ChannelMap[chn]->loaded = -1;
|
||||
/* FIXME: should load here the IDF midi data... and allow channel and
|
||||
* patch mappings
|
||||
*/
|
||||
}
|
||||
if (mom->ChannelMap[chn]->loaded > 0)
|
||||
{
|
||||
/* change channel */
|
||||
dwParam &= ~0x0F;
|
||||
dwParam |= mom->ChannelMap[chn]->aChn[chn];
|
||||
|
||||
if ((LOBYTE(LOWORD(dwParam)) & 0xF0) == 0xC0 /* program change */ &&
|
||||
mom->ChannelMap[chn]->lpbPatch)
|
||||
{
|
||||
BYTE patch = HIBYTE(LOWORD(dwParam));
|
||||
|
||||
/* change patch */
|
||||
dwParam &= ~0x0000FF00;
|
||||
dwParam |= mom->ChannelMap[chn]->lpbPatch[patch];
|
||||
}
|
||||
ret = midiOutShortMsg(mom->ChannelMap[chn]->hMidi, dwParam);
|
||||
}
|
||||
break;
|
||||
case 0xF0:
|
||||
for (chn = 0; chn < 16; chn++)
|
||||
{
|
||||
if (mom->ChannelMap[chn]->loaded > 0)
|
||||
ret = midiOutShortMsg(mom->ChannelMap[chn]->hMidi, dwParam);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
FIXME("ooch %lu\n", dwParam);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static DWORD modPrepare(MIDIMAPDATA* mom, LPMIDIHDR lpMidiHdr, DWORD dwParam2)
|
||||
{
|
||||
if (MIDIMAP_IsBadData(mom)) return MMSYSERR_ERROR;
|
||||
if (lpMidiHdr->dwFlags & (MHDR_ISSTRM|MHDR_PREPARED))
|
||||
return MMSYSERR_INVALPARAM;
|
||||
|
||||
lpMidiHdr->dwFlags |= MHDR_PREPARED;
|
||||
return MMSYSERR_NOERROR;
|
||||
}
|
||||
|
||||
static DWORD modUnprepare(MIDIMAPDATA* mom, LPMIDIHDR lpMidiHdr, DWORD dwParam2)
|
||||
{
|
||||
if (MIDIMAP_IsBadData(mom)) return MMSYSERR_ERROR;
|
||||
if ((lpMidiHdr->dwFlags & MHDR_ISSTRM) || !(lpMidiHdr->dwFlags & MHDR_PREPARED))
|
||||
return MMSYSERR_INVALPARAM;
|
||||
|
||||
lpMidiHdr->dwFlags &= ~MHDR_PREPARED;
|
||||
return MMSYSERR_NOERROR;
|
||||
}
|
||||
|
||||
static DWORD modGetDevCaps(UINT wDevID, MIDIMAPDATA* mom, LPMIDIOUTCAPSA lpMidiCaps, DWORD size)
|
||||
{
|
||||
lpMidiCaps->wMid = 0x00FF;
|
||||
lpMidiCaps->wPid = 0x0001;
|
||||
lpMidiCaps->vDriverVersion = 0x0100;
|
||||
strcpy(lpMidiCaps->szPname, "Wine midi out mapper");
|
||||
lpMidiCaps->wTechnology = MOD_MAPPER;
|
||||
lpMidiCaps->wVoices = 0;
|
||||
lpMidiCaps->wNotes = 0;
|
||||
lpMidiCaps->wChannelMask = 0xFFFF;
|
||||
lpMidiCaps->dwSupport = 0L;
|
||||
|
||||
return MMSYSERR_NOERROR;
|
||||
}
|
||||
|
||||
static DWORD modReset(MIDIMAPDATA* mom)
|
||||
{
|
||||
WORD chn;
|
||||
DWORD ret = MMSYSERR_NOERROR;
|
||||
|
||||
if (MIDIMAP_IsBadData(mom))
|
||||
return MMSYSERR_ERROR;
|
||||
|
||||
for (chn = 0; chn < 16; chn++)
|
||||
{
|
||||
if (mom->ChannelMap[chn] && mom->ChannelMap[chn]->loaded > 0)
|
||||
{
|
||||
ret = midiOutReset(mom->ChannelMap[chn]->hMidi);
|
||||
if (ret != MMSYSERR_NOERROR) break;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* modMessage (MIDIMAP.@)
|
||||
*/
|
||||
DWORD WINAPI MIDIMAP_modMessage(UINT wDevID, UINT wMsg, DWORD dwUser,
|
||||
DWORD dwParam1, DWORD dwParam2)
|
||||
{
|
||||
TRACE("(%u, %04X, %08lX, %08lX, %08lX);\n",
|
||||
wDevID, wMsg, dwUser, dwParam1, dwParam2);
|
||||
|
||||
switch (wMsg)
|
||||
{
|
||||
case DRVM_INIT:
|
||||
case DRVM_EXIT:
|
||||
case DRVM_ENABLE:
|
||||
case DRVM_DISABLE:
|
||||
/* FIXME: Pretend this is supported */
|
||||
return 0;
|
||||
|
||||
case MODM_OPEN: return modOpen ((LPDWORD)dwUser, (LPMIDIOPENDESC)dwParam1,dwParam2);
|
||||
case MODM_CLOSE: return modClose ((MIDIMAPDATA*)dwUser);
|
||||
|
||||
case MODM_DATA: return modData ((MIDIMAPDATA*)dwUser, dwParam1);
|
||||
case MODM_LONGDATA: return modLongData ((MIDIMAPDATA*)dwUser, (LPMIDIHDR)dwParam1, dwParam2);
|
||||
case MODM_PREPARE: return modPrepare ((MIDIMAPDATA*)dwUser, (LPMIDIHDR)dwParam1, dwParam2);
|
||||
case MODM_UNPREPARE: return modUnprepare ((MIDIMAPDATA*)dwUser, (LPMIDIHDR)dwParam1, dwParam2);
|
||||
case MODM_RESET: return modReset ((MIDIMAPDATA*)dwUser);
|
||||
|
||||
case MODM_GETDEVCAPS: return modGetDevCaps (wDevID, (MIDIMAPDATA*)dwUser, (LPMIDIOUTCAPSA)dwParam1,dwParam2);
|
||||
case MODM_GETNUMDEVS: return 1;
|
||||
case MODM_GETVOLUME: return MMSYSERR_NOTSUPPORTED;
|
||||
case MODM_SETVOLUME: return MMSYSERR_NOTSUPPORTED;
|
||||
default:
|
||||
FIXME("unknown message %d!\n", wMsg);
|
||||
}
|
||||
return MMSYSERR_NOTSUPPORTED;
|
||||
}
|
||||
|
||||
/*======================================================================*
|
||||
* Driver part *
|
||||
*======================================================================*/
|
||||
|
||||
/**************************************************************************
|
||||
* MIDIMAP_drvOpen [internal]
|
||||
*/
|
||||
static DWORD MIDIMAP_drvOpen(LPSTR str)
|
||||
{
|
||||
MIDIOUTCAPSA moc;
|
||||
unsigned dev, i;
|
||||
|
||||
if (midiOutPorts)
|
||||
return 0;
|
||||
|
||||
numMidiOutPorts = midiOutGetNumDevs();
|
||||
midiOutPorts = HeapAlloc(GetProcessHeap(), 0,
|
||||
numMidiOutPorts * sizeof(MIDIOUTPORT));
|
||||
for (dev = 0; dev < numMidiOutPorts; dev++)
|
||||
{
|
||||
if (midiOutGetDevCapsA(dev, &moc, sizeof(moc)) == 0L)
|
||||
{
|
||||
strcpy(midiOutPorts[dev].name, moc.szPname);
|
||||
midiOutPorts[dev].loaded = 0;
|
||||
midiOutPorts[dev].hMidi = 0;
|
||||
midiOutPorts[dev].uDevID = dev;
|
||||
midiOutPorts[dev].lpbPatch = NULL;
|
||||
for (i = 0; i < 16; i++)
|
||||
midiOutPorts[dev].aChn[i] = i;
|
||||
}
|
||||
else
|
||||
{
|
||||
midiOutPorts[dev].loaded = -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* MIDIMAP_drvClose [internal]
|
||||
*/
|
||||
static DWORD MIDIMAP_drvClose(DWORD dwDevID)
|
||||
{
|
||||
if (midiOutPorts)
|
||||
{
|
||||
HeapFree(GetProcessHeap(), 0, midiOutPorts);
|
||||
midiOutPorts = NULL;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* DriverProc (MIDIMAP.@)
|
||||
*/
|
||||
LONG CALLBACK MIDIMAP_DriverProc(DWORD dwDevID, HDRVR hDriv, DWORD wMsg,
|
||||
DWORD dwParam1, DWORD dwParam2)
|
||||
{
|
||||
/* EPP TRACE("(%08lX, %04X, %08lX, %08lX, %08lX)\n", */
|
||||
/* EPP dwDevID, hDriv, wMsg, dwParam1, dwParam2); */
|
||||
|
||||
switch (wMsg)
|
||||
{
|
||||
case DRV_LOAD: return 1;
|
||||
case DRV_FREE: return 1;
|
||||
case DRV_OPEN: return MIDIMAP_drvOpen((LPSTR)dwParam1);
|
||||
case DRV_CLOSE: return MIDIMAP_drvClose(dwDevID);
|
||||
case DRV_ENABLE: return 1;
|
||||
case DRV_DISABLE: return 1;
|
||||
case DRV_QUERYCONFIGURE: return 1;
|
||||
case DRV_CONFIGURE: MessageBoxA(0, "MIDIMAP MultiMedia Driver !", "OSS Driver", MB_OK); return 1;
|
||||
case DRV_INSTALL: return DRVCNF_RESTART;
|
||||
case DRV_REMOVE: return DRVCNF_RESTART;
|
||||
default:
|
||||
return DefDriverProc(dwDevID, hDriv, wMsg, dwParam1, dwParam2);
|
||||
}
|
||||
}
|
39
reactos/lib/winmm/midimap/midimap.rc
Normal file
39
reactos/lib/winmm/midimap/midimap.rc
Normal file
|
@ -0,0 +1,39 @@
|
|||
#include <defines.h>
|
||||
#include <reactos/resource.h>
|
||||
|
||||
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION RES_UINT_FV_MAJOR,RES_UINT_FV_MINOR,RES_UINT_FV_REVISION,RES_UINT_FV_BUILD
|
||||
PRODUCTVERSION RES_UINT_PV_MAJOR,RES_UINT_PV_MINOR,RES_UINT_PV_REVISION,RES_UINT_PV_BUILD
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
#else
|
||||
FILEFLAGS 0x0L
|
||||
#endif
|
||||
FILEOS 0x40004L
|
||||
FILETYPE 0x2L
|
||||
FILESUBTYPE 0x0L
|
||||
BEGIN
|
||||
BLOCK "StringFileInfo"
|
||||
BEGIN
|
||||
BLOCK "040904b0"
|
||||
BEGIN
|
||||
VALUE "CompanyName", RES_STR_COMPANY_NAME
|
||||
VALUE "FileDescription", "ReactOS/WINE MIDI Mapper\0"
|
||||
VALUE "FileVersion", RES_STR_FILE_VERSION
|
||||
VALUE "InternalName", "midimap\0"
|
||||
VALUE "LegalCopyright", RES_STR_LEGAL_COPYRIGHT
|
||||
VALUE "OriginalFilename", "midimap.drv\0"
|
||||
VALUE "ProductName", RES_STR_PRODUCT_NAME
|
||||
VALUE "ProductVersion", RES_STR_PRODUCT_VERSION
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
BEGIN
|
||||
VALUE "Translation", 0x409, 1200
|
||||
END
|
||||
END
|
||||
|
||||
|
2
reactos/lib/winmm/midimap/midimap.spec.def
Normal file
2
reactos/lib/winmm/midimap/midimap.spec.def
Normal file
|
@ -0,0 +1,2 @@
|
|||
@ stdcall DriverProc(long long long long long) MIDIMAP_DriverProc
|
||||
@ stdcall modMessage(long long long long long) MIDIMAP_modMessage
|
9
reactos/lib/winmm/wavemap/.cvsignore
Normal file
9
reactos/lib/winmm/wavemap/.cvsignore
Normal file
|
@ -0,0 +1,9 @@
|
|||
*.a
|
||||
*.d
|
||||
*.o
|
||||
*.dll
|
||||
*.coff
|
||||
*.sym
|
||||
*.map
|
||||
*.tmp
|
||||
temp.exp
|
13
reactos/lib/winmm/wavemap/Makefile.in
Normal file
13
reactos/lib/winmm/wavemap/Makefile.in
Normal file
|
@ -0,0 +1,13 @@
|
|||
TOPSRCDIR = @top_srcdir@
|
||||
TOPOBJDIR = ../../..
|
||||
SRCDIR = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
MODULE = msacm.drv
|
||||
IMPORTS = msacm32 winmm user32 kernel32
|
||||
|
||||
C_SRCS = \
|
||||
wavemap.c
|
||||
|
||||
@MAKE_DLL_RULES@
|
||||
|
||||
### Dependencies:
|
21
reactos/lib/winmm/wavemap/Makefile.ros
Normal file
21
reactos/lib/winmm/wavemap/Makefile.ros
Normal file
|
@ -0,0 +1,21 @@
|
|||
# $Id: Makefile.ros,v 1.1 2004/03/10 15:22:45 silverblade Exp $
|
||||
|
||||
TARGET_NAME = wavemap
|
||||
|
||||
TARGET_OBJECTS = wavemap.o
|
||||
|
||||
TARGET_CFLAGS = -D__REACTOS__
|
||||
|
||||
TARGET_SDKLIBS = winmm.a libwine.a ws2_32.a wine_uuid.a ntdll.a msacm32.a
|
||||
|
||||
TARGET_BASE = 0x77300000
|
||||
|
||||
TARGET_RC_SRCS = wavemap.rc
|
||||
TARGET_RC_BINSRC = wavemap.rc
|
||||
TARGET_RC_BINARIES =
|
||||
|
||||
default: all
|
||||
|
||||
DEP_OBJECTS = $(TARGET_OBJECTS)
|
||||
|
||||
include $(TOOLS_PATH)/depend.mk
|
21
reactos/lib/winmm/wavemap/Makefile.ros-template
Normal file
21
reactos/lib/winmm/wavemap/Makefile.ros-template
Normal file
|
@ -0,0 +1,21 @@
|
|||
# $Id: Makefile.ros-template,v 1.1 2004/03/10 15:22:45 silverblade Exp $
|
||||
|
||||
TARGET_NAME = midimap
|
||||
|
||||
TARGET_OBJECTS = @C_SRCS@
|
||||
|
||||
TARGET_CFLAGS = @EXTRADEFS@ -D__REACTOS__
|
||||
|
||||
TARGET_SDKLIBS = @IMPORTS@ winmm.a libwine.a wine_uuid.a ntdll.a
|
||||
|
||||
TARGET_BASE = 0x76160000
|
||||
|
||||
TARGET_RC_SRCS = @RC_SRCS@
|
||||
TARGET_RC_BINSRC = @RC_BINSRC@
|
||||
TARGET_RC_BINARIES = @RC_BINARIES@
|
||||
|
||||
default: all
|
||||
|
||||
DEP_OBJECTS = $(TARGET_OBJECTS)
|
||||
|
||||
include $(TOOLS_PATH)/depend.mk
|
9
reactos/lib/winmm/wavemap/makefile
Normal file
9
reactos/lib/winmm/wavemap/makefile
Normal file
|
@ -0,0 +1,9 @@
|
|||
# $Id: makefile,v 1.1 2004/03/10 15:22:45 silverblade Exp $
|
||||
|
||||
PATH_TO_TOP = ../../..
|
||||
|
||||
TARGET_TYPE = winedll
|
||||
|
||||
include $(PATH_TO_TOP)/rules.mak
|
||||
|
||||
include $(TOOLS_PATH)/helper.mk
|
3
reactos/lib/winmm/wavemap/msacm.spec.def
Normal file
3
reactos/lib/winmm/wavemap/msacm.spec.def
Normal file
|
@ -0,0 +1,3 @@
|
|||
@ stdcall DriverProc(long long long long long) WAVEMAP_DriverProc
|
||||
@ stdcall widMessage(long long long long long) WAVEMAP_widMessage
|
||||
@ stdcall wodMessage(long long long long long) WAVEMAP_wodMessage
|
975
reactos/lib/winmm/wavemap/wavemap.c
Normal file
975
reactos/lib/winmm/wavemap/wavemap.c
Normal file
|
@ -0,0 +1,975 @@
|
|||
/* -*- tab-width: 8; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
* Wine Wave mapper driver
|
||||
*
|
||||
* Copyright 1999,2001 Eric Pouech
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* TODOs
|
||||
* + better protection against evilish dwUser parameters
|
||||
* + use asynchronous ACM conversion
|
||||
* + don't use callback functions when none is required in open
|
||||
* + the buffer sizes may not be accurate, so there may be some
|
||||
* remaining bytes in src and dst buffers after ACM conversions...
|
||||
* those should be taken care of...
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "wingdi.h"
|
||||
#include "winuser.h"
|
||||
#include "mmddk.h"
|
||||
#include "mmreg.h"
|
||||
#include "msacm.h"
|
||||
#include "wine/debug.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(msacm);
|
||||
|
||||
typedef struct tagWAVEMAPDATA {
|
||||
struct tagWAVEMAPDATA* self;
|
||||
union {
|
||||
struct {
|
||||
HWAVEOUT hOuterWave;
|
||||
HWAVEOUT hInnerWave;
|
||||
} out;
|
||||
struct {
|
||||
HWAVEIN hOuterWave;
|
||||
HWAVEIN hInnerWave;
|
||||
} in;
|
||||
} u;
|
||||
HACMSTREAM hAcmStream;
|
||||
/* needed data to filter callbacks. Only needed when hAcmStream is not 0 */
|
||||
DWORD dwCallback;
|
||||
DWORD dwClientInstance;
|
||||
DWORD dwFlags;
|
||||
/* ratio to compute position from a PCM playback to any format */
|
||||
DWORD avgSpeedOuter;
|
||||
DWORD avgSpeedInner;
|
||||
} WAVEMAPDATA;
|
||||
|
||||
static BOOL WAVEMAP_IsData(WAVEMAPDATA* wm)
|
||||
{
|
||||
return (!IsBadReadPtr(wm, sizeof(WAVEMAPDATA)) && wm->self == wm);
|
||||
}
|
||||
|
||||
/*======================================================================*
|
||||
* WAVE OUT part *
|
||||
*======================================================================*/
|
||||
|
||||
static void CALLBACK wodCallback(HWAVEOUT hWave, UINT uMsg, DWORD dwInstance,
|
||||
DWORD dwParam1, DWORD dwParam2)
|
||||
{
|
||||
WAVEMAPDATA* wom = (WAVEMAPDATA*)dwInstance;
|
||||
|
||||
TRACE("(%p %u %ld %lx %lx);\n", hWave, uMsg, dwInstance, dwParam1, dwParam2);
|
||||
|
||||
if (!WAVEMAP_IsData(wom)) {
|
||||
ERR("Bad data\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (hWave != wom->u.out.hInnerWave && uMsg != WOM_OPEN)
|
||||
ERR("Shouldn't happen (%p %p)\n", hWave, wom->u.out.hInnerWave);
|
||||
|
||||
switch (uMsg) {
|
||||
case WOM_OPEN:
|
||||
case WOM_CLOSE:
|
||||
/* dwParam1 & dwParam2 are supposed to be 0, nothing to do */
|
||||
break;
|
||||
case WOM_DONE:
|
||||
if (wom->hAcmStream) {
|
||||
LPWAVEHDR lpWaveHdrDst = (LPWAVEHDR)dwParam1;
|
||||
PACMSTREAMHEADER ash = (PACMSTREAMHEADER)((LPSTR)lpWaveHdrDst - sizeof(ACMSTREAMHEADER));
|
||||
LPWAVEHDR lpWaveHdrSrc = (LPWAVEHDR)ash->dwUser;
|
||||
|
||||
lpWaveHdrSrc->dwFlags &= ~WHDR_INQUEUE;
|
||||
lpWaveHdrSrc->dwFlags |= WHDR_DONE;
|
||||
dwParam1 = (DWORD)lpWaveHdrSrc;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ERR("Unknown msg %u\n", uMsg);
|
||||
}
|
||||
|
||||
DriverCallback(wom->dwCallback, HIWORD(wom->dwFlags), (HDRVR)wom->u.out.hOuterWave,
|
||||
uMsg, wom->dwClientInstance, dwParam1, dwParam2);
|
||||
}
|
||||
|
||||
/******************************************************************
|
||||
* wodOpenHelper
|
||||
*
|
||||
*
|
||||
*/
|
||||
static DWORD wodOpenHelper(WAVEMAPDATA* wom, UINT idx,
|
||||
LPWAVEOPENDESC lpDesc, LPWAVEFORMATEX lpwfx,
|
||||
DWORD dwFlags)
|
||||
{
|
||||
DWORD ret;
|
||||
|
||||
/* destination is always PCM, so the formulas below apply */
|
||||
lpwfx->nBlockAlign = (lpwfx->nChannels * lpwfx->wBitsPerSample) / 8;
|
||||
lpwfx->nAvgBytesPerSec = lpwfx->nSamplesPerSec * lpwfx->nBlockAlign;
|
||||
if (dwFlags & WAVE_FORMAT_QUERY) {
|
||||
ret = acmStreamOpen(NULL, 0, lpDesc->lpFormat, lpwfx, NULL, 0L, 0L, ACM_STREAMOPENF_QUERY);
|
||||
} else {
|
||||
ret = acmStreamOpen(&wom->hAcmStream, 0, lpDesc->lpFormat, lpwfx, NULL, 0L, 0L, 0L);
|
||||
}
|
||||
if (ret == MMSYSERR_NOERROR) {
|
||||
ret = waveOutOpen(&wom->u.out.hInnerWave, idx, lpwfx, (DWORD)wodCallback,
|
||||
(DWORD)wom, (dwFlags & ~CALLBACK_TYPEMASK) | CALLBACK_FUNCTION);
|
||||
if (ret != MMSYSERR_NOERROR && !(dwFlags & WAVE_FORMAT_QUERY)) {
|
||||
acmStreamClose(wom->hAcmStream, 0);
|
||||
wom->hAcmStream = 0;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static DWORD wodOpen(LPDWORD lpdwUser, LPWAVEOPENDESC lpDesc, DWORD dwFlags)
|
||||
{
|
||||
UINT ndlo, ndhi;
|
||||
UINT i;
|
||||
WAVEMAPDATA* wom = HeapAlloc(GetProcessHeap(), 0, sizeof(WAVEMAPDATA));
|
||||
|
||||
TRACE("(%p %p %08lx)\n", lpdwUser, lpDesc, dwFlags);
|
||||
|
||||
if (!wom)
|
||||
return MMSYSERR_NOMEM;
|
||||
|
||||
ndhi = waveOutGetNumDevs();
|
||||
if (dwFlags & WAVE_MAPPED) {
|
||||
if (lpDesc->uMappedDeviceID >= ndhi) return MMSYSERR_INVALPARAM;
|
||||
ndlo = lpDesc->uMappedDeviceID;
|
||||
ndhi = ndlo + 1;
|
||||
dwFlags &= ~WAVE_MAPPED;
|
||||
} else {
|
||||
ndlo = 0;
|
||||
}
|
||||
wom->self = wom;
|
||||
wom->dwCallback = lpDesc->dwCallback;
|
||||
wom->dwFlags = dwFlags;
|
||||
wom->dwClientInstance = lpDesc->dwInstance;
|
||||
wom->u.out.hOuterWave = (HWAVEOUT)lpDesc->hWave;
|
||||
wom->avgSpeedOuter = wom->avgSpeedInner = lpDesc->lpFormat->nAvgBytesPerSec;
|
||||
|
||||
for (i = ndlo; i < ndhi; i++) {
|
||||
/* if no ACM stuff is involved, no need to handle callbacks at this
|
||||
* level, this will be done transparently
|
||||
*/
|
||||
if (waveOutOpen(&wom->u.out.hInnerWave, i, lpDesc->lpFormat, (DWORD)wodCallback,
|
||||
(DWORD)wom, (dwFlags & ~CALLBACK_TYPEMASK) | CALLBACK_FUNCTION | WAVE_FORMAT_DIRECT) == MMSYSERR_NOERROR) {
|
||||
wom->hAcmStream = 0;
|
||||
goto found;
|
||||
}
|
||||
}
|
||||
|
||||
if ((dwFlags & WAVE_FORMAT_DIRECT) == 0) {
|
||||
WAVEFORMATEX wfx;
|
||||
|
||||
wfx.wFormatTag = WAVE_FORMAT_PCM;
|
||||
wfx.cbSize = 0; /* normally, this field is not used for PCM format, just in case */
|
||||
/* try some ACM stuff */
|
||||
|
||||
#define TRY(sps,bps) wfx.nSamplesPerSec = (sps); wfx.wBitsPerSample = (bps); \
|
||||
switch (wodOpenHelper(wom, i, lpDesc, &wfx, dwFlags | WAVE_FORMAT_DIRECT)) { \
|
||||
case MMSYSERR_NOERROR: wom->avgSpeedInner = wfx.nAvgBytesPerSec; goto found; \
|
||||
case WAVERR_BADFORMAT: break; \
|
||||
default: goto error; \
|
||||
}
|
||||
|
||||
/* Our resampling algorithm is quite primitive so first try
|
||||
* to just change the bit depth and number of channels
|
||||
*/
|
||||
for (i = ndlo; i < ndhi; i++) {
|
||||
wfx.nSamplesPerSec=lpDesc->lpFormat->nSamplesPerSec;
|
||||
wfx.nChannels = lpDesc->lpFormat->nChannels;
|
||||
TRY(wfx.nSamplesPerSec, 16);
|
||||
TRY(wfx.nSamplesPerSec, 8);
|
||||
wfx.nChannels ^= 3;
|
||||
TRY(wfx.nSamplesPerSec, 16);
|
||||
TRY(wfx.nSamplesPerSec, 8);
|
||||
}
|
||||
|
||||
for (i = ndlo; i < ndhi; i++) {
|
||||
/* first try with same stereo/mono option as source */
|
||||
wfx.nChannels = lpDesc->lpFormat->nChannels;
|
||||
TRY(96000, 16);
|
||||
TRY(48000, 16);
|
||||
TRY(44100, 16);
|
||||
TRY(22050, 16);
|
||||
TRY(11025, 16);
|
||||
|
||||
/* 2^3 => 1, 1^3 => 2, so if stereo, try mono (and the other way around) */
|
||||
wfx.nChannels ^= 3;
|
||||
TRY(96000, 16);
|
||||
TRY(48000, 16);
|
||||
TRY(44100, 16);
|
||||
TRY(22050, 16);
|
||||
TRY(11025, 16);
|
||||
|
||||
/* first try with same stereo/mono option as source */
|
||||
wfx.nChannels = lpDesc->lpFormat->nChannels;
|
||||
TRY(96000, 8);
|
||||
TRY(48000, 8);
|
||||
TRY(44100, 8);
|
||||
TRY(22050, 8);
|
||||
TRY(11025, 8);
|
||||
|
||||
/* 2^3 => 1, 1^3 => 2, so if stereo, try mono (and the other way around) */
|
||||
wfx.nChannels ^= 3;
|
||||
TRY(96000, 8);
|
||||
TRY(48000, 8);
|
||||
TRY(44100, 8);
|
||||
TRY(22050, 8);
|
||||
TRY(11025, 8);
|
||||
}
|
||||
#undef TRY
|
||||
}
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, wom);
|
||||
return WAVERR_BADFORMAT;
|
||||
|
||||
found:
|
||||
if (dwFlags & WAVE_FORMAT_QUERY) {
|
||||
*lpdwUser = 0L;
|
||||
HeapFree(GetProcessHeap(), 0, wom);
|
||||
} else {
|
||||
*lpdwUser = (DWORD)wom;
|
||||
}
|
||||
return MMSYSERR_NOERROR;
|
||||
error:
|
||||
HeapFree(GetProcessHeap(), 0, wom);
|
||||
return MMSYSERR_ERROR;
|
||||
}
|
||||
|
||||
static DWORD wodClose(WAVEMAPDATA* wom)
|
||||
{
|
||||
DWORD ret = waveOutClose(wom->u.out.hInnerWave);
|
||||
|
||||
if (ret == MMSYSERR_NOERROR) {
|
||||
if (wom->hAcmStream) {
|
||||
ret = acmStreamClose(wom->hAcmStream, 0);
|
||||
}
|
||||
if (ret == MMSYSERR_NOERROR) {
|
||||
HeapFree(GetProcessHeap(), 0, wom);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static DWORD wodWrite(WAVEMAPDATA* wom, LPWAVEHDR lpWaveHdrSrc, DWORD dwParam2)
|
||||
{
|
||||
PACMSTREAMHEADER ash;
|
||||
LPWAVEHDR lpWaveHdrDst;
|
||||
|
||||
if (!wom->hAcmStream) {
|
||||
return waveOutWrite(wom->u.out.hInnerWave, lpWaveHdrSrc, dwParam2);
|
||||
}
|
||||
|
||||
lpWaveHdrSrc->dwFlags |= WHDR_INQUEUE;
|
||||
ash = (PACMSTREAMHEADER)lpWaveHdrSrc->reserved;
|
||||
/* acmStreamConvert will actually check that the new size is less than initial size */
|
||||
ash->cbSrcLength = lpWaveHdrSrc->dwBufferLength;
|
||||
if (acmStreamConvert(wom->hAcmStream, ash, 0L) != MMSYSERR_NOERROR)
|
||||
return MMSYSERR_ERROR;
|
||||
|
||||
lpWaveHdrDst = (LPWAVEHDR)((LPSTR)ash + sizeof(ACMSTREAMHEADER));
|
||||
if (ash->cbSrcLength > ash->cbSrcLengthUsed)
|
||||
FIXME("Not all src buffer has been written, expect bogus sound\n");
|
||||
else if (ash->cbSrcLength < ash->cbSrcLengthUsed)
|
||||
ERR("CoDec has read more data than it is allowed to\n");
|
||||
|
||||
if (ash->cbDstLengthUsed == 0)
|
||||
{
|
||||
/* something went wrong in decoding */
|
||||
FIXME("Got 0 length\n");
|
||||
return MMSYSERR_ERROR;
|
||||
}
|
||||
lpWaveHdrDst->dwBufferLength = ash->cbDstLengthUsed;
|
||||
return waveOutWrite(wom->u.out.hInnerWave, lpWaveHdrDst, sizeof(*lpWaveHdrDst));
|
||||
}
|
||||
|
||||
static DWORD wodPrepare(WAVEMAPDATA* wom, LPWAVEHDR lpWaveHdrSrc, DWORD dwParam2)
|
||||
{
|
||||
PACMSTREAMHEADER ash;
|
||||
DWORD size;
|
||||
DWORD dwRet;
|
||||
LPWAVEHDR lpWaveHdrDst;
|
||||
|
||||
if (!wom->hAcmStream) {
|
||||
return waveOutPrepareHeader(wom->u.out.hInnerWave, lpWaveHdrSrc, dwParam2);
|
||||
}
|
||||
if (acmStreamSize(wom->hAcmStream, lpWaveHdrSrc->dwBufferLength, &size, ACM_STREAMSIZEF_SOURCE) != MMSYSERR_NOERROR)
|
||||
return MMSYSERR_ERROR;
|
||||
|
||||
ash = HeapAlloc(GetProcessHeap(), 0, sizeof(ACMSTREAMHEADER) + sizeof(WAVEHDR) + size);
|
||||
if (ash == NULL)
|
||||
return MMSYSERR_NOMEM;
|
||||
|
||||
ash->cbStruct = sizeof(*ash);
|
||||
ash->fdwStatus = 0L;
|
||||
ash->dwUser = (DWORD)lpWaveHdrSrc;
|
||||
ash->pbSrc = lpWaveHdrSrc->lpData;
|
||||
ash->cbSrcLength = lpWaveHdrSrc->dwBufferLength;
|
||||
/* ash->cbSrcLengthUsed */
|
||||
ash->dwSrcUser = lpWaveHdrSrc->dwUser; /* FIXME ? */
|
||||
ash->pbDst = (LPSTR)ash + sizeof(ACMSTREAMHEADER) + sizeof(WAVEHDR);
|
||||
ash->cbDstLength = size;
|
||||
/* ash->cbDstLengthUsed */
|
||||
ash->dwDstUser = 0; /* FIXME ? */
|
||||
dwRet = acmStreamPrepareHeader(wom->hAcmStream, ash, 0L);
|
||||
if (dwRet != MMSYSERR_NOERROR)
|
||||
goto errCleanUp;
|
||||
|
||||
lpWaveHdrDst = (LPWAVEHDR)((LPSTR)ash + sizeof(ACMSTREAMHEADER));
|
||||
lpWaveHdrDst->lpData = ash->pbDst;
|
||||
lpWaveHdrDst->dwBufferLength = size; /* conversion is not done yet */
|
||||
lpWaveHdrDst->dwFlags = 0;
|
||||
lpWaveHdrDst->dwLoops = 0;
|
||||
dwRet = waveOutPrepareHeader(wom->u.out.hInnerWave, lpWaveHdrDst, sizeof(*lpWaveHdrDst));
|
||||
if (dwRet != MMSYSERR_NOERROR)
|
||||
goto errCleanUp;
|
||||
|
||||
lpWaveHdrSrc->reserved = (DWORD)ash;
|
||||
lpWaveHdrSrc->dwFlags = WHDR_PREPARED;
|
||||
TRACE("=> (0)\n");
|
||||
return MMSYSERR_NOERROR;
|
||||
errCleanUp:
|
||||
TRACE("=> (%ld)\n", dwRet);
|
||||
HeapFree(GetProcessHeap(), 0, ash);
|
||||
return dwRet;
|
||||
}
|
||||
|
||||
static DWORD wodUnprepare(WAVEMAPDATA* wom, LPWAVEHDR lpWaveHdrSrc, DWORD dwParam2)
|
||||
{
|
||||
PACMSTREAMHEADER ash;
|
||||
LPWAVEHDR lpWaveHdrDst;
|
||||
DWORD dwRet1, dwRet2;
|
||||
|
||||
if (!wom->hAcmStream) {
|
||||
return waveOutUnprepareHeader(wom->u.out.hInnerWave, lpWaveHdrSrc, dwParam2);
|
||||
}
|
||||
ash = (PACMSTREAMHEADER)lpWaveHdrSrc->reserved;
|
||||
dwRet1 = acmStreamUnprepareHeader(wom->hAcmStream, ash, 0L);
|
||||
|
||||
lpWaveHdrDst = (LPWAVEHDR)((LPSTR)ash + sizeof(ACMSTREAMHEADER));
|
||||
dwRet2 = waveOutUnprepareHeader(wom->u.out.hInnerWave, lpWaveHdrDst, sizeof(*lpWaveHdrDst));
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, ash);
|
||||
|
||||
lpWaveHdrSrc->dwFlags &= ~WHDR_PREPARED;
|
||||
return (dwRet1 == MMSYSERR_NOERROR) ? dwRet2 : dwRet1;
|
||||
}
|
||||
|
||||
static DWORD wodGetPosition(WAVEMAPDATA* wom, LPMMTIME lpTime, DWORD dwParam2)
|
||||
{
|
||||
DWORD val = waveOutGetPosition(wom->u.out.hInnerWave, lpTime, dwParam2);
|
||||
if (lpTime->wType == TIME_BYTES)
|
||||
lpTime->u.cb = MulDiv(lpTime->u.cb, wom->avgSpeedOuter, wom->avgSpeedInner);
|
||||
/* other time types don't require conversion */
|
||||
return val;
|
||||
}
|
||||
|
||||
static DWORD wodGetDevCaps(UINT wDevID, WAVEMAPDATA* wom, LPWAVEOUTCAPSA lpWaveCaps, DWORD dwParam2)
|
||||
{
|
||||
/* if opened low driver, forward message */
|
||||
if (WAVEMAP_IsData(wom))
|
||||
return waveOutGetDevCapsA((UINT)wom->u.out.hInnerWave, lpWaveCaps, dwParam2);
|
||||
/* otherwise, return caps of mapper itself */
|
||||
if (wDevID == (UINT)-1 || wDevID == (UINT16)-1) {
|
||||
lpWaveCaps->wMid = 0x00FF;
|
||||
lpWaveCaps->wPid = 0x0001;
|
||||
lpWaveCaps->vDriverVersion = 0x0100;
|
||||
strcpy(lpWaveCaps->szPname, "Wine wave out mapper");
|
||||
lpWaveCaps->dwFormats =
|
||||
WAVE_FORMAT_4M08 | WAVE_FORMAT_4S08 | WAVE_FORMAT_4M16 | WAVE_FORMAT_4S16 |
|
||||
WAVE_FORMAT_2M08 | WAVE_FORMAT_2S08 | WAVE_FORMAT_2M16 | WAVE_FORMAT_2S16 |
|
||||
WAVE_FORMAT_1M08 | WAVE_FORMAT_1S08 | WAVE_FORMAT_1M16 | WAVE_FORMAT_1S16;
|
||||
lpWaveCaps->wChannels = 2;
|
||||
lpWaveCaps->dwSupport = WAVECAPS_VOLUME | WAVECAPS_LRVOLUME;
|
||||
|
||||
return MMSYSERR_NOERROR;
|
||||
}
|
||||
ERR("This shouldn't happen\n");
|
||||
return MMSYSERR_ERROR;
|
||||
}
|
||||
|
||||
static DWORD wodGetVolume(UINT wDevID, WAVEMAPDATA* wom, LPDWORD lpVol)
|
||||
{
|
||||
if (WAVEMAP_IsData(wom))
|
||||
return waveOutGetVolume(wom->u.out.hInnerWave, lpVol);
|
||||
return MMSYSERR_NOERROR;
|
||||
}
|
||||
|
||||
static DWORD wodSetVolume(UINT wDevID, WAVEMAPDATA* wom, DWORD vol)
|
||||
{
|
||||
if (WAVEMAP_IsData(wom))
|
||||
return waveOutSetVolume(wom->u.out.hInnerWave, vol);
|
||||
return MMSYSERR_NOERROR;
|
||||
}
|
||||
|
||||
static DWORD wodPause(WAVEMAPDATA* wom)
|
||||
{
|
||||
return waveOutPause(wom->u.out.hInnerWave);
|
||||
}
|
||||
|
||||
static DWORD wodRestart(WAVEMAPDATA* wom)
|
||||
{
|
||||
return waveOutRestart(wom->u.out.hInnerWave);
|
||||
}
|
||||
|
||||
static DWORD wodReset(WAVEMAPDATA* wom)
|
||||
{
|
||||
return waveOutReset(wom->u.out.hInnerWave);
|
||||
}
|
||||
|
||||
static DWORD wodBreakLoop(WAVEMAPDATA* wom)
|
||||
{
|
||||
return waveOutBreakLoop(wom->u.out.hInnerWave);
|
||||
}
|
||||
|
||||
static DWORD wodMapperStatus(WAVEMAPDATA* wom, DWORD flags, LPVOID ptr)
|
||||
{
|
||||
UINT id;
|
||||
DWORD ret = MMSYSERR_NOTSUPPORTED;
|
||||
|
||||
switch (flags) {
|
||||
case WAVEOUT_MAPPER_STATUS_DEVICE:
|
||||
ret = waveOutGetID(wom->u.out.hInnerWave, &id);
|
||||
*(LPDWORD)ptr = id;
|
||||
break;
|
||||
case WAVEOUT_MAPPER_STATUS_MAPPED:
|
||||
FIXME("Unsupported flag=%ld\n", flags);
|
||||
*(LPDWORD)ptr = 0; /* FIXME ?? */
|
||||
break;
|
||||
case WAVEOUT_MAPPER_STATUS_FORMAT:
|
||||
FIXME("Unsupported flag=%ld\n", flags);
|
||||
/* ptr points to a WAVEFORMATEX struct - before or after streaming ? */
|
||||
*(LPDWORD)ptr = 0;
|
||||
break;
|
||||
default:
|
||||
FIXME("Unsupported flag=%ld\n", flags);
|
||||
*(LPDWORD)ptr = 0;
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* wodMessage (MSACM.@)
|
||||
*/
|
||||
DWORD WINAPI WAVEMAP_wodMessage(UINT wDevID, UINT wMsg, DWORD dwUser,
|
||||
DWORD dwParam1, DWORD dwParam2)
|
||||
{
|
||||
TRACE("(%u, %04X, %08lX, %08lX, %08lX);\n",
|
||||
wDevID, wMsg, dwUser, dwParam1, dwParam2);
|
||||
|
||||
switch (wMsg) {
|
||||
case DRVM_INIT:
|
||||
case DRVM_EXIT:
|
||||
case DRVM_ENABLE:
|
||||
case DRVM_DISABLE:
|
||||
/* FIXME: Pretend this is supported */
|
||||
return 0;
|
||||
case WODM_OPEN: return wodOpen ((LPDWORD)dwUser, (LPWAVEOPENDESC)dwParam1,dwParam2);
|
||||
case WODM_CLOSE: return wodClose ((WAVEMAPDATA*)dwUser);
|
||||
case WODM_WRITE: return wodWrite ((WAVEMAPDATA*)dwUser, (LPWAVEHDR)dwParam1, dwParam2);
|
||||
case WODM_PAUSE: return wodPause ((WAVEMAPDATA*)dwUser);
|
||||
case WODM_GETPOS: return wodGetPosition ((WAVEMAPDATA*)dwUser, (LPMMTIME)dwParam1, dwParam2);
|
||||
case WODM_BREAKLOOP: return wodBreakLoop ((WAVEMAPDATA*)dwUser);
|
||||
case WODM_PREPARE: return wodPrepare ((WAVEMAPDATA*)dwUser, (LPWAVEHDR)dwParam1, dwParam2);
|
||||
case WODM_UNPREPARE: return wodUnprepare ((WAVEMAPDATA*)dwUser, (LPWAVEHDR)dwParam1, dwParam2);
|
||||
case WODM_GETDEVCAPS: return wodGetDevCaps (wDevID, (WAVEMAPDATA*)dwUser, (LPWAVEOUTCAPSA)dwParam1,dwParam2);
|
||||
case WODM_GETNUMDEVS: return 1;
|
||||
case WODM_GETPITCH: return MMSYSERR_NOTSUPPORTED;
|
||||
case WODM_SETPITCH: return MMSYSERR_NOTSUPPORTED;
|
||||
case WODM_GETPLAYBACKRATE: return MMSYSERR_NOTSUPPORTED;
|
||||
case WODM_SETPLAYBACKRATE: return MMSYSERR_NOTSUPPORTED;
|
||||
case WODM_GETVOLUME: return wodGetVolume (wDevID, (WAVEMAPDATA*)dwUser, (LPDWORD)dwParam1);
|
||||
case WODM_SETVOLUME: return wodSetVolume (wDevID, (WAVEMAPDATA*)dwUser, dwParam1);
|
||||
case WODM_RESTART: return wodRestart ((WAVEMAPDATA*)dwUser);
|
||||
case WODM_RESET: return wodReset ((WAVEMAPDATA*)dwUser);
|
||||
case WODM_MAPPER_STATUS: return wodMapperStatus ((WAVEMAPDATA*)dwUser, dwParam1, (LPVOID)dwParam2);
|
||||
default:
|
||||
FIXME("unknown message %d!\n", wMsg);
|
||||
}
|
||||
return MMSYSERR_NOTSUPPORTED;
|
||||
}
|
||||
|
||||
/*======================================================================*
|
||||
* WAVE IN part *
|
||||
*======================================================================*/
|
||||
|
||||
static void CALLBACK widCallback(HWAVEIN hWave, UINT uMsg, DWORD dwInstance,
|
||||
DWORD dwParam1, DWORD dwParam2)
|
||||
{
|
||||
WAVEMAPDATA* wim = (WAVEMAPDATA*)dwInstance;
|
||||
|
||||
TRACE("(%p %u %ld %lx %lx);\n", hWave, uMsg, dwInstance, dwParam1, dwParam2);
|
||||
|
||||
if (!WAVEMAP_IsData(wim)) {
|
||||
ERR("Bad data\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (hWave != wim->u.in.hInnerWave && uMsg != WIM_OPEN)
|
||||
ERR("Shouldn't happen (%p %p)\n", hWave, wim->u.in.hInnerWave);
|
||||
|
||||
switch (uMsg) {
|
||||
case WIM_OPEN:
|
||||
case WIM_CLOSE:
|
||||
/* dwParam1 & dwParam2 are supposed to be 0, nothing to do */
|
||||
break;
|
||||
case WIM_DATA:
|
||||
if (wim->hAcmStream) {
|
||||
LPWAVEHDR lpWaveHdrSrc = (LPWAVEHDR)dwParam1;
|
||||
PACMSTREAMHEADER ash = (PACMSTREAMHEADER)((LPSTR)lpWaveHdrSrc - sizeof(ACMSTREAMHEADER));
|
||||
LPWAVEHDR lpWaveHdrDst = (LPWAVEHDR)ash->dwUser;
|
||||
|
||||
/* convert data just gotten from waveIn into requested format */
|
||||
if (acmStreamConvert(wim->hAcmStream, ash, 0L) != MMSYSERR_NOERROR) {
|
||||
ERR("ACM conversion failed\n");
|
||||
return;
|
||||
} else {
|
||||
TRACE("Converted %ld bytes into %ld\n", ash->cbSrcLengthUsed, ash->cbDstLengthUsed);
|
||||
}
|
||||
/* and setup the wavehdr to return accordingly */
|
||||
lpWaveHdrDst->dwFlags &= ~WHDR_INQUEUE;
|
||||
lpWaveHdrDst->dwFlags |= WHDR_DONE;
|
||||
lpWaveHdrDst->dwBytesRecorded = ash->cbDstLengthUsed;
|
||||
dwParam1 = (DWORD)lpWaveHdrDst;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ERR("Unknown msg %u\n", uMsg);
|
||||
}
|
||||
|
||||
DriverCallback(wim->dwCallback, HIWORD(wim->dwFlags), (HDRVR)wim->u.in.hOuterWave,
|
||||
uMsg, wim->dwClientInstance, dwParam1, dwParam2);
|
||||
}
|
||||
|
||||
static DWORD widOpenHelper(WAVEMAPDATA* wim, UINT idx,
|
||||
LPWAVEOPENDESC lpDesc, LPWAVEFORMATEX lpwfx,
|
||||
DWORD dwFlags)
|
||||
{
|
||||
DWORD ret;
|
||||
|
||||
/* source is always PCM, so the formulas below apply */
|
||||
lpwfx->nBlockAlign = (lpwfx->nChannels * lpwfx->wBitsPerSample) / 8;
|
||||
lpwfx->nAvgBytesPerSec = lpwfx->nSamplesPerSec * lpwfx->nBlockAlign;
|
||||
if (dwFlags & WAVE_FORMAT_QUERY) {
|
||||
ret = acmStreamOpen(NULL, 0, lpwfx, lpDesc->lpFormat, NULL, 0L, 0L, ACM_STREAMOPENF_QUERY);
|
||||
} else {
|
||||
ret = acmStreamOpen(&wim->hAcmStream, 0, lpwfx, lpDesc->lpFormat, NULL, 0L, 0L, 0L);
|
||||
}
|
||||
if (ret == MMSYSERR_NOERROR) {
|
||||
ret = waveInOpen(&wim->u.in.hInnerWave, idx, lpwfx, (DWORD)widCallback,
|
||||
(DWORD)wim, (dwFlags & ~CALLBACK_TYPEMASK) | CALLBACK_FUNCTION);
|
||||
if (ret != MMSYSERR_NOERROR && !(dwFlags & WAVE_FORMAT_QUERY)) {
|
||||
acmStreamClose(wim->hAcmStream, 0);
|
||||
wim->hAcmStream = 0;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static DWORD widOpen(LPDWORD lpdwUser, LPWAVEOPENDESC lpDesc, DWORD dwFlags)
|
||||
{
|
||||
UINT ndlo, ndhi;
|
||||
UINT i;
|
||||
WAVEMAPDATA* wim = HeapAlloc(GetProcessHeap(), 0, sizeof(WAVEMAPDATA));
|
||||
|
||||
TRACE("(%p %p %08lx)\n", lpdwUser, lpDesc, dwFlags);
|
||||
|
||||
if (!wim)
|
||||
return MMSYSERR_NOMEM;
|
||||
|
||||
wim->self = wim;
|
||||
wim->dwCallback = lpDesc->dwCallback;
|
||||
wim->dwFlags = dwFlags;
|
||||
wim->dwClientInstance = lpDesc->dwInstance;
|
||||
wim->u.in.hOuterWave = (HWAVEIN)lpDesc->hWave;
|
||||
|
||||
ndhi = waveInGetNumDevs();
|
||||
if (dwFlags & WAVE_MAPPED) {
|
||||
if (lpDesc->uMappedDeviceID >= ndhi) return MMSYSERR_INVALPARAM;
|
||||
ndlo = lpDesc->uMappedDeviceID;
|
||||
ndhi = ndlo + 1;
|
||||
dwFlags &= ~WAVE_MAPPED;
|
||||
} else {
|
||||
ndlo = 0;
|
||||
}
|
||||
|
||||
wim->avgSpeedOuter = wim->avgSpeedInner = lpDesc->lpFormat->nAvgBytesPerSec;
|
||||
|
||||
for (i = ndlo; i < ndhi; i++) {
|
||||
if (waveInOpen(&wim->u.in.hInnerWave, i, lpDesc->lpFormat, (DWORD)widCallback,
|
||||
(DWORD)wim, (dwFlags & ~CALLBACK_TYPEMASK) | CALLBACK_FUNCTION | WAVE_FORMAT_DIRECT) == MMSYSERR_NOERROR) {
|
||||
wim->hAcmStream = 0;
|
||||
goto found;
|
||||
}
|
||||
}
|
||||
|
||||
if ((dwFlags & WAVE_FORMAT_DIRECT) == 0)
|
||||
{
|
||||
WAVEFORMATEX wfx;
|
||||
|
||||
wfx.wFormatTag = WAVE_FORMAT_PCM;
|
||||
wfx.cbSize = 0; /* normally, this field is not used for PCM format, just in case */
|
||||
/* try some ACM stuff */
|
||||
|
||||
#define TRY(sps,bps) wfx.nSamplesPerSec = (sps); wfx.wBitsPerSample = (bps); \
|
||||
switch (widOpenHelper(wim, i, lpDesc, &wfx, dwFlags | WAVE_FORMAT_DIRECT)) { \
|
||||
case MMSYSERR_NOERROR: wim->avgSpeedInner = wfx.nAvgBytesPerSec; goto found; \
|
||||
case WAVERR_BADFORMAT: break; \
|
||||
default: goto error; \
|
||||
}
|
||||
|
||||
for (i = ndlo; i < ndhi; i++) {
|
||||
wfx.nSamplesPerSec=lpDesc->lpFormat->nSamplesPerSec;
|
||||
/* first try with same stereo/mono option as source */
|
||||
wfx.nChannels = lpDesc->lpFormat->nChannels;
|
||||
TRY(wfx.nSamplesPerSec, 16);
|
||||
TRY(wfx.nSamplesPerSec, 8);
|
||||
wfx.nChannels ^= 3;
|
||||
TRY(wfx.nSamplesPerSec, 16);
|
||||
TRY(wfx.nSamplesPerSec, 8);
|
||||
}
|
||||
|
||||
for (i = ndlo; i < ndhi; i++) {
|
||||
wfx.nSamplesPerSec=lpDesc->lpFormat->nSamplesPerSec;
|
||||
/* first try with same stereo/mono option as source */
|
||||
wfx.nChannels = lpDesc->lpFormat->nChannels;
|
||||
TRY(96000, 16);
|
||||
TRY(48000, 16);
|
||||
TRY(44100, 16);
|
||||
TRY(22050, 16);
|
||||
TRY(11025, 16);
|
||||
|
||||
/* 2^3 => 1, 1^3 => 2, so if stereo, try mono (and the other way around) */
|
||||
wfx.nChannels ^= 3;
|
||||
TRY(96000, 16);
|
||||
TRY(48000, 16);
|
||||
TRY(44100, 16);
|
||||
TRY(22050, 16);
|
||||
TRY(11025, 16);
|
||||
|
||||
/* first try with same stereo/mono option as source */
|
||||
wfx.nChannels = lpDesc->lpFormat->nChannels;
|
||||
TRY(96000, 8);
|
||||
TRY(48000, 8);
|
||||
TRY(44100, 8);
|
||||
TRY(22050, 8);
|
||||
TRY(11025, 8);
|
||||
|
||||
/* 2^3 => 1, 1^3 => 2, so if stereo, try mono (and the other way around) */
|
||||
wfx.nChannels ^= 3;
|
||||
TRY(96000, 8);
|
||||
TRY(48000, 8);
|
||||
TRY(44100, 8);
|
||||
TRY(22050, 8);
|
||||
TRY(11025, 8);
|
||||
}
|
||||
#undef TRY
|
||||
}
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, wim);
|
||||
return WAVERR_BADFORMAT;
|
||||
found:
|
||||
if (dwFlags & WAVE_FORMAT_QUERY) {
|
||||
*lpdwUser = 0L;
|
||||
HeapFree(GetProcessHeap(), 0, wim);
|
||||
} else {
|
||||
*lpdwUser = (DWORD)wim;
|
||||
}
|
||||
TRACE("Ok (stream=%08lx)\n", (DWORD)wim->hAcmStream);
|
||||
return MMSYSERR_NOERROR;
|
||||
error:
|
||||
HeapFree(GetProcessHeap(), 0, wim);
|
||||
return MMSYSERR_ERROR;
|
||||
}
|
||||
|
||||
static DWORD widClose(WAVEMAPDATA* wim)
|
||||
{
|
||||
DWORD ret = waveInClose(wim->u.in.hInnerWave);
|
||||
|
||||
if (ret == MMSYSERR_NOERROR) {
|
||||
if (wim->hAcmStream) {
|
||||
ret = acmStreamClose(wim->hAcmStream, 0);
|
||||
}
|
||||
if (ret == MMSYSERR_NOERROR) {
|
||||
HeapFree(GetProcessHeap(), 0, wim);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static DWORD widAddBuffer(WAVEMAPDATA* wim, LPWAVEHDR lpWaveHdrDst, DWORD dwParam2)
|
||||
{
|
||||
PACMSTREAMHEADER ash;
|
||||
LPWAVEHDR lpWaveHdrSrc;
|
||||
|
||||
if (!wim->hAcmStream) {
|
||||
return waveInAddBuffer(wim->u.in.hInnerWave, lpWaveHdrDst, dwParam2);
|
||||
}
|
||||
|
||||
lpWaveHdrDst->dwFlags |= WHDR_INQUEUE;
|
||||
ash = (PACMSTREAMHEADER)lpWaveHdrDst->reserved;
|
||||
|
||||
lpWaveHdrSrc = (LPWAVEHDR)((LPSTR)ash + sizeof(ACMSTREAMHEADER));
|
||||
return waveInAddBuffer(wim->u.in.hInnerWave, lpWaveHdrSrc, sizeof(*lpWaveHdrSrc));
|
||||
}
|
||||
|
||||
static DWORD widPrepare(WAVEMAPDATA* wim, LPWAVEHDR lpWaveHdrDst, DWORD dwParam2)
|
||||
{
|
||||
PACMSTREAMHEADER ash;
|
||||
DWORD size;
|
||||
DWORD dwRet;
|
||||
LPWAVEHDR lpWaveHdrSrc;
|
||||
|
||||
if (!wim->hAcmStream) {
|
||||
return waveInPrepareHeader(wim->u.in.hInnerWave, lpWaveHdrDst, dwParam2);
|
||||
}
|
||||
if (acmStreamSize(wim->hAcmStream, lpWaveHdrDst->dwBufferLength, &size,
|
||||
ACM_STREAMSIZEF_DESTINATION) != MMSYSERR_NOERROR)
|
||||
return MMSYSERR_ERROR;
|
||||
|
||||
ash = HeapAlloc(GetProcessHeap(), 0, sizeof(ACMSTREAMHEADER) + sizeof(WAVEHDR) + size);
|
||||
if (ash == NULL)
|
||||
return MMSYSERR_NOMEM;
|
||||
|
||||
ash->cbStruct = sizeof(*ash);
|
||||
ash->fdwStatus = 0L;
|
||||
ash->dwUser = (DWORD)lpWaveHdrDst;
|
||||
ash->pbSrc = (LPSTR)ash + sizeof(ACMSTREAMHEADER) + sizeof(WAVEHDR);
|
||||
ash->cbSrcLength = size;
|
||||
/* ash->cbSrcLengthUsed */
|
||||
ash->dwSrcUser = 0L; /* FIXME ? */
|
||||
ash->pbDst = lpWaveHdrDst->lpData;
|
||||
ash->cbDstLength = lpWaveHdrDst->dwBufferLength;
|
||||
/* ash->cbDstLengthUsed */
|
||||
ash->dwDstUser = lpWaveHdrDst->dwUser; /* FIXME ? */
|
||||
dwRet = acmStreamPrepareHeader(wim->hAcmStream, ash, 0L);
|
||||
if (dwRet != MMSYSERR_NOERROR)
|
||||
goto errCleanUp;
|
||||
|
||||
lpWaveHdrSrc = (LPWAVEHDR)((LPSTR)ash + sizeof(ACMSTREAMHEADER));
|
||||
lpWaveHdrSrc->lpData = ash->pbSrc;
|
||||
lpWaveHdrSrc->dwBufferLength = size; /* conversion is not done yet */
|
||||
lpWaveHdrSrc->dwFlags = 0;
|
||||
lpWaveHdrSrc->dwLoops = 0;
|
||||
dwRet = waveInPrepareHeader(wim->u.in.hInnerWave, lpWaveHdrSrc, sizeof(*lpWaveHdrSrc));
|
||||
if (dwRet != MMSYSERR_NOERROR)
|
||||
goto errCleanUp;
|
||||
|
||||
lpWaveHdrDst->reserved = (DWORD)ash;
|
||||
lpWaveHdrDst->dwFlags = WHDR_PREPARED;
|
||||
TRACE("=> (0)\n");
|
||||
return MMSYSERR_NOERROR;
|
||||
errCleanUp:
|
||||
TRACE("=> (%ld)\n", dwRet);
|
||||
HeapFree(GetProcessHeap(), 0, ash);
|
||||
return dwRet;
|
||||
}
|
||||
|
||||
static DWORD widUnprepare(WAVEMAPDATA* wim, LPWAVEHDR lpWaveHdrDst, DWORD dwParam2)
|
||||
{
|
||||
PACMSTREAMHEADER ash;
|
||||
LPWAVEHDR lpWaveHdrSrc;
|
||||
DWORD dwRet1, dwRet2;
|
||||
|
||||
if (!wim->hAcmStream) {
|
||||
return waveInUnprepareHeader(wim->u.in.hInnerWave, lpWaveHdrDst, dwParam2);
|
||||
}
|
||||
ash = (PACMSTREAMHEADER)lpWaveHdrDst->reserved;
|
||||
dwRet1 = acmStreamUnprepareHeader(wim->hAcmStream, ash, 0L);
|
||||
|
||||
lpWaveHdrSrc = (LPWAVEHDR)((LPSTR)ash + sizeof(ACMSTREAMHEADER));
|
||||
dwRet2 = waveInUnprepareHeader(wim->u.in.hInnerWave, lpWaveHdrSrc, sizeof(*lpWaveHdrSrc));
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, ash);
|
||||
|
||||
lpWaveHdrDst->dwFlags &= ~WHDR_PREPARED;
|
||||
return (dwRet1 == MMSYSERR_NOERROR) ? dwRet2 : dwRet1;
|
||||
}
|
||||
|
||||
static DWORD widGetPosition(WAVEMAPDATA* wim, LPMMTIME lpTime, DWORD dwParam2)
|
||||
{
|
||||
DWORD val = waveInGetPosition(wim->u.in.hInnerWave, lpTime, dwParam2);
|
||||
if (lpTime->wType == TIME_BYTES)
|
||||
lpTime->u.cb = MulDiv(lpTime->u.cb, wim->avgSpeedOuter, wim->avgSpeedInner);
|
||||
/* other time types don't require conversion */
|
||||
return val;
|
||||
}
|
||||
|
||||
static DWORD widGetDevCaps(UINT wDevID, WAVEMAPDATA* wim, LPWAVEINCAPSA lpWaveCaps, DWORD dwParam2)
|
||||
{
|
||||
/* if opened low driver, forward message */
|
||||
if (WAVEMAP_IsData(wim))
|
||||
return waveInGetDevCapsA((UINT)wim->u.in.hInnerWave, lpWaveCaps, dwParam2);
|
||||
/* otherwise, return caps of mapper itself */
|
||||
if (wDevID == (UINT)-1 || wDevID == (UINT16)-1) {
|
||||
lpWaveCaps->wMid = 0x00FF;
|
||||
lpWaveCaps->wPid = 0x0001;
|
||||
lpWaveCaps->vDriverVersion = 0x0001;
|
||||
strcpy(lpWaveCaps->szPname, "Wine wave in mapper");
|
||||
lpWaveCaps->dwFormats =
|
||||
WAVE_FORMAT_4M08 | WAVE_FORMAT_4S08 | WAVE_FORMAT_4M16 | WAVE_FORMAT_4S16 |
|
||||
WAVE_FORMAT_2M08 | WAVE_FORMAT_2S08 | WAVE_FORMAT_2M16 | WAVE_FORMAT_2S16 |
|
||||
WAVE_FORMAT_1M08 | WAVE_FORMAT_1S08 | WAVE_FORMAT_1M16 | WAVE_FORMAT_1S16;
|
||||
lpWaveCaps->wChannels = 2;
|
||||
return MMSYSERR_NOERROR;
|
||||
}
|
||||
ERR("This shouldn't happen\n");
|
||||
return MMSYSERR_ERROR;
|
||||
}
|
||||
|
||||
static DWORD widStop(WAVEMAPDATA* wim)
|
||||
{
|
||||
return waveInStop(wim->u.in.hInnerWave);
|
||||
}
|
||||
|
||||
static DWORD widStart(WAVEMAPDATA* wim)
|
||||
{
|
||||
return waveInStart(wim->u.in.hInnerWave);
|
||||
}
|
||||
|
||||
static DWORD widReset(WAVEMAPDATA* wim)
|
||||
{
|
||||
return waveInReset(wim->u.in.hInnerWave);
|
||||
}
|
||||
|
||||
static DWORD widMapperStatus(WAVEMAPDATA* wim, DWORD flags, LPVOID ptr)
|
||||
{
|
||||
UINT id;
|
||||
DWORD ret = MMSYSERR_NOTSUPPORTED;
|
||||
|
||||
switch (flags) {
|
||||
case WAVEIN_MAPPER_STATUS_DEVICE:
|
||||
ret = waveInGetID(wim->u.in.hInnerWave, &id);
|
||||
*(LPDWORD)ptr = id;
|
||||
break;
|
||||
case WAVEIN_MAPPER_STATUS_MAPPED:
|
||||
FIXME("Unsupported yet flag=%ld\n", flags);
|
||||
*(LPDWORD)ptr = 0; /* FIXME ?? */
|
||||
break;
|
||||
case WAVEIN_MAPPER_STATUS_FORMAT:
|
||||
FIXME("Unsupported flag=%ld\n", flags);
|
||||
/* ptr points to a WAVEFORMATEX struct - before or after streaming ? */
|
||||
*(LPDWORD)ptr = 0; /* FIXME ?? */
|
||||
break;
|
||||
default:
|
||||
FIXME("Unsupported flag=%ld\n", flags);
|
||||
*(LPDWORD)ptr = 0;
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* widMessage (MSACM.@)
|
||||
*/
|
||||
DWORD WINAPI WAVEMAP_widMessage(WORD wDevID, WORD wMsg, DWORD dwUser,
|
||||
DWORD dwParam1, DWORD dwParam2)
|
||||
{
|
||||
TRACE("(%u, %04X, %08lX, %08lX, %08lX);\n",
|
||||
wDevID, wMsg, dwUser, dwParam1, dwParam2);
|
||||
|
||||
switch (wMsg) {
|
||||
case DRVM_INIT:
|
||||
case DRVM_EXIT:
|
||||
case DRVM_ENABLE:
|
||||
case DRVM_DISABLE:
|
||||
/* FIXME: Pretend this is supported */
|
||||
return 0;
|
||||
|
||||
case WIDM_OPEN: return widOpen ((LPDWORD)dwUser, (LPWAVEOPENDESC)dwParam1, dwParam2);
|
||||
case WIDM_CLOSE: return widClose ((WAVEMAPDATA*)dwUser);
|
||||
|
||||
case WIDM_ADDBUFFER: return widAddBuffer ((WAVEMAPDATA*)dwUser, (LPWAVEHDR)dwParam1, dwParam2);
|
||||
case WIDM_PREPARE: return widPrepare ((WAVEMAPDATA*)dwUser, (LPWAVEHDR)dwParam1, dwParam2);
|
||||
case WIDM_UNPREPARE: return widUnprepare ((WAVEMAPDATA*)dwUser, (LPWAVEHDR)dwParam1, dwParam2);
|
||||
case WIDM_GETDEVCAPS: return widGetDevCaps (wDevID, (WAVEMAPDATA*)dwUser, (LPWAVEINCAPSA)dwParam1, dwParam2);
|
||||
case WIDM_GETNUMDEVS: return 1;
|
||||
case WIDM_GETPOS: return widGetPosition ((WAVEMAPDATA*)dwUser, (LPMMTIME)dwParam1, dwParam2);
|
||||
case WIDM_RESET: return widReset ((WAVEMAPDATA*)dwUser);
|
||||
case WIDM_START: return widStart ((WAVEMAPDATA*)dwUser);
|
||||
case WIDM_STOP: return widStop ((WAVEMAPDATA*)dwUser);
|
||||
case WIDM_MAPPER_STATUS: return widMapperStatus ((WAVEMAPDATA*)dwUser, dwParam1, (LPVOID)dwParam2);
|
||||
default:
|
||||
FIXME("unknown message %u!\n", wMsg);
|
||||
}
|
||||
return MMSYSERR_NOTSUPPORTED;
|
||||
}
|
||||
|
||||
/*======================================================================*
|
||||
* Driver part *
|
||||
*======================================================================*/
|
||||
|
||||
static struct WINE_WAVEMAP* oss = NULL;
|
||||
|
||||
/**************************************************************************
|
||||
* WAVEMAP_drvOpen [internal]
|
||||
*/
|
||||
static DWORD WAVEMAP_drvOpen(LPSTR str)
|
||||
{
|
||||
if (oss)
|
||||
return 0;
|
||||
|
||||
/* I know, this is ugly, but who cares... */
|
||||
oss = (struct WINE_WAVEMAP*)1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* WAVEMAP_drvClose [internal]
|
||||
*/
|
||||
static DWORD WAVEMAP_drvClose(DWORD dwDevID)
|
||||
{
|
||||
if (oss) {
|
||||
oss = NULL;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* DriverProc (MSACM.@)
|
||||
*/
|
||||
LONG CALLBACK WAVEMAP_DriverProc(DWORD dwDevID, HDRVR hDriv, DWORD wMsg,
|
||||
DWORD dwParam1, DWORD dwParam2)
|
||||
{
|
||||
TRACE("(%08lX, %p, %08lX, %08lX, %08lX)\n",
|
||||
dwDevID, hDriv, wMsg, dwParam1, dwParam2);
|
||||
|
||||
switch(wMsg) {
|
||||
case DRV_LOAD: return 1;
|
||||
case DRV_FREE: return 1;
|
||||
case DRV_OPEN: return WAVEMAP_drvOpen((LPSTR)dwParam1);
|
||||
case DRV_CLOSE: return WAVEMAP_drvClose(dwDevID);
|
||||
case DRV_ENABLE: return 1;
|
||||
case DRV_DISABLE: return 1;
|
||||
case DRV_QUERYCONFIGURE: return 1;
|
||||
case DRV_CONFIGURE: MessageBoxA(0, "WAVEMAP MultiMedia Driver !", "Wave mapper Driver", MB_OK); return 1;
|
||||
case DRV_INSTALL: return DRVCNF_RESTART;
|
||||
case DRV_REMOVE: return DRVCNF_RESTART;
|
||||
default:
|
||||
return DefDriverProc(dwDevID, hDriv, wMsg, dwParam1, dwParam2);
|
||||
}
|
||||
}
|
39
reactos/lib/winmm/wavemap/wavemap.rc
Normal file
39
reactos/lib/winmm/wavemap/wavemap.rc
Normal file
|
@ -0,0 +1,39 @@
|
|||
#include <defines.h>
|
||||
#include <reactos/resource.h>
|
||||
|
||||
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION RES_UINT_FV_MAJOR,RES_UINT_FV_MINOR,RES_UINT_FV_REVISION,RES_UINT_FV_BUILD
|
||||
PRODUCTVERSION RES_UINT_PV_MAJOR,RES_UINT_PV_MINOR,RES_UINT_PV_REVISION,RES_UINT_PV_BUILD
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
#else
|
||||
FILEFLAGS 0x0L
|
||||
#endif
|
||||
FILEOS 0x40004L
|
||||
FILETYPE 0x2L
|
||||
FILESUBTYPE 0x0L
|
||||
BEGIN
|
||||
BLOCK "StringFileInfo"
|
||||
BEGIN
|
||||
BLOCK "040904b0"
|
||||
BEGIN
|
||||
VALUE "CompanyName", RES_STR_COMPANY_NAME
|
||||
VALUE "FileDescription", "ReactOS/WINE Wave Mapper\0"
|
||||
VALUE "FileVersion", RES_STR_FILE_VERSION
|
||||
VALUE "InternalName", "wavemap\0"
|
||||
VALUE "LegalCopyright", RES_STR_LEGAL_COPYRIGHT
|
||||
VALUE "OriginalFilename", "wavemap.dll\0"
|
||||
VALUE "ProductName", RES_STR_PRODUCT_NAME
|
||||
VALUE "ProductVersion", RES_STR_PRODUCT_VERSION
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
BEGIN
|
||||
VALUE "Translation", 0x409, 1200
|
||||
END
|
||||
END
|
||||
|
||||
|
2
reactos/lib/winmm/wavemap/wavemap.spec.def
Normal file
2
reactos/lib/winmm/wavemap/wavemap.spec.def
Normal file
|
@ -0,0 +1,2 @@
|
|||
@ stdcall DriverProc(long long long long long) MIDIMAP_DriverProc
|
||||
@ stdcall modMessage(long long long long long) MIDIMAP_modMessage
|
|
@ -16,7 +16,7 @@
|
|||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
/* $Id: bitmaps.c,v 1.58 2004/02/25 01:25:51 sedwards Exp $ */
|
||||
/* $Id: bitmaps.c,v 1.59 2004/03/10 15:22:43 silverblade Exp $ */
|
||||
#undef WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#include <stdlib.h>
|
||||
|
@ -268,6 +268,7 @@ HBITMAP STDCALL NtGdiCreateBitmap(INT Width,
|
|||
{
|
||||
PBITMAPOBJ bmp;
|
||||
HBITMAP hBitmap;
|
||||
int Pixel;
|
||||
|
||||
Planes = (BYTE) Planes;
|
||||
BitsPerPel = (BYTE) BitsPerPel;
|
||||
|
@ -321,6 +322,12 @@ HBITMAP STDCALL NtGdiCreateBitmap(INT Width,
|
|||
bmp->bitmap.bmBits = ExAllocatePoolWithTag(PagedPool, bmp->bitmap.bmWidthBytes * bmp->bitmap.bmHeight, TAG_BITMAP);
|
||||
|
||||
BITMAPOBJ_UnlockBitmap( hBitmap );
|
||||
|
||||
// Initialize the bitmap (fixes bug 244?)
|
||||
for (Pixel = 0; Pixel < Height * bmp->bitmap.bmWidthBytes; Pixel ++)
|
||||
{
|
||||
((char*)Bits)[Pixel] = 0;
|
||||
}
|
||||
|
||||
if (Bits) /* Set bitmap bits */
|
||||
{
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# $Id: helper.mk,v 1.59 2004/03/04 23:14:01 dwelch Exp $
|
||||
# $Id: helper.mk,v 1.60 2004/03/10 15:22:44 silverblade Exp $
|
||||
#
|
||||
# Helper makefile for ReactOS modules
|
||||
# Variables this makefile accepts:
|
||||
|
@ -467,6 +467,38 @@ endif
|
|||
MK_RC_BINARIES = $(TARGET_RC_BINARIES)
|
||||
endif
|
||||
|
||||
ifeq ($(TARGET_TYPE),winedrv)
|
||||
-include Makefile.ros
|
||||
MK_GENERATED_MAKEFILE = Makefile.ros
|
||||
MK_MODE := user
|
||||
MK_EXETYPE := drv
|
||||
MK_DEFEXT := .drv
|
||||
# does this need changing?:
|
||||
MK_DEFENTRY := _DllMain@12
|
||||
MK_DDKLIBS :=
|
||||
MK_SDKLIBS :=
|
||||
MK_CFLAGS := -D__USE_W32API -D_WIN32_IE=0x600 -D_WIN32_WINNT=0x501 -DWINVER=0x501 -D__need_offsetof -DCOBJMACROS -I$(PATH_TO_TOP)/include/wine
|
||||
MK_CPPFLAGS := -D__USE_W32API -D_WIN32_IE=0x600 -D_WIN32_WINNT=0x501 -DWINVER=0x501 -D__need_offsetof -DCOBJMACROS -I$(PATH_TO_TOP)/include -I$(PATH_TO_TOP)/include/wine
|
||||
MK_RCFLAGS := --define __USE_W32API --include-dir $(PATH_TO_TOP)/include/wine
|
||||
MK_IMPLIB := yes
|
||||
MK_IMPLIBONLY := no
|
||||
MK_IMPLIBDEFPATH := $(SDK_PATH_LIB)
|
||||
MK_IMPLIB_EXT := .a
|
||||
MK_INSTALLDIR := system32
|
||||
MK_BOOTCDDIR := system32
|
||||
MK_DISTDIR := dlls
|
||||
MK_RES_BASE := $(TARGET_NAME)
|
||||
ifeq ($(TARGET_DEFNAME),)
|
||||
MK_DEFBASENAME := $(TARGET_NAME).spec
|
||||
MK_SPECDEF := $(MK_DEFBASENAME).def
|
||||
else
|
||||
MK_DEFBASENAME := $(TARGET_DEFNAME)
|
||||
endif
|
||||
MK_KILLAT := --kill-at
|
||||
TARGET_DEFONLY := yes
|
||||
MK_RC_BINARIES = $(TARGET_RC_BINARIES)
|
||||
endif
|
||||
|
||||
ifeq ($(TARGET_RC_SRCS),)
|
||||
MK_RES_SRC := $(TARGET_PATH)/$(MK_RES_BASE).rc
|
||||
MK_RESOURCE := $(MK_RES_BASE).coff
|
||||
|
@ -1030,6 +1062,8 @@ endif # ROS_USE_PCH
|
|||
$(RC) $(TARGET_RCFLAGS) $< -o $@
|
||||
%.spec.def: %.spec
|
||||
$(WINEBUILD) $(DEFS) -o $@ --def $<
|
||||
%.drv.spec.def: %.spec
|
||||
$(WINEBUILD) $(DEFS) -o $@ --def $<
|
||||
# Kill implicit rule
|
||||
.o:;
|
||||
|
||||
|
|
Loading…
Reference in a new issue